Beautifulsoup

       网页解析库,灵活方便,处理效率高,支持多种解析器

       利用它不用编写正则表达式,即可实现网页信息的处理

       需定义frombs4 import Beautifulsoup

1.    用法详解

BeautifulSoup解析库

解析器

使用方法

优势

备注

Python标准库

BeautifulSoup(markup,'html.parnser')

python内置标准库,速度适中,文档容错强

python2.7.3 or 3.2.2 中文容错差

lxml HTML解析器 

BeautifulSoup(markup,'lxml')

速度快,文档容错能力强

需要安装C语言库

lxml XML解析器

BeautifulSoup(markup,'xml')

速度快,唯一支持xml的解析器  

需要安装C语言库

html5lib    

BeautifulSoup(markup,'html5lib')

容错最好,以浏览器的方式解析,生成html5格式的文档

速度慢,不依赖外部扩展

 

 

2.    基本使用方法

from bs4 importBeautifulSoup

html = '''

            <html><head><title>TheTom Story</title></head>

            <pname='dromouse'><b>The Dormouse's story</b></p>

     <pclass='story'>Once upon a time there were three little sisters; and theirnames were

            <a href='http://example.com/elsie'id='link1'><!--Elsle--></b>,

            <a href='http://example.com/lacie'class='sister' id='link2'>Lacie</a> and

            <a href='http://example.com/title'class='sister' id='link3'>Title</a>;

            and they lived at the bottom of awell.</p>

            <p>...</p> #去掉通过Beautifulsoup自动补全

            '''

       soup=BeautifulSoup(html,'lxml') 

print(soup.prettify())

#转变为html的标准格式,例如‘’转为"",标签自动闭合


3.    标签选择器

1> 

 print(soup.title)   #打印标签,代替正则

  #返回  <title>The Tom Story</title>

print(soup.head)

 #返回 <head><title>The Tom Story</title></head>

print(soup.p)  #<p>标签多个,只返回第一个

BeautifulSoup_Soup

2>

print(soup.title.name)   #标签名称  返回title

print(soup.title.string)  #标签中内容  返回The Tom Story

print(soup.head.title.string) #用‘.’分隔,进行嵌套选择

print(soup.p.string) #第一个p标签内容 à TheDormouse's story

3>

print(soup.p.attrs['name'])  #获取属性的值

print(soup.p['name'])  #两者返回结果相同  为dromouse

print(soup.p.attrs['class'])

print(soup.p['class'])    

#返回  ['title']此列表类型与class关键字有关,若换做其他,则返回字符串

4>   

html = '''

   <html>

       <head>

           <title>

                The Tom Story

           </title>

       </head>

       <body>

           <p>

                Once upon a time there werethree little sisters; and their names were

                <ahref="http://example.com/elsie" id="link1">

                   <span><!--Elsle--></span>

                </a>

                <ahref="http://example.com/lacie"id="link2">Lacie</a>

                and

                <ahref="http://example.com/title"id="link3">Title</a>

                and they lived at the bottom ofa well.

           </p>

           <p>...</p>

       </body>

   </html>'''

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,'lxml')

print(soup.p.contents)   #contents用来选择子节点(下一级),返回列表

print(soup.p.children)  #同contents一样,返回列表,但需要for循环遍历取出

#但不仅限于标签,空格、换行、字符串都包括在内

for i,child inenumerate(soup.p.children):

    print(i,child)

BeautifulSoup_Beautiful_02

# print(soup.p.descendants)   #descendants 所有子孙节点

for i,child inenumerate(soup.p.descendants):

print(i,child)    #返回第一个p标签下的所有内容

BeautifulSoup_Soup_03

print(soup.a.parent)  #父节点,返回上一级,即p节点下的所有内容原型输出

print(list(enumerate(soup.a.parents)))

 #parents祖父节点,顺序往上一级父节点,再上一级,最后输出整个html

print(list(enumerate(soup.a.next_siblings)))   #兄弟节点

 #打印第一个a标签的所有同级的内容,不包括本身

print(list(enumerate(soup.a.previous_siblings)))

#第一个a标签的同级内容,不包括本身

