《Python網絡數據采集》讀書筆記(二)
和之前一樣,抓取整個頁面,然後創建一個BeautifulSoup對象。這裏面“lxml”解析器需要另外下載。
pip3 install lxml
>>> from urllib.request import urlopen >>> from bs4 import BeautifulSoup >>> html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html") >>> bsObj = BeautifulSoup(html, "lxml")
finAll()可以獲取頁面中所有指定的標簽,抽取只包含在<span class="green"></span>標簽裏的文字,這樣就會得到一個人物名稱的列表。.get_text()會把所有的標簽都清除,返回一個只包含文字的字符串。
>>> nameList = bsObj.findAll("span", {"class":"green"}) >>> for name in nameList: print(name.get_text())
2、詳解finAll()和find()的參數
findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)
tag--可以傳一個標簽的名稱或多個標簽名稱組成的列表做參數;如下示例將返回一個包含HTML文檔中所有標題標簽的列表
>>> bsObj.findAll({"h1", "h2", "h3", "h4", "h5", "h6"}) [<h1>War and Peace</h1>, <h2>Chapter 1</h2>]
attributes--字典封裝一個標簽的若幹屬性和對應的屬性值;如下示例會返回HTML文檔裏紅色與綠色兩種顏色的span標簽
>>> bsObj.findAll("span", {"class":{"green", "red"}})
recursive--布爾變量(默認為True)查找標簽參數的所有子標簽,及子標簽的子標簽;為False時,只查找文檔的一級標簽
text--是用標簽的文本內容去匹配;如下示例作用是查找網頁中包含“the prince”內容的標簽數量
>>> nameList=bsObj.findAll(text="the prince") >>> print(len(nameList)) 7
limit--按照網頁上的順序排序,獲取的前 x 項結果(等於1時等價於find)
keywords--可以讓你選擇那些具有指定屬性的標簽
>>> allText = bsObj.findAll(id="text") >>> print(allText[0].get_text())
下面兩行代碼是完全一樣的
bsObj.findAll(id="text") bsObj.findAll("", {"id":"text"})
由於class為關鍵字,使用keywords指定時需要多加一個下劃線
bsObj.findAll(class_="green") bsObj.findAll("", {"class":"green"})
3、BeautifulSoup對象
BeautifulSoup對象:如前面代碼示例中的bsObj
Tag對象:BeautifulSoup對象通過find和findAll或直接調用子標簽獲取的一列象或單個對象(如bsObj.div.h1)
NavigableString對象:表示標簽裏的文字
Comment對象:查找 HTML 文檔的註釋標簽
4、標簽解析樹的導航:通過標簽在文檔中的位置來查找標簽。
處理子標簽與後代標簽:
子標簽(child)是一個父標簽的下一級。
後代標簽(descendant)是指一個父標簽下面所有級別的標簽。
同樣的
>>> from urllib.request import urlopen >>> from bs4 import BeautifulSoup >>> html = urlopen("http://www.pythonscraping.com/pages/page3.html") >>> bsObj = BeautifulSoup(html, "lxml")
只想找出子標簽,可以用.children;如下示例會打印giftList表格中所有產品的數據行(如使用.descendants將打印出二十幾個標簽)
>>> for child in bsObj.find("table", {"id":"giftList"}).children: print(child)
處理兄弟標簽:
next_siblings和previous_siblings將返回一組標簽
next_sibling和previous_sibling將返回單個標簽
如下示例會打印產品列表裏除第一行外的所有行的產品
>>> for sibling in bsObj.find("table", {"id":"giftList"}).tr.next_siblings: print(sibling)
處理父標簽:
parent 和 parents
如下示例會打印出指定圖片對應的商品價格
>>> print(bsObj.find("img", {"src":"../img/gifts/img1.jpg"}).parent.previous_sibling.get_text()) $15.00
《Python網絡數據采集》讀書筆記(二)