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>標籤多個,只返回第一個
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)
# print(soup.p.descendants) #descendants 所有子孫節點
for i,child inenumerate(soup.p.descendants):
print(i,child) #返回第一個p標籤下的所有內容
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裏,則前面要加一個‘.’,返回該內容所處位置標籤的整個內容
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'))
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