Beautiful Soup是一個爬蟲的神級庫!今天教你完全摸透它!
博主使用的是Mac系統,直接通過命令安裝庫:
sudo easy_install beautifulsoup4
安裝完成後,嘗試包含庫運行:
from bs4 import BeautifulSoup
若沒有報錯,則說明庫已正常安裝完成。
開始
本文會通過這個網頁http://reeoo.com來進行示例講解,如下圖所示
也可以通過文件句柄來初始化,可先將HTML的源碼保存到本地同級目錄 reo.html,然後將文件名作為參數:
soup = BeautifulSoup(open(‘reo.html‘))
可以打印 soup,輸出內容和HTML文本無二致,此時它為一個復雜的樹形結構,每個節點都是Python對象。
Ps. 接下來示例代碼中所用到的 soup 都為該soup。
Tag
Tag對象與HTML原生文檔中的標簽相同,可以直接通過對應名字獲取
tag = soup.titleprint tag
打印結果:
Reeoo - web design inspiration and website gallery
Name
通過Tag對象的name屬性,可以獲取到標簽的名稱
print tag.name# title
tag中的字符串
通過 string 方法獲取標簽中包含的字符串
tag = soup.titles = tag.stringprint s# Reeoo - web design inspiration and website gallery
文檔樹的遍歷
如下圖:
我們希望獲取到 article 標簽中的 li
tag = soup.article.div.ul.liprint tag
打印結果:
也可以把中間的一些節點省略,結果也一致
tag = soup.article.li
通過 . 屬性只能獲取到第一個tag,若想獲取到所有的 li 標簽,可以通過 find_all() 方法
ls = soup.article.div.ul.find_all(‘li‘)
獲取到的是包含所有li標簽的列表。
tag的 .contents 屬性可以將tag的子節點以列表的方式輸出:
tag = soup.article.div.ulcontents = tag.contents
打印 contents 可以看到列表中不僅包含了 li 標簽內容,還包括了換行符 ‘ ‘
過tag的 .children 生成器,可以對tag的子節點進行循環
tag = soup.article.div.ulchildren = tag.childrenprint childrenfor child in children: print child
文檔樹的搜索
對樹形結構的文檔進行特定的搜索是爬蟲抓取過程中最常用的操作。
find_all()
find_all(name , attrs , recursive , string , ** kwargs)
name 參數
查找所有名字為 name 的tag
指定名字的屬性參數值可以包括:字符串、正則表達式、列表、True/False。
True/False
是否存在指定的屬性。
搜索所有帶有 target 屬性的標簽
soup.find_all(target=True)
搜索所有不帶 target 屬性的標簽(仔細觀察會發現,搜索結果還是會有帶 target 的標簽,那是不帶 target 標簽的子標簽,這裏需要註意一下。)
soup.find_all(target=False)
可以指定多個參數作為過濾條件,例如頁面縮略圖部分的標簽如下所示:
...
![AIM Creative Studios](//upload-images.jianshu.io/upload_images/1346917-f6281ffe1a8f0b18.gif?imageMogr2/auto-orient/strip) AIM Creative Studios
...
搜索 src 屬性中包含 reeoo 字符串,並且 class 為 lazy 的標簽:
soup.find_all(src=re.compile("reeoo.com"), class_=‘lazy‘)
搜索結果即為所有的縮略圖 img 標簽。
打印搜索結果可看到包含3個元素,分別是對應標簽裏的內容,具體見下圖所示
limit 參數
find_all() 返回的是整個文檔的搜索結果,如果文檔內容較多則搜索過程耗時過長,加上 limit 限制,當結果到達 limit 值時停止搜索並返回結果。
搜索 class 為 thumb 的 div 標簽,只搜索3個
soup.find_all(‘div‘, class_=‘thumb‘, limit=3)
打印結果為一個包含3個元素的列表,實際滿足結果的標簽在文檔裏不止3個。
recursive 參數
find_all() 會檢索當前tag的所有子孫節點,如果只想搜索tag的直接子節點,可以使用參數 recursive=False。
CSS選擇器
Tag 或 BeautifulSoup 對象通過 select() 方法中傳入字符串參數, 即可使用CSS選擇器的語法找到tag。
語義和CSS一致,搜索 article 標簽下的 ul 標簽中的 li 標簽
print soup.select(‘article ul li‘)
通過類名查找,兩行代碼的結果一致,搜索 class 為 thumb 的標簽
soup.select(‘.thumb‘)soup.select(‘[class~=thumb]‘)
通過id查找,搜索 id 為 sponsor 的標簽
soup.select(‘#sponsor‘)
通過是否存在某個屬性來查找,搜索具有 id 屬性的 li 標簽
soup.select(‘li[id]‘)
通過屬性的值來查找查找,搜索 id 為 sponsor 的 li 標簽
soup.select(‘li[id="sponsor"]‘)
其他
其他的搜索方法還有:
find_parents() 和 find_parent()
find_next_siblings() 和 find_next_sibling()
find_previous_siblings() 和 find_previous_sibling()
…
參數的作用和 find_all()、find() 差別不大,這裏就不再列舉使用方式了。這兩個方法基本已經能滿足絕大部分的查詢需求。
還有一些方法涉及文檔樹的修改。對於爬蟲來說大部分工作只是檢索頁面的信息,很少需要對頁面源碼做改動,所以這部分的內容也不再列舉。
進群:125240963 即可獲取數十套PDF哦!
Beautiful Soup是一個爬蟲的神級庫!今天教你完全摸透它!