【網絡爬蟲入門03】爬蟲解析利器beautifulSoup模塊的基本應用


【網絡爬蟲入門03】爬蟲解析利器beautifulSoup模塊的基本應用

 廣東職業技術學院  歐浩源  2017-10-20

1、引言

    網絡爬蟲最終的目的就是過濾選取網絡信息,因此最重要的就是解析器了,其性能的優劣直接決定這網絡爬蟲的速度和效率。BeautifulSoup可以通過定位HTML件中的標簽來格式化和組織復雜的網絡信息,嘗試化平淡為神奇,用簡單易用的Python對象為我們展現XML的信息結構,它會幫你節省數小時甚至數天的工作時間。

2、什么是BeautifulSoup模塊?

    BeautifulSoup是一個非常優秀的Python擴展庫,它可以從HTML或XML文件中提取我們感興趣的數據。它不但可以標簽進行查找,還可以通過標簽屬性來查找。 BeautifulSoup除了支持Python標准庫中的HTML解析器之外,還支持一些第三方的解析器,可以有針對性地向網頁進行解析。 BeautifulSoup官方推薦使用lxml作為解析器,據說因為lxml解析器的效率更高。
    學習BeautifulSoup的最完整和最好資料是官方文檔,常用的內容熟練掌握,不常用的需要的時候查閱就好。在本文中,只總結爬蟲開發中常用知識,更多內容要看官方文檔:
    http://beautifulsoup.readthedocs.io/zh_CN/latest/#id18

3、對象的種類

    BeautifulSoup對象是一個復雜的樹形結構,它的每一個節點都是一個Python對象,獲取網頁內容就是一個提取對象內容的過程,其提取對象的方法可以分為:遍歷文檔樹搜索文檔樹CSS選擇器
    所有的對象可以分為4種:
    <1> Tag:Tag對象與XML或HTML原生文檔中的tag相同。它有很多方法和屬性,其中最重要的是:name和attributes。BeautifulSoup對象通過find()和find_all()方法,或者直接調用子標簽獲取一列對象或單個對象。
    <2> NavigableString:用來表示標簽里的文字,不是標簽。
    <3> Comment:這是一個特殊類型的NavigableString對象,用來查找HTML文檔中的注釋
    <4> BeautifulSoup:這個對象表示文檔的全部內容。大部分時候可以把它當作Tag對象,它支持遍歷文檔樹和搜索文檔樹的大部分方法。

4、官方測試樣例

5、遍歷文檔樹

    文檔樹的遍歷方法就好像爬樹一樣,需要首先爬到樹干上,然后慢慢爬到小樹干,最后到樹枝上,就可以得到需要的數據了。
例1:獲取文檔樹中的‘body標簽中的‘p’標簽中的’‘b’標簽。

    在遍歷文檔樹中,搞清各個標簽之間的關系是非常重要的。子標簽就是一個父標簽的下一級;而后代標簽是指一個父標簽下面所有級別的標簽。所有子標簽都是后代標簽,但不是所有的后代標簽都是子標簽。一般情況下,BeautifulSoup的方法總是處理當前標簽的后代標簽
    可以通過 .parent 屬性來獲取某個元素的父節點.
例2:獲取文檔樹中‘p’標簽的父標簽。

    tag的.contents 屬性可以將tag的子節點以列表的方式輸出;通過tag的.children 生成器,也可以對tag的子節點進行循環。
例3:獲取文檔樹中‘p’標簽的子標簽。

6、搜索文檔樹

    相對於遍歷文檔樹來說,搜索文檔樹最常用。在搜索文檔樹時,最常用的是find_all()和find()方法。在這里,主要通過例子講述find_all()的常見使用,關於find_all()的具體描述參見官方文檔。
    find_all (name, attrs, recursive, string, limit, keyword)
    該方法搜索當前tag的所有tag子節點,並判斷是否符合過濾器的條件。
