python:BeautifulSoup 模塊使用指南

BeautifulSoup

官方文檔如下介紹:

Beautiful Soup 是一個可以從 HTMLXML 文件中提取數(shù)據(jù)的 Python 庫.它能夠通過你喜歡的轉(zhuǎn)換器實現(xiàn)慣用的文檔導(dǎo)航,查找,修改文檔的方式.Beautiful Soup 會幫你節(jié)省數(shù)小時甚至數(shù)天的工作時間.


1. 安裝

以下都是在 python2.7 中進行測試的

可以直接使用 pip 安裝:

$ pip install beautifulsoup4

BeautifulSoup 不僅支持 HTML 解析器,還支持一些第三方的解析器,如,lxml,XML,html5lib 但是需要安裝相應(yīng)的庫。

$ pip install lxml

$ pip install html5lib

2. 開始使用

Beautiful Soup 的功能相當(dāng)強大,但我們只介紹經(jīng)常使用的功能。

簡單用法

將一段文檔傳入 BeautifulSoup 的構(gòu)造方法,就能得到一個文檔的對象, 可以傳入一段字符串或一個文件句柄.


>>> from bs4 import BeautifulSoup

>>> soup = BeautifulSoup("<html><body><p>data</p></body></html>")

>>> soup
<html><body><p>data</p></body></html>

>>> soup('p')
[<p>data</p>]

首先傳入一個 html 文檔,soup 是獲得文檔的對象。然后,文檔被轉(zhuǎn)換成 Unicode ,并且 HTML 的實例都被轉(zhuǎn)換成 Unicode 編碼。然后,Beautiful Soup 選擇最合適的解析器來解析這段文檔,如果手動指定解析器那么 Beautiful Soup 會選擇指定的解析器來解析文檔。但是一般最好手動指定解析器,并且使用 requestsBeautifulSoup 結(jié)合使用, requests 是用于爬取網(wǎng)頁源碼的一個庫,此處不再介紹,requests 更多用法請參考 Requests 2.10.0 文檔

  • 要解析的文檔是什么類型: 目前支持, html, xml,html5
  • 指定使用哪種解析器: 目前支持, lxml, html5lib,html.parser

from bs4 import BeautifulSoup
import requests

