第二章_復雜HTML解析

已經(jīng)確定目標內(nèi)容后,應該怎么做儡蔓?

· 尋找“打印此頁”的鏈接黍衙,或者看看網(wǎng)站有沒有 HTML 樣式更友好的移動版冕象。
· 尋找隱藏在 JavaScript 文件里的信息。
· 所需信息是否存在于其它網(wǎng)站龟梦?網(wǎng)站上顯示的數(shù)據(jù)是不是從其它網(wǎng)站上抓取的隐锭?

再來一碗 BeautifulSoup

通過屬性查找標簽

CSS 可以讓 HTML 元素呈現(xiàn)出差異化,使那些具有相同修飾元素呈現(xiàn)出不同的樣式计贰。

比如一個頁面中钦睡,小說任務對話都是紅色的,任務名稱都是綠色的躁倒。源代碼里的 span 標簽荞怒,引用了對應的 CSS 屬性,如下所示:
"<span class="red">Heavens! what a virulent attack!</span>" replied <span class="green">the prince</span>, not in the least disconcerted by this reception.
我們可以抓出整個頁面秧秉,然后創(chuàng)建一個 BeautifulSoup 對象:

from urllib.request import urlopen  
from bs4 import BeautifulSoup  
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")  
bsObj = BeautifulSoup(html)

通過 BeautifulSoup 對象褐桌,我們可以用 find_all 函數(shù)抽取只包含在 <span class="green"></span> 標簽里的文字,這樣就會得到一個人物名稱的 Python 列表:

name_list = bsObj.find_all('span', {'class':'green'})  
for name in name_list:      
    print(name.get_text())

代碼執(zhí)行后就會按照《戰(zhàn)爭與和平》中的人物出場順序顯示所有的人名象迎。這是怎么實現(xiàn)的呢荧嵌?

之前,我們調(diào)用 bsObj.tagName 只能獲取頁面中的第一個指定的標簽±剩現(xiàn)在完丽,調(diào)用 bsObj.find_all(tagName, tagAttributes) 可以獲取頁面中所有指定的標簽,不再只是第一個拇舀。

獲取人名列表之后逻族,程序遍歷列表中所有的名字,然后打印 name.get_text()骄崩,就可以把標簽中的內(nèi)容分開顯示了聘鳞。

find() 和 find_all()

這兩個函數(shù)非常類似,BeautifulSoup 文檔里兩者的定義是這樣的:

find_all(tag, attrs, recursive, text, limit, keywords)  
find(tag, attrs, recursive, text, keywords)

標簽參數(shù) tag 前面已經(jīng)介紹過——你可以傳一個標簽的名稱或者多個標簽名稱組成的列表做標簽參數(shù)要拂。

屬性參數(shù) attributes 是用一個Python字典封裝一個標簽的若干屬性和對應的屬性值抠璃。例如,下面這個函數(shù)會返回 HTML 文檔里紅色與綠色兩種顏色的 span 標簽:

.find_all('span', {'class':{'green', 'red'}})

遞歸參數(shù) recursive 是一個布爾變量脱惰。你想抓取 HTML 文檔標簽結(jié)構(gòu)里多少層的信息搏嗡?如果設置為 True,find_all() 就會查找標簽參數(shù)的所有子標簽,以及子標簽的子標簽采盒。如果設置為 False旧乞,find_all() 就只查找文檔的一級標簽。(默認值為 True)

文本參數(shù) text 有點不同磅氨,它是用標簽的文本內(nèi)容去匹配尺栖,而不是用標簽的屬性。假如我們想查找前面網(wǎng)頁中包含“the prince”內(nèi)容的標簽數(shù)量烦租,我們可以把之前的 find_all() 方法換成下面的代碼:

name_list = bsObj.find_all(text='the prince')  
print(len(name_list))

輸出結(jié)果為“7”延赌。

范圍限制參數(shù) limit。find 其實等價于 find_all 的limit 等于 1 時的情形叉橱。如果你只對網(wǎng)頁中獲取的前 n 項結(jié)果感興趣挫以,就可以設置它。但是前幾項的結(jié)果是按照網(wǎng)頁上的順序排序的窃祝。

還有一個關(guān)鍵詞參數(shù) keyword屡贺,可以讓你選擇哪些具有指定屬性的標簽。但是锌杀,任何關(guān)鍵詞參數(shù)能夠完成的任務甩栈,同樣可以用 attrs 解決。

