當咱們想要從複雜的網絡信息中抽取出咱們須要的信息時,不假思索的寫出層層抽取的代碼是很是不理智的。這樣的代碼又臭又長,難以閱讀,且容易失效。正確的方法是三思然後行,使用正確的技巧方法寫出簡潔,易懂,擴展性強的代碼。 重要的事情說三遍:三思然後行,三思然後行,三思然後行html
網頁的class屬性和id屬性是很是豐富的,咱們可使用這些屬性來抽取信息: 例子:python
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://pythonscraping.com/pages/warandpeace.html") #網頁html代碼賦給變量bs0bj bs0bj = BeautifulSoup(html) #返回一個含有class=green屬性的列表 namelist = bs0bj.findAll("span",{"class":"green"}) #遍歷輸出列表中不含標籤的文字。 for name in namelist: print(name.get_text())
.get_text():把正在處理的html文檔中的全部標籤都清除,返回一個只包含文字的字符串,通常狀況下因儘量保留標籤,在最後狀況下使用get_text()。正則表達式
find()和finaall()這兩個函數是很是經常使用的,咱們能夠用它們找到須要的標籤或標籤組。 函數的格式定義以下:api
findAll(tag, attributes, recursive, text, limit, keywords) find(tag, attributes, recursive, text, keywords)
整個html頁面能夠簡化爲一棵樹,以下所示:網絡
1.處理子標籤和後代標籤:函數
通常狀況下,beautifulsoup老是處理當前標籤下的後代標籤,如bs0bj.body.h1是處理當前body標籤下的第一個h1標籤。bs0bj.body.finaAll("img")是找到第一div標籤下的索引img列表。學習
若是隻想要找到子標籤,可使用.children標籤。測試
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) for child in bsObj.find("table",{"id":"giftList"}).children: print(child)
上面的代碼會打印giftlist表格中的索引產品的數據行。this
使用descendants()標籤能夠輸出全部的後代標籤。url
2.兄弟標籤: 使用next_siblings()函數能夠處理兄弟標籤。
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) for sibling in bsObj.find("table",{"id":"giftList"}).tr.next_siblings: print(sibling)
使用兄弟標籤會跳過標籤自身,由於自身不能看成本身的兄弟,同時兄弟標籤只能查找後面的標籤,不能查找自身以及前面的兄弟標籤。
與next_siblings()相似,previous_siblings()函數是查找前面的兄弟節點。
同時還有next_siblings()和previous_siblings()函數,它們的做業是返回單個標籤。
3.父標籤
使用parent和parents標籤能夠查找給定標籤的父標籤或父標籤列表。
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) print(bsObj.find("img",{"src":"../img/gifts/img1.jpg" }).parent.previous_sibling.get_text())
上面代碼的意思是找到給定標籤的父標籤的前一個兄弟標籤中的文字。
正則表達式是很是豐富的,可是上手很簡單。能夠本身搜索一些教程學習。 正則測試:http://www.regexpal.com/
正則表達式是很是有用的,舉個例子,加入你想要抓取索引的img圖片,使用finaall()獲得的結果可能會出乎意料,多了許多隱藏的圖片或不相關的圖片,此時可使用正則表達式。咱們發現想要獲取的圖片源代碼格式以下:
<img src="../img/gifts/img3.jpg">
這樣咱們能夠直接經過文件路徑來查找信息,
from urllib.request import urlopenfrom bs4 import BeautifulSoupimport re html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")}) for image in images: print(image["src"])
上面的例子使用了正則表達式匹配了以../img/gifts/img開頭,以.jpg結尾的圖片。結果以下:
../img/gifts/img1.jpg ../img/gifts/img2.jpg ../img/gifts/img3.jpg ../img/gifts/img4.jpg ../img/gifts/img6.jpg
對於一個標籤對象,可使用下面代碼得到它的所有屬性:
myTag.attrs
得到的屬性存在一個字典中,能夠取出某一個屬性
myTag.attrs["href"]