很多讀者在學(xué)習(xí)了 Python 之后都想做一些爬蟲(chóng)程序渠驼,去網(wǎng)上采集數(shù)據(jù)或完成一些自動(dòng)化操作敢会。因此想括,我們也制作了一套爬蟲(chóng)實(shí)戰(zhàn)課程柠辞,目前正在最后的完善中,很快將和各位見(jiàn)面主胧。
等不及的朋友叭首,可以先來(lái)看看這個(gè)類似于 bs4 的網(wǎng)頁(yè)分析模塊——PyQuery。
如果說(shuō)到 jQuery踪栋,熟悉前端的同學(xué)肯定不陌生焙格,它可以簡(jiǎn)單優(yōu)雅地對(duì) html 文件進(jìn)行定位、選擇夷都、移動(dòng)等操作眷唉。而本文的主角 pyquery,支持以 jquery 的方式對(duì) html 進(jìn)行操作。因此非常適合有前端或 js 基礎(chǔ)的同學(xué)使用冬阳。
廢話不多說(shuō)蛤虐,一邊看文章,一邊打開(kāi)編輯器肝陪,跟著我一探究竟吧驳庭。
1、安裝
安裝過(guò)程比較簡(jiǎn)單
pip install pyquery
2氯窍、入門(mén)使用
接下來(lái)饲常,我們以分析簡(jiǎn)書(shū)首頁(yè)文章為例,簡(jiǎn)單梳理 pyquery 的部分函數(shù) 狼讨。
2.1 導(dǎo)入相關(guān)的庫(kù)
分別導(dǎo)入 網(wǎng)絡(luò)請(qǐng)求庫(kù) - requests贝淤、以及 pyquery 。
import requests
import pyquery
2.2 向 pyquery 導(dǎo)入數(shù)據(jù)
本文的重點(diǎn)在于 pyquery政供,請(qǐng)求部分我就簡(jiǎn)單的一筆帶過(guò)播聪,大家知道使用 pyquery 有這么個(gè)流程就行了。
與 bs4 一樣布隔,處理網(wǎng)頁(yè)首先建立一個(gè) Pyquery 對(duì)象离陶。
# 請(qǐng)求簡(jiǎn)書(shū)地址
url = 'http://www.reibang.com/'
req = requests.get(url)
page = req.text
# 導(dǎo)入 pyquery 處理
pq = pyquery.PyQuery(page)
Pyquery 還可以直接調(diào)用內(nèi)置的網(wǎng)絡(luò)請(qǐng)求模塊,對(duì)于簡(jiǎn)單的網(wǎng)頁(yè)請(qǐng)求执泰,我們還可以直接這樣寫(xiě):
url = 'http://www.baidu.com'
pq = pyquery.PyQuery(url=url)
2.3 定位元素
pyquery 提供多種定位元素的方法枕磁,這里簡(jiǎn)單介紹三種,直接定位术吝、根據(jù) id
定位 计济,根據(jù) class
定位。
根據(jù) html 標(biāo)簽直接定位:
# 直接定位 head 標(biāo)簽
pq_head = pq('head')
以上代碼就是獲取 html 中 < head>.......< /head>
標(biāo)簽內(nèi)的內(nèi)容排苍。
根據(jù) id 定位:
在簡(jiǎn)書(shū)首頁(yè)源代碼中可找到這么一段
根據(jù) id 定位找到這個(gè) li
標(biāo)簽沦寂,代碼如下:
# 定位 id = note-11700031 的 li 標(biāo)簽
pq_id = pq('#note-11700031')
以上代碼獲取 id
名為 note-11700031
的標(biāo)簽,需要注意的是查詢 id 時(shí)添加 #
前綴淘衙,這是 css 選擇器語(yǔ)法传藏。
根據(jù) class 定位:
同樣以剛才的為例
我們根據(jù) class=have-img
去獲取這個(gè) div
標(biāo)簽
# 定位 class = have-img 的 div 標(biāo)簽
pq_class = pq('.have-img')
注意的是查詢 class
時(shí)添加 .
前綴,這也是 css 選擇器語(yǔ)法彤守。
2.3 索引標(biāo)簽
在上一節(jié)的最后有個(gè)小問(wèn)題毯侦,我們知道 head
標(biāo)簽在 html 中只有一個(gè),而 class
名為 have-img
的 li
標(biāo)簽可能有多個(gè)具垫,我們?cè)?br>
如何遍歷所有的 li
標(biāo)簽?zāi)兀?又該如何單獨(dú)的取某一個(gè) li
呢侈离?
首先我們可以逐個(gè)遍歷
# 遍歷所有 class = have-img 的 li 標(biāo)簽
for li in pq_class:
# 獲取每一個(gè) li 標(biāo)簽
pq_li = pq(li)
我們可以索引某一個(gè) li
標(biāo)簽
使用.ep(index)
函數(shù)。
# 獲取第一個(gè) li 標(biāo)簽
li_first = pq_class.ep(0)
# 獲取第二個(gè) li 標(biāo)簽
li_second = pq_class.ep(1)
2.4 尋找標(biāo)簽
同樣回到剛剛的那張圖
在上一步筝蚕,我們已經(jīng)找到了所有的 li
標(biāo)簽卦碾,也知道如何取索引其中的元素铺坞,但我們現(xiàn)在要準(zhǔn)確定位到某一個(gè)元素,比如上圖中 id = note-11772642
這個(gè) li
標(biāo)簽洲胖。
這時(shí)候 filter(selecter)
就派上了用場(chǎng)
li_spec = pq_class.filter('#note-11772642')
這樣我們就找到了指定的這個(gè) li
標(biāo)簽济榨,需要注意的是, filter
函數(shù)只能在同一級(jí)標(biāo)簽中尋找绿映,比如在這里只能過(guò)濾 li
標(biāo)簽擒滑,而不能定位 li
標(biāo)簽下的 a
標(biāo)簽、 div
標(biāo)簽等绘梦。
當(dāng)然橘忱,針對(duì)這種情況赴魁, pyquery 為我們提供了另外一個(gè)函數(shù) find(selector)
卸奉,該函數(shù)用于尋找子節(jié)點(diǎn),繼續(xù)以上圖為例颖御,尋找該特定 li 標(biāo)簽下的 p 標(biāo)簽
p_tag = li_spec.find('p')
2.5 提取屬性與值
以上我們講了許多關(guān)于標(biāo)簽的知識(shí)榄棵,現(xiàn)在來(lái)談?wù)勗趺传@取標(biāo)簽內(nèi)的屬性和標(biāo)簽包裹的文本,實(shí)際的爬蟲(chóng)項(xiàng)目中潘拱,通常這是最重要的一步疹鳄,比如從 a
標(biāo)簽中獲取鏈接、從 li
標(biāo)簽或者 p
標(biāo)簽中獲取文本芦岂。
獲取屬性:
使用 attr()
函數(shù)瘪弓,以我們之前獲取的 li
標(biāo)簽為例,獲取其中的 id
屬性
# 獲取 id 屬性的方法
li_spec_id = li_spec.attr('id')
li_spec_id_2 = li_spec.attr.id
li_spec_id_3 = li_spec.attr['id']
獲取文本:
使用 text()
函數(shù)禽最, 以我們之前得到的 p
標(biāo)簽為例腺怯,獲取其中的文本。
string = p_tag.text()
到此川无,在爬蟲(chóng)中會(huì)使用到的函數(shù)就是這些了呛占。
3、小結(jié)
pyquery 還擁有操作文檔樹(shù)的能力懦趋,本篇文章著重介紹與爬蟲(chóng)相關(guān)的知識(shí)晾虑,所以就不再此詳細(xì)敘述了,有興趣的同學(xué)移步官方文檔:
http://pythonhosted.org/pyquery/index.html
最后仅叫,既然我們都分析了簡(jiǎn)書(shū)首頁(yè)帜篇,請(qǐng)大家根據(jù)所學(xué)內(nèi)容爬取簡(jiǎn)書(shū)首頁(yè)所有的文章標(biāo)題和文章鏈接,然后打印出來(lái)吧诫咱,像下圖一樣
當(dāng)然笙隙,我們也給出參考代碼:
https://git.oschina.net/zx576/Crossin-practices/blob/master/python_weekly_modual/modual_pyquery/query.py