[1] name參數:可以查找所有名字為name的tag,字符串對象會自動忽略掉。該參數的值可以接受:字符串正則表達式列表True
例4:搜索文檔樹中的‘title’標簽。

例5:搜索文檔樹中的‘a’標簽,逐條打印出來

[2] attrs參數:是用一個Python字典封裝一個標簽的若干屬性和對應的屬性值
例6:搜索‘a’標簽中,id屬性的值為“link2”的標簽。

    因為表示CSS類名的關鍵字class在Python中是保留字,所以,在按照CSS類名搜索tag的時候,如果使用class作為參數會導致語法的錯誤,不過,可以通過class_搜索指定CSS類名的tag,或者通過字典的方式指定參數。
例7:搜索‘a’標簽中,class屬性的值為“sister1”的標簽。

 例8:搜索‘a’標簽中,class屬性的值為“sister1”和屬性值為“sister3”的標簽。   

[3] recursive參數:是一個布爾變量。該參數為True,find_all()就會根據你的要求去查找標簽參數的所有子標簽,以及子標簽的子標簽。如果該參數為False,find_all()就只查找文檔一級標簽。該參數默認是True一般情況下不需要修改,除非你真正了解自己需要那些信息,而且抓去的速度非常重要,那么你可以設置該參數。
[4] string參數:通過該參數可以搜索文檔中的字符串內容,與name參數相似,其可選值一樣,接受:字符串正則表達式列表True,例如:
    soup.find_all(string = "Elsie")
    soup.find_all(string = ["Elsie", "Tillie", "Lacie"])
    soup.find_all(string = re.compile("Dormouse"))
    該參數還可以與其他參數混合使用來過濾:
    soup.find_all("a", string = "Elsie")
例9:搜索文檔樹中符合列表中參數的字符串內容。

[5] limit參數:find_all()方法返回的是全部的搜索結果,如果我們不需要全部結果,可以使用limit參數來限制返回結果的數量。當搜索到的結果數量達到limit的限制時,就停止搜索返回結果。find()方法實際上等價於find_all()的limit參數為1的情形。
例10:搜索'a'標簽並返回一個結果。

[6]keyword參數:如果一個指定名字的參數不是搜索內置的參數名,搜索時會把該參數當作指定名字tag的屬性來搜索。
    通過標簽參數name把標簽列表傳到find_all()里獲取一系列標簽,其實就是一個“或”關系的過濾器;而關鍵字參數keyword可以讓你增加一個“與”關系的過濾器來簡化工作。
    如果傳入一個名字為id的參數,BeautifulSoup會搜索每一個tag的id屬性,如果傳入href參數,則會搜索每一個tag的href屬性。在搜索指定名字的屬性時,可以使用的參數值包括:字符串正則表達式列表True
例11:在文檔樹中查找所有包含id屬性的tag,無論id屬性的值是什么。

例12:查找id屬性值為link2的標簽。

    除了上面的基礎應用之外,關於find_all()使用可以相當靈活,需要通過在實踐中不斷的體會和積累,我們在看幾個例子:
例13:使用多個指定名字的參數,同時過濾tag的多個屬性。

例14:將‘a’標簽中的網絡鏈接抓取出來。

例15:將‘a’標簽中的網絡鏈接和字符串抓取出來,形成可視數據。

例16:將class屬性值為“story”的‘p’標簽的全部子標簽的文本抓取出來。

7、小結

    對爬取網頁的解析工作,除了 BeautifulSoup之外,還可以使用re正則表達式lxml解析器xpath等等來實現,熟練掌握一個工具,學習其他的會很容易。BeautifulSoup的用法遠不止此,但作為網絡爬蟲的入門應用,上述知識基本足夠。如果在學習過程中觀看不練,會感覺非常抽象,無法理解;如果只知道敲代碼而忽略了為什么,也只能一知半解,難以靈活應用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM