python:BeautifulSoup 模塊使用指南

BeautifulSoup

官方文檔如下介紹:

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


1. 安裝

以下都是在 python2.7 中進(jìn)行測(cè)試的

可以直接使用 pip 安裝:

$ pip install beautifulsoup4

BeautifulSoup 不僅支持 HTML 解析器,還支持一些第三方的解析器济竹,如勉耀,lxml痰憎,XML忱反,html5lib 但是需要安裝相應(yīng)的庫(kù)。

$ pip install lxml

$ pip install html5lib

2. 開(kāi)始使用

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

簡(jiǎn)單用法

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


>>> 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>]

首先傳入一個(gè) html 文檔,soup 是獲得文檔的對(duì)象趣斤。然后,文檔被轉(zhuǎn)換成 Unicode ,并且 HTML 的實(shí)例都被轉(zhuǎn)換成 Unicode 編碼。然后,Beautiful Soup 選擇最合適的解析器來(lái)解析這段文檔,如果手動(dòng)指定解析器那么 Beautiful Soup 會(huì)選擇指定的解析器來(lái)解析文檔黎休。但是一般最好手動(dòng)指定解析器浓领,并且使用 requestsBeautifulSoup 結(jié)合使用, requests 是用于爬取網(wǎng)頁(yè)源碼的一個(gè)庫(kù)势腮,此處不再介紹联贩,requests 更多用法請(qǐng)參考 Requests 2.10.0 文檔

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

from bs4 import BeautifulSoup
import requests

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

對(duì)象的種類

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

  • Tag:通俗點(diǎn)講就是 HTML 中的一個(gè)個(gè)標(biāo)簽捎拯,像上面的 div泪幌,p。每個(gè) Tag 有兩個(gè)重要的屬性 nameattrs署照,name 指標(biāo)簽的名字或者 tag 本身的 name祸泪,attrs 通常指一個(gè)標(biāo)簽的 class
  • NavigableString:獲取標(biāo)簽內(nèi)部的文字建芙,如没隘,soup.p.string
  • BeautifulSoup:表示一個(gè)文檔的全部?jī)?nèi)容禁荸。
  • Comment:Comment 對(duì)象是一個(gè)特殊類型的 NavigableString 對(duì)象右蒲,其輸出的內(nèi)容不包括注釋符號(hào).

示例

下面是一個(gè)示例,帶你了解 Beautiful Soup 的常見(jiàn)用法:


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>首頁(yè) - 簡(jiǎn)書</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"> 只裝了這六款軟件赶熟,工作就高效到有時(shí)間逛某寶刷某圈</a></h4>
      <div class="list-footer">
        <a target="_blank" href="/p/49c4728c3ab2">
          閱讀 1830
</a>        <a target="_blank" href="/p/49c4728c3ab2#comments">
           · 評(píng)論 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é)點(diǎn)
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 主要用來(lái)遍歷子節(jié)點(diǎn)及子節(jié)點(diǎn)的屬性品嚣,通過(guò)點(diǎn)取屬性的方式只能獲得當(dāng)前文檔中的第一個(gè) tag,例如钧大,soup.li。如果想要得到所有的<li> 標(biāo)簽,或是通過(guò)名字得到比一個(gè) tag 更多的內(nèi)容的時(shí)候,就需要用到 find_all()罩旋,find_all() 方法搜索當(dāng)前 tag 的所有 tag 子節(jié)點(diǎn),并判斷是否符合過(guò)濾器的條件find_all() 所接受的參數(shù)如下:

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

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

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

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

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

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

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

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

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

get_text()

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

    tag.p.a.get_text()

如果想看更多內(nèi)容瓜饥,請(qǐng)參考 Beautiful Soup 4.4.0 文檔 (中文文檔)逝撬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乓土,隨后出現(xiàn)的幾起案子宪潮,更是在濱河造成了極大的恐慌,老刑警劉巖趣苏,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡相,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡食磕,警方通過(guò)查閱死者的電腦和手機(jī)尽棕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)彬伦,“玉大人滔悉,你說(shuō)我怎么就攤上這事〉グ螅” “怎么了回官?”我有些...
    開(kāi)封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搂橙。 經(jīng)常有香客問(wèn)我歉提,道長(zhǎng),這世上最難降的妖魔是什么份氧? 我笑而不...
    開(kāi)封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任唯袄,我火速辦了婚禮,結(jié)果婚禮上蜗帜,老公的妹妹穿的比我還像新娘恋拷。我一直安慰自己,他們只是感情好厅缺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布蔬顾。 她就那樣靜靜地躺著,像睡著了一般湘捎。 火紅的嫁衣襯著肌膚如雪诀豁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天窥妇,我揣著相機(jī)與錄音舷胜,去河邊找鬼。 笑死活翩,一個(gè)胖子當(dāng)著我的面吹牛烹骨,可吹牛的內(nèi)容都是我干的翻伺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼沮焕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吨岭!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起峦树,我...
    開(kāi)封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辣辫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后魁巩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體急灭,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年歪赢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了化戳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埋凯,死狀恐怖点楼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情白对,我是刑警寧澤掠廓,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站甩恼,受9級(jí)特大地震影響蟀瞧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜条摸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一悦污、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钉蒲,春花似錦切端、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至钙蒙,卻和暖如春茵瀑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躬厌。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工马昨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓鸿捧,卻偏偏與公主長(zhǎng)得像抢呆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笛谦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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