通過標簽參數(shù)列表傳到 .find_all() 里獲取一列標簽糕再,其實就是一個“或”關(guān)系的過濾器量没。而關(guān)鍵詞參數(shù)可以讓你增加一個“與”關(guān)系的過濾器來簡化工作。

導航樹

獲取屬性

在網(wǎng)絡數(shù)據(jù)采集時你經(jīng)常不需要查找標簽的內(nèi)容突想,而是需要查找標簽屬性殴蹄。比如標簽 <a> 指向的URL鏈接包含在 href 屬性中,或者 <img> 標簽的圖片文件包含 src 屬性中猾担,這時獲取標簽屬性就變得非常有用了袭灯。

對于一個標簽對象,可以用下面的代碼獲取它的全部屬性:

myTag.attrs

這行代碼返回的是一個 Python 字典對象绑嘹,可以獲取和操作這些屬性稽荧。比如要獲取圖片的資源位置 src,可以用下面的代碼:

myTag.attrs['src']

lambda 表達式

BeautifulSoup 允許我們把特定函數(shù)類型當作 find_all() 函數(shù)的參數(shù)工腋。唯一的限制條件是這些函數(shù)必須把一個標簽作為參數(shù)且返回結(jié)果是布爾類型姨丈。 BeautifulSoup 用這個函數(shù)來評估它遇到的每個標簽對象,最后把評估結(jié)果為“真”的標簽保留擅腰,把其他標簽剔除蟋恬。

例如,下面的代碼就是獲取有兩個屬性的標簽:

soup.find_all(lambda tag: len(tag.attrs) == 2)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趁冈,一起剝皮案震驚了整個濱河市歼争,隨后出現(xiàn)的幾起案子拜马,更是在濱河造成了極大的恐慌,老刑警劉巖沐绒,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俩莽,死亡現(xiàn)場離奇詭異,居然都是意外死亡洒沦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門价淌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來申眼,“玉大人,你說我怎么就攤上這事蝉衣±ㄊ” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵病毡,是天一觀的道長濒翻。 經(jīng)常有香客問我,道長啦膜,這世上最難降的妖魔是什么有送? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮僧家,結(jié)果婚禮上雀摘,老公的妹妹穿的比我還像新娘。我一直安慰自己八拱,他們只是感情好阵赠,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肌稻,像睡著了一般清蚀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爹谭,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天枷邪,我揣著相機與錄音,去河邊找鬼诺凡。 笑死齿风,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的绑洛。 我是一名探鬼主播救斑,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼真屯!你這毒婦竟也來了脸候?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎运沦,沒想到半個月后泵额,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡携添,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年嫁盲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烈掠。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡羞秤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出左敌,到底是詐尸還是另有隱情瘾蛋,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布矫限,位于F島的核電站哺哼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏叼风。R本人自食惡果不足惜取董,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望无宿。 院中可真熱鬧甲葬,春花似錦、人聲如沸懈贺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梭灿。三九已至画侣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間堡妒,已是汗流浹背配乱。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皮迟,地道東北人搬泥。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像伏尼,于是被迫代替她去往敵國和親忿檩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

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

  • 1爆阶、獲取指定標簽內(nèi)容 2燥透、處理子標簽 3沙咏、處理兄弟標簽 4、父標簽處理 5班套、正則表達式
    VB過得VB閱讀 219評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理肢藐,服務發(fā)現(xiàn),斷路器吱韭,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 平時很喜歡聽歌吆豹,不同的心情搭配不同的音樂,不同的氛圍伴隨不同的旋律理盆,發(fā)現(xiàn)音樂對我來說是一個很高頻的需求痘煤,所以...
    Cuz_Loading閱讀 457評論 0 0
  • by:文琪 我遇見你,我記得你熏挎,這座城市天生就適合戀愛速勇,你天生就適合我的靈魂晌砾。 -杜拉斯 人們大多就年少時期...
    我們USlive閱讀 5,488評論 0 1
  • 今天來對雪迪龍养匈,聚光科技哼勇,先河環(huán)保通過經(jīng)營,管理呕乎,財務积担,與行業(yè)增長來分 從經(jīng)營來來說雪迪龍這兩年有緩慢趨勢 總結(jié):...
    西米韜閱讀 335評論 0 0