BeautifulSoup

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>標籤多個,只返回第一個

wKiom1mqCh_CO-3nAAAO07SQ4jc431.png-wh_50

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)

wKiom1mqC86AnkEBAABqacaBSKo385.png-wh_50

# print(soup.p.descendants)   #descendants 所有子孫節點

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

print(i,child)    #返回第一個p標籤下的所有內容

wKioL1mqC96h3L00AACbNYxgwm0410.png-wh_50

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裏,則前面要加一個‘.’,返回該內容所處位置標籤的整個內容

wKiom1mqDI-jLlLuAAAPxRsoCF0958.png-wh_50

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'))

wKiom1mqDYDAbfblAAAYJWTeL7s027.png-wh_50

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章