05 頁面解析

05 頁面解析

一、BeautifulSoup

BeautifulSoup 是一個可以從HTML或XML文件中提取數(shù)據(jù)的Python庫沧竟,它的使用方式相對于正則來說更加的簡單方便碗殷,常常能夠節(jié)省我們大量的時間。

官方中文文檔的:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

BeautifulSoup的安裝也是非常方便的,pip安裝即可抹镊。
pip install beautifulsoup4

1、簡單例子

# 實(shí)例BeautifulSoup對象
soup = BeautifulSoup(html_doc,'lxml')

print(soup.title)   # 獲取title標(biāo)簽
print(soup.title.name)  # 獲取title標(biāo)簽的標(biāo)簽名
print(soup.title.string)    # 獲取title標(biāo)簽的文字內(nèi)容
print(soup.title.parent.name) # 獲取title標(biāo)簽父標(biāo)簽的標(biāo)簽名
print(soup.a) # 獲取第一個a標(biāo)簽    # <a href="homepage.html">首頁</a>
print(soup.a.attrs) # 獲取屬性 {'href': 'homepage.html'}
print(soup.a.string)    # 首頁
print(soup.p['class'])
print(soup.find_all('a'))   # 獲取所有的a標(biāo)簽
print(soup.find(id='link3'))   # 獲取id為link3的標(biāo)簽

print(type(soup))   # <class 'bs4.BeautifulSoup'>
print(soup.name)    # [document]
print(soup.attrs)   # {}

print(soup.li)  # <li><a href="homepage.html"><!--首頁--></a></li>
print(soup.li.string)   # 首頁

2瞪慧、指定解析器

BeautifulSoup解析網(wǎng)頁需要指定一個可用的解析器髓考,以下是主要幾種解析器:

01.jpg

由于這個解析的過程在大規(guī)模的爬取中是會影響到整個爬蟲系統(tǒng)的速度的,所以推薦使用的是lxml弃酌,速度會快很多氨菇,而lxml需要單獨(dú)安裝:

pip install lxml
soup = BeautifulSoup(html_doc, 'lxml') # 指定

提示:如果一段HTML或XML文檔格式不正確的話,那么在不同的解析器中返回的結(jié)果可能是不一樣的,所以要指定某一個解析器妓湘。

3查蓉、節(jié)點(diǎn)對象

02.jpg

5、Tag與遍歷文檔樹

tag對象可以說是BeautifulSoup中最為重要的對象榜贴,通過BeautifulSoup來提取數(shù)據(jù)基本都圍繞著這個對象來進(jìn)行操作豌研。

首先,一個節(jié)點(diǎn)中是可以包含多個子節(jié)點(diǎn)和多個字符串的唬党。例如html節(jié)點(diǎn)中包含著head和body節(jié)點(diǎn)鹃共。所以BeautifulSoup就可以將一個HTML的網(wǎng)頁用這樣一層層嵌套的節(jié)點(diǎn)來進(jìn)行表示。

03.jpg

6驶拱、find_all()

上方這種直接通過屬性來進(jìn)行訪問屬性的方法霜浴,很多時候只能適用于比較簡單的一些場景,所以BeautifulSoup還提供了搜索整個文檔樹的方法find_all()蓝纲。

通過name搜索阴孟,find_all('b')可以直接查找出整個文檔樹中所有的b標(biāo)簽,并返回列表

通過屬性搜索税迷,我們在搜索的時候一般只有標(biāo)簽名是不夠的永丝,因為可能同名的標(biāo)簽很多,那么這時候我們就要通過標(biāo)簽的屬性來進(jìn)行搜索箭养。這時候我們可以通過傳遞給attrs一個字典參數(shù)來搜索屬性慕嚷。

soup.find_all(attrs={'class': 'sister'})

通過文本搜索,在find_all()方法中,還可以根據(jù)文本內(nèi)容來進(jìn)行搜索闯冷。soup.find_all(text="Elsie")

限制查找范圍為子節(jié)點(diǎn)

find_all()方法會默認(rèn)的去所有的子孫節(jié)點(diǎn)中搜索砂心,而如果將recursive參數(shù)設(shè)置為False,則可以將搜索范圍限制在直接子節(jié)點(diǎn)中蛇耀。 soup.html.find_all("title", recursive=False)

通過正則表達(dá)式來篩選查找結(jié)果在BeautifulSoup中辩诞,也是可以與re模塊進(jìn)行相互配合的,將re.compile編譯的對象傳入find_all()方法纺涤,即可通過正則來進(jìn)行搜索译暂。

tags = soup.find_all(re.compile("^b"))

7、css選擇器查找

在BeautifulSoup中撩炊,同樣也支持使用CSS選擇器來進(jìn)行搜索外永。使用select(),在其中傳入字符串參數(shù)拧咳,就可以使用CSS選擇器的語法來找到tag伯顶。

print(soup.select('.top .menu'))
# [<ul class="menu">
# <li><a href="homepage.html"><!--首頁--></a></li>
# <li><a href="online.html">在線課堂</a></li>
# <li><a href="consult.html">付費(fèi)咨詢</a></li>
# <li><a href="search.html">搜索</a></li>
# </ul>]