#小结:它是一种标签选择器,基于C库,速度非常快,但是在实际使用中并不能满足我们的需求,比如一些class属性

4. 标准选择器

find_all(name,attrs,recursive,text,**kwargs),类似正则的findall, 可根据标签名,属性,内容查找文档找出所有的相关内容   

html='''

<div>

   <div>

       <h4>Hello</h4>

   </div>

   <div>

       <ul id="list-1">

           <li>Foo</li>

           <li>Bar</li>

           <li>Jay</li>

       </ul>

       <ul class="list list-small" id="list-2">

           <liclass="element">Foo</li>

           <li>Bar</li>

       </ul>

   </div>

</div>'''

from bs4 import BeautifulSoup

soup=BeautifulSoup(html,'lxml')

print(soup.find_all('ul'))  #打印所有ul标签

for ul in soup.find_all('ul'):

   for li in ul.find_all('li'):

       print(li)     #根据标签名层层查找迭代,打印所有li标签

#attrs用法,优点在于可以使用字典类型进行查找, 字典的键名,就是html标签中属性的名称, 键值就是对应标签中属性的值

print(soup.find_all(attrs={'id':'list-1'}))  #定位到该内容,并以列表形式输出完整标签

print(soup.find_all(attrs={'name':'elements'}))  #结果同上

#另一种写法

print(soup.find_all(id='list-1'))

print(soup.find_all(class_='element'))

 #class是python的保留字,所以在这里我们为了让程序加以区分, 写成 class_

# text的相关用法  即根据文本的内容进行选择

print(soup.find_all(text='Foo'))  #返回 ['Foo', 'Foo']

 

5.    find ,与find_all不同, find用来返回单个元素

html = '''

   <div>

       <div>

           <h4>Hello</h4>

       </div>

       <div>

           <ul id="list-1">

                <liclass="element">Foo</li>

                <liclass="element">Bar</li>

                <liclass="element">Jay</li>

           </ul>

           <ul class="list list-small" id="list-2">

                <liclass="element">Foo</li>

                <liclass="element">Bar</li>

           </ul>

       </div>

   </div>'''

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,'lxml')

print(soup.find('ul')) #返回第一个ul标签 

 

#find_parents()             #返回所有祖先节点,用法同上

#find_parent()              #返回直接父节点,用法同上

#find_next_siblings()       #返回后面所有兄弟节点

#find_next_sibling()        #返回后面第一个兄弟节点

#find_previous_siblings()   #返回前面所有兄弟节点

#find_previous_sibling()    #返回前面第一个兄弟节点

#find_all_next()            #返回节点后所有符合条件的节点

#find_next()                #返回节点后第一个符合条件的节点

#find_all_previous()        #返回节点前所有符合条件的节点

#find_all_previou()         #返回节点前第一个符合条件的节点

 

6.    CSS 选择器

通过select()直接传入CSS选择器即可完成选择

1>   

html='''

<div>

   <div>

       <h4>Hello</h4>

   </div>

   <div>

       <ul id="list-1"name="elements">

           <li>Foo</li>

           <li>Bar</li>

           <li>Jay</li>

       </ul>

       <ul class="list list-small" id="list-2">

           <li>Foo</li>

           <li>Bar</li>

       </ul>

   </div>

</div>

'''

from bs4 import BeautifulSoup

soup=BeautifulSoup(html,'lxml')

print(soup.select('.panel .panel-heading'))

#节点在class里,则前面要加一个‘.’,返回该内容所处位置标签的整个内容

BeautifulSoup_Soup_04

print(soup.select('ul li'))

#根据标签,找到ul中的li标签,并返回所有li标签

print(soup.select('#list-2 .element'))

#节点在id里,前面要加一个#,返回了在节点id=list-2下,且内容有class=element的两个li标签的内容

for ul in soup.select('ul'):

print(ul.select('li'))

BeautifulSoup_Soup_05

2> 

 Select获取属性值的方法

for ul insoup.select('ul):

print(ul['id'])        #用来获取id里面的值  

     print(ul.attrs['id'])   #同上

3>  

获取内容的方法

for li insoup.select('li):

print(li.get_text())     #打印li标签里面的内容

       #返回Foo  Bar  Jay Foo  Bar