html = requests.get(‘http://www.lxweimin.com/’).content  
soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')
result = soup('div')

對象的種類

Beautiful Soup 將復(fù)雜 HTML 文檔轉(zhuǎn)換成一個復(fù)雜的樹形結(jié)構(gòu),每個節(jié)點都是 Python 對象,所有對象可以歸納為 4 種: Tag , NavigableString , BeautifulSoup , Comment .

  • Tag:通俗點講就是 HTML 中的一個個標簽,像上面的 div,p。每個 Tag 有兩個重要的屬性 nameattrs,name 指標簽的名字或者 tag 本身的 name,attrs 通常指一個標簽的 class
  • NavigableString:獲取標簽內(nèi)部的文字,如,soup.p.string
  • BeautifulSoup:表示一個文檔的全部內(nèi)容。
  • Comment:Comment 對象是一個特殊類型的 NavigableString 對象,其輸出的內(nèi)容不包括注釋符號.

示例

下面是一個示例,帶你了解 Beautiful Soup 的常見用法:


import sys  
reload(sys)  
sys.setdefaultencoding('utf-8') 
from bs4 import BeautifulSoup
import requests


html_doc = """
<head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <title>首頁 - 簡書</title>
</head>

<body class="output fluid zh cn win reader-day-mode reader-font2 " data-js-module="recommendation" data-locale="zh-CN">

<ul class="article-list thumbnails">

  <li class=have-img>
      <a class="wrap-img" href="/p/49c4728c3ab2"><img src="http://upload-images.jianshu.io/upload_images/2442470-745c6471c6f8258c.jpg?imageMogr2/auto-orient/strip%7CimageView2/1/w/300/h/300" alt="300" /></a>
    <div>
      <p class="list-top">
        <a class="author-name blue-link" target="_blank" href="/users/0af6b163b687">阿隨向前沖</a>
        <em>·</em>
        <span class="time" data-shared-at="2016-07-27T07:03:54+08:00"></span>
      </p>
      <h4 class="title"><a target="_blank" href="/p/49c4728c3ab2"> 只裝了這六款軟件,工作就高效到有時間逛某寶刷某圈</a></h4>
      <div class="list-footer">
        <a target="_blank" href="/p/49c4728c3ab2">
          閱讀 1830
</a>        <a target="_blank" href="/p/49c4728c3ab2#comments">
           · 評論 35
</a>        <span> · 喜歡 95</span>
          <span> · 打賞 1</span>
        
      </div>
    </div>
  </li>
</ul>

</body>
"""

soup = BeautifulSoup(html_doc, 'html.parser', from_encoding='utf-8')

# 查找所有有關(guān)的節(jié)點
tags = soup.find_all('li', class_="have-img")

for tag in tags:
        image = tag.img['src']
        article_user = tag.p.a.get_text()
        article_user_url = tag.p.a['href']      
        created = tag.p.span['data-shared-at']        
        article_url = tag.h4.a['href']

        # 可以在查找的 tag 下繼續(xù)使用 find_all()
        tag_span = tag.div.div.find_all('span')

        likes = tag_span[0].get_text(strip=True)

BeautifulSoup 主要用來遍歷子節(jié)點及子節(jié)點的屬性,通過點取屬性的方式只能獲得當(dāng)前文檔中的第一個 tag,例如,soup.li。如果想要得到所有的<li> 標簽,或是通過名字得到比一個 tag 更多的內(nèi)容的時候,就需要用到 find_all()find_all() 方法搜索當(dāng)前 tag 的所有 tag 子節(jié)點,并判斷是否符合過濾器的條件find_all() 所接受的參數(shù)如下:

find_all( name , attrs , recursive , string , **kwargs )
  1. name 搜索: name 參數(shù)可以查找所有名字為 nametag,字符串對象會被自動忽略掉:

     soup.find_all("li")
    
  2. id 搜索: 如果包含一個名字為 id 的參數(shù),搜索時會把該參數(shù)當(dāng)作指定名字 tag 的屬性來搜索:

     soup.find_all(id='link2')
    
  3. attr 搜索:有些 tag 屬性在搜索不能使用,比如 HTML5 中的 data-* 屬性,但是可以通過 find_all() 方法的 attrs 參數(shù)定義一個字典參數(shù)來搜索包含特殊屬性的 tag:

     data_soup.find_all(attrs={"data-foo": "value"})
    
  4. CSS 搜索: 按照 CSS 類名搜索 tag 的功能非常實用,但標識CSS 類名的關(guān)鍵字 classPython 中是保留字,使用 class 做參數(shù)會導(dǎo)致語法錯誤.從 Beautiful Soup 的 4.1.1 版本開始,可以通過 class_ 參數(shù)搜索有指定 CSS 類名的 tag:

     soup.find_all('li', class_="have-img")
    
  5. string 參數(shù):通過 string 參數(shù)可以搜搜文檔中的字符串內(nèi)容.與 name 參數(shù)的可選值一樣, string 參數(shù)接受 字符串 , 正則表達式 , 列表, True 。 看例子:

     soup.find_all("a", string="Elsie")
    
  6. recursive 參數(shù):調(diào)用 tagfind_all() 方法時,Beautiful Soup 會檢索當(dāng)前 tag 的所有子孫節(jié)點,如果只想搜索 tag 的直接子節(jié)點,可以使用參數(shù) recursive=False .

     soup.find_all("title", recursive=False)
    

find_all() 幾乎是 Beautiful Soup中最常用的搜索方法,也可以使用其簡寫方法,以下代碼等價:

    soup.find_all("a")
    soup("a")

get_text()

如果只想得到 tag 中包含的文本內(nèi)容,那么可以用 get_text() 方法,這個方法獲取到 tag 中包含的所有文版內(nèi)容包括子孫 tag 中的內(nèi)容,并將結(jié)果作為 Unicode 字符串返回:

    tag.p.a.get_text()

如果想看更多內(nèi)容,請參考 Beautiful Soup 4.4.0 文檔 (中文文檔)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,844評論 2 372

推薦閱讀更多精彩內(nèi)容