二、xpath

XPath 是一門在 XML 文檔中查找信息的語言骆膝。XPath 可用來在 XML 文檔中對元素和屬性進(jìn)行遍歷祭衩。

相比于BeautifulSoup,Xpath在提取數(shù)據(jù)時會更有效率阅签。

在python中很多庫都提供XPath的功能掐暮,但是最流行的還是lxml這個庫,效率最高政钟。在之前BeautifulSoup中我們也介紹了lxml是如何安裝的路克。

pip install lxml

1、語法

XPath 使用路徑表達(dá)式在 XML/HTML 文檔中選取節(jié)點(diǎn)养交。節(jié)點(diǎn)是通過沿著路徑或者 step 來選取的精算。

04.jpg
05.jpg
06.jpg
07.jpg

nodename 選取當(dāng)前節(jié)點(diǎn)的所有nodename子節(jié)點(diǎn)
/ 從根節(jié)點(diǎn)選取
// 從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮它們的位置碎连。
. 選取當(dāng)前節(jié)點(diǎn)
.. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)
@ 選取屬性

例子
//bookstore/book[1] 選取屬于 bookstore 子元素的第一個 book 元素灰羽。
//bookstore/book[last()] 選取屬于 bookstore 子元素的最后一個 book 元素。
//bookstore/book[last()-1] 選取屬于 bookstore 子元素的倒數(shù)第二個 book 元素破花。
//bookstore/book[position()<3] 選取最前面的兩個屬于 bookstore 元素的子元素的 book 元素。
//title[@lang] 選取所有擁有名為 lang 的屬性的 title 元素疲吸。
//title[@lang='eng'] 選取所有 title 元素座每,且這些元素?fù)碛兄禐?eng 的 lang 屬性。
//bookstore/book[price>35.00] 選取 bookstore 元素的所有 book 元素摘悴,且其中的 price 元素的值須大于 35.00峭梳。
//bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大于 35.00。

  • 匹配任何元素節(jié)點(diǎn) //bookstore/* 選取bookstore元素的所有子元素葱椭。
    • 匹配任何屬性節(jié)點(diǎn) //* 選取文檔中國的所有元素
      de() 匹配任何類型的節(jié)點(diǎn) //title[@*] 選取所有帶有屬性的title元素

選取多個路徑
通過在路徑表達(dá)式中使用"|"運(yùn)算符捂寿,您可以選取若干個路徑。
在下面的表格中孵运,我們列出了一些路徑表達(dá)式秦陋,以及這些表達(dá)式的結(jié)果:

//book/title | //book/price 選取book元素的所有title和price元素
//title | //price 選取文檔中所有的title和price元素
//bookstore/book/title | //price 選取bookstore元素的book元素的所有title元素,以及文檔中所有的price元素

用text()獲取某個節(jié)點(diǎn)下的文本

08.jpg

用string()獲取某個節(jié)點(diǎn)下所有的文本

09.jpg

2治笨、例子

from lxml import etree
import requests

# 獲取網(wǎng)頁源代碼
resp = requests.get('http://www.baidu.com').content.decode()

# 實(shí)例化
selector = etree.HTML(resp)
print(selector.xpath('//div[@id="u1"]/a[@class="mnav"]/@href'))
print(selector.xpath('//div[@id="u1"]/a[@class="mnav"]/text()'))    # ['新聞', 'hao123', '地圖', '視頻', '貼吧']
print(selector.xpath('//a/text()'))
# 模糊匹配 匹配 id中含有“a“的標(biāo)簽
print(selector.xpath('//div[contains(@id,"a")]'))
print(selector.xpath('//a[1]/text()'))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驳概,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子旷赖,更是在濱河造成了極大的恐慌顺又,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件等孵,死亡現(xiàn)場離奇詭異稚照,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俯萌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門果录,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绳瘟,你說我怎么就攤上這事雕憔。” “怎么了糖声?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵斤彼,是天一觀的道長。 經(jīng)常有香客問我蘸泻,道長琉苇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任悦施,我火速辦了婚禮并扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抡诞。我一直安慰自己穷蛹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布昼汗。 她就那樣靜靜地躺著肴熏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顷窒。 梳的紋絲不亂的頭發(fā)上蛙吏,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼鸦做。 笑死励烦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泼诱。 我是一名探鬼主播坛掠,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坷檩!你這毒婦竟也來了却音?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矢炼,失蹤者是張志新(化名)和其女友劉穎系瓢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體句灌,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夷陋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胰锌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骗绕。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖资昧,靈堂內(nèi)的尸體忽然破棺而出酬土,到底是詐尸還是另有隱情,我是刑警寧澤格带,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布撤缴,位于F島的核電站,受9級特大地震影響叽唱,放射性物質(zhì)發(fā)生泄漏屈呕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一棺亭、第九天 我趴在偏房一處隱蔽的房頂上張望虎眨。 院中可真熱鬧,春花似錦镶摘、人聲如沸嗽桩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碌冶。三九已至,卻和暖如春贡未,著一層夾襖步出監(jiān)牢的瞬間种樱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工俊卤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫩挤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓消恍,卻偏偏與公主長得像岂昭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狠怨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

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