日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery

發(fā)布時(shí)間:2023/12/31 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

PyQuery:一個(gè)類似jquery的python庫(kù)

學(xué)習(xí)一時(shí)爽,一直學(xué)習(xí)一直爽

??Hello,大家好,我是 Connor,一個(gè)從無(wú)到有的技術(shù)小白。上一次我們說(shuō)到了 BeautifulSoup 美味的湯,BeautifulSoup 很適合剛剛接觸爬蟲的新手使用。雖然 BeautifulSoup 好用,但是也有它的局限性。今天我們來(lái)講一講 PyQuery,讓我們以 JQuery的方式來(lái)快速提取我們想要的內(nèi)容。廢話不多說(shuō),讓我們開始吧。

1. PyQuery 的簡(jiǎn)介

??pyquery 允許您在 xml 文檔上進(jìn)行 jquery 查詢。API 盡可能與 jquery 類似。pyquery 使用lxml 進(jìn)行快速 xml 和 html 操作。當(dāng)然這并不能用于生成 JavaScript 代碼或者與 JavaScript 進(jìn)行代碼交互。所以,如果你想在 Python 上運(yùn)行 JavaScript 代碼,那么 pyquery 不是一個(gè)好的選擇。


2. PyQuery 的簡(jiǎn)單使用

??pyquery還是非常容易上手的。現(xiàn)在,我們以下面的這段 xml 代碼為例,進(jìn)行演示:

html = """ <html><head><title>我的示例</title></head> <body><div class="book"><a class="book_title" id="book" href="abc.html">百煉成鋼</a><p class="book_author" id="author" >王者之勢(shì)</p><p class="time" id="time">2019/01/13</p></div></body> </html> """

??首先,我們先將這段文檔變成 PyQuery 對(duì)象,pyquery的操作基本都是通過(guò)PyQuery 對(duì)象來(lái)進(jìn)行的。你可以這樣做:

In [2]: from pyquery import PyQueryIn [3]: doc = PyQuery(html)In [4]: type(doc) Out[4]: pyquery.pyquery.PyQuery

??使用 CSS 選擇器可以快速地對(duì)節(jié)點(diǎn)進(jìn)行選擇,CSS 選擇器是一種快速高效的選擇方式,它可以在頁(yè)面中實(shí)現(xiàn) 一對(duì)一,一對(duì)多,多對(duì)一的多種控制,使用 CSS 選擇器無(wú)疑是一種快速便捷的提取方式,你只需要像JQuery一樣進(jìn)行選擇可以了:

In [10]: print(doc(".book")) <div class="book"><a class="book_title" id="book" href="abc.html">百煉成鋼</a><p class="book_author" id="author">王者之勢(shì)</p><p class="time" id="time">2019/01/13</p></div>

??可以看到,只要像JQuery一樣進(jìn)行選擇就可以輕而易舉的將我們想要的東西就選擇出來(lái)了,而且不需要像Xpath一樣去找它的路徑


3. 使用 PyQuery 選擇單一節(jié)點(diǎn)

3.1 通過(guò)節(jié)點(diǎn)名稱進(jìn)行選擇

??在 pyquery 中,你可以通過(guò)節(jié)點(diǎn)名來(lái)對(duì)節(jié)點(diǎn)進(jìn)行簡(jiǎn)單的選擇,當(dāng)某個(gè)節(jié)點(diǎn)在文檔中只出現(xiàn)一次的時(shí)候,這種方式是最簡(jiǎn)單的,你無(wú)需考慮其他因素的影響,就像這樣:

In [11]: c = doc("a")In [12]: print(c) <a class="book_title" id="book" href="abc.html">百煉成鋼</a>

??可以看到,很輕松的就將我們想要的節(jié)點(diǎn)選取出來(lái)了,但是很多時(shí)候某個(gè)節(jié)點(diǎn)有很多個(gè),很少有單獨(dú)出現(xiàn)一次的情況,這個(gè)時(shí)候我們就需要通過(guò)別的方法來(lái)進(jìn)行選擇了


3.2 通過(guò)屬性進(jìn)行選擇

??你也可以通過(guò)節(jié)點(diǎn)的屬性來(lái)選擇一個(gè)節(jié)點(diǎn),當(dāng)某個(gè)節(jié)點(diǎn)的某個(gè)屬性在文檔中是唯一的時(shí)候,這是最方便的做法。在上面的例子文檔中,有很多的節(jié)點(diǎn)都擁有唯一的屬性,所以,您可以這樣做:

In [13]: c = doc("#author")In [14]: print(c) <p class="book_author" id="author">王者之勢(shì)</p>

??我們可以看到,通過(guò)單獨(dú)的屬性是很容易選取出我們想要的的內(nèi)容的,這只是 id 屬性, 我們也可以使用 class 屬性來(lái)進(jìn)行快速選擇,其寫法也和 JQuery 相同,這里不再演示。 但是當(dāng)我們遇到其他的屬性的時(shí)候該怎么辦?我們可以通過(guò)指明屬性的名稱和值來(lái)進(jìn)行選擇, 就像這樣:

In [15]: c = doc('[href="abc.html"]')In [16]: print(c) <a class="book_title" id="book" href="abc.html">百煉成鋼</a>

??就像這樣,我們只是通過(guò)一個(gè)href屬性就選擇出了我們想要的節(jié)點(diǎn)。當(dāng)然,有些時(shí)候某個(gè)屬性也是眾多節(jié)點(diǎn)一起使用的,這個(gè)時(shí)候你可以結(jié)合我們講的第一種方法,通過(guò)節(jié)點(diǎn)名稱來(lái)進(jìn)行選擇,將節(jié)點(diǎn)與屬性進(jìn)行結(jié)合,來(lái)進(jìn)行選擇:

In [17]: c = doc('p[id="author"]')In [18]: print(c) <p class="book_author" id="author">王者之勢(shì)</p>

??通過(guò)上面的方法,還是基本上很容易滿足我們的需求了,但是有些時(shí)候,當(dāng)我們有更高的需求的時(shí)候,我們需要用到css的偽類選擇器,下面,我們將介紹偽類選擇器:


3.3 通過(guò)偽類來(lái)進(jìn)行選擇

??當(dāng)某些節(jié)點(diǎn)擁有多個(gè),或者與其它節(jié)點(diǎn)有太多重復(fù)屬性的時(shí)候,我們就需要用到偽類選擇器,偽類選擇器出了可以使用css自帶的偽類選擇器之外,pyquery 還提供了類似 JQuery 一樣的非標(biāo)準(zhǔn)偽類選擇器,這些偽類選擇器可以幫助我們快速的進(jìn)行選擇:

In [19]: c = doc("p:first")In [20]: print(c) <p class="book_author" id="author">王者之勢(shì)</p>

??偽類選擇器支持幾乎所有的 CSS 標(biāo)準(zhǔn)偽類以及 JQuery 的非標(biāo)準(zhǔn)偽類:

CSS 標(biāo)準(zhǔn)偽類

選擇器示例示例說(shuō)明
:checkedinput:checked選擇所有選中的表單元素
:disabledinput:disabled選擇所有禁用的表單元素
:emptyp:empty選擇所有沒(méi)有子元素的p元素
:enabledinput:enabled選擇所有啟用的表單元素
:first-of-typep:first-of-type選擇每個(gè)父元素是p元素的第一個(gè)p子元素
:last-childp:last-child選擇所有p元素的最后一個(gè)子元素
:last-of-typep:last-of-type選擇每個(gè)p元素是其母元素的最后一個(gè)p元素
:not(selector):not§選擇所有p以外的元素
:nth-child(n)p:nth-child(2)選擇所有 p 元素的父元素的第二個(gè)子元素
:nth-last-child(n)p:nth-last-child(2)選擇所有p元素倒數(shù)的第二個(gè)子元素
:nth-last-of-type(n)p:nth-last-of-type(2)選擇所有p元素倒數(shù)的第二個(gè)為p的子元素
:nth-of-type(n)p:nth-of-type(2)選擇所有p元素第二個(gè)為p的子元素
:only-of-typep:only-of-type選擇所有僅有一個(gè)子元素為p的元素
:only-childp:only-child選擇所有僅有一個(gè)子元素的p元素
:rootroot選擇文檔的根元素
:target#news:target選擇當(dāng)前活動(dòng)#news元素(點(diǎn)擊URL包含錨的名字)
:linka:link選擇所有未訪問(wèn)鏈接
:visiteda:visited選擇所有訪問(wèn)過(guò)的鏈接
:activea:active選擇正在活動(dòng)鏈接
:hovera:hover把鼠標(biāo)放在鏈接上的狀態(tài)
:focusinput:focus選擇元素輸入后具有焦點(diǎn)
:first-childp:first-child選擇器匹配屬于任意元素的第一個(gè)子元素的

元素

:lang(language)p:lang(it)

元素的lang屬性選擇一個(gè)開始值

上表部分取自--菜鳥教程

JQuery 非標(biāo)準(zhǔn)偽類

選擇器示例示例說(shuō)明
:firstp:first選擇第一個(gè)

元素

:lastp:last選擇最后一個(gè)

元素

:oddp:odd選擇所有

元素中索引為奇數(shù)的元素

:evenp:even選擇所有

元素中索引為偶數(shù)的元素

:eq(index)p:eq(0)選擇所有

元素中索引為0的元素

:lt(index)p:lt(3)選擇所有

元素中索引小于3的元素

:gt(index)p:gt(2)選擇所有

元素中索引大于2的元素

:header:header選擇所有的H1-H6的元素
:hiddenp:hidden選取所有

元素中包含有隱藏屬性的元素

:contains(text)p:contains(王者)選擇所有

元素中內(nèi)容包含有‘王者’的元素

:has(selector)div:has§選擇所有帶有

元素的

元素

:input:input選擇所有的元素
:(type)type指input的類型:submit選擇所有type為submit的元素
input的類型包括
button submit reset text checkbox image hidden file

??通過(guò)上列的偽類你可以更快更方便的對(duì)節(jié)點(diǎn)進(jìn)行選擇,當(dāng)然 pyquery 并不只有這些功能,它還有更多的功能:


4. 使用 PyQuery 選擇多個(gè)節(jié)點(diǎn)

??當(dāng)我們使用 PyQuery 進(jìn)行選擇的時(shí)候,難免會(huì)遇到某個(gè)節(jié)點(diǎn)都是使用同一種方式來(lái)進(jìn)行封裝的,他們的描述方式都是相同的,亦或者我們想要批量的選取某個(gè)東西的時(shí)候,他們的封裝形式是相同的,這樣很難進(jìn)行單一的選取。或者說(shuō)單一選取太麻煩了。此時(shí)我們就需要考慮選擇后的遍歷問(wèn)題了。因?yàn)橐粋€(gè)東西如果不能遍歷,對(duì)我們?nèi)≈涤泻艽蟮睦щy,PyQuery 自然也是可以進(jìn)行遍歷的,可能你會(huì)這樣做:

In [21]: c = doc('p')In [22]: for item in c:...: print(item)...: <Element p at 0x21395a4b448> <Element p at 0x21395a12888>

??你會(huì)發(fā)現(xiàn),通過(guò)這種方式打印出來(lái)的只是一個(gè)內(nèi)存地址,并沒(méi)有實(shí)際的東西。當(dāng)我們需要遍歷 PyQuery 選擇出來(lái)的東西的時(shí)候,我們需要使用 items() 方法。通過(guò)這種方法可以將選擇的多個(gè)內(nèi)容區(qū)分開來(lái):

In [23]: c = doc('p').items()In [24]: for item in c:...: print(item)...: <p class="book_author" id="author">王者之勢(shì)</p><p class="time" id="time">2019/01/13</p>

??通過(guò) items() 方法就可以打印出每一項(xiàng)的內(nèi)容了。


5. PyQuery 的其它使用方法

5.1 text() 方法

??當(dāng)我們獲取到指定的節(jié)點(diǎn)的時(shí)候,有時(shí)候我們需要獲取他的文本內(nèi)容,這個(gè)時(shí)候就需要的使用 text() 方法了,這個(gè)方法可以取出當(dāng)前 PyQuery 對(duì)象中的文本內(nèi)容,例如:

In [25]: c = doc('#author')In [26]: print(c.text()) 王者之勢(shì)

5.2 attr() 方法

??有些時(shí)候我們不只是需要提取文本內(nèi)容,有時(shí)候我們也需要提取節(jié)點(diǎn)中的屬性內(nèi)容,例如 href,這個(gè)時(shí)候我們就需要使用到 attr() 方法,通過(guò)該方法來(lái)進(jìn)行屬性內(nèi)容的提取:

In [13]: tags = doc('a').attr('href')...: print(tags) abc.html

5.3 html() 方法

??如果你所選擇的當(dāng)前節(jié)點(diǎn)還有子節(jié)點(diǎn),那么你可以通過(guò) html() 方法將當(dāng)前節(jié)點(diǎn)下的所有子元素選擇出來(lái),當(dāng)然,你也可以對(duì)它進(jìn)行更改,改變當(dāng)前節(jié)點(diǎn)下的內(nèi)容:

In [27]: c = doc('div')In [28]: print(c.html())<a class="book_title" id="book" href="abc.html">百煉成鋼</a><p class="book_author" id="author">王者之勢(shì)</p><p class="time" id="time">2019/01/13</p>

??或者你可以通過(guò)向html()方法中給參數(shù)的方法來(lái)改變當(dāng)前節(jié)點(diǎn)下的子節(jié)點(diǎn)內(nèi)容:

In [29]: c = doc('div')In [30]: print(c.html('abcdefghijklmnopqrstuvwxyz')) <div class="book">abcdefghijklmnopqrstuvwxyz</div>

5.4 find() 方法

??在找到某一節(jié)點(diǎn)的內(nèi)容之后,你還可以通過(guò) find() 方法來(lái)在當(dāng)前基礎(chǔ)上進(jìn)行二次查找甚至是多次查找,find() 的使用方法和正常的查找方式是相同的:

In [31]: c = doc('div').find('#author')In [32]: print(c) <p class="book_author" id="author">王者之勢(shì)</p>

5.5 children() 方法

??通過(guò) children() 方法可以快速的選取出某個(gè)節(jié)點(diǎn)下的所有子節(jié)點(diǎn),該方法同樣適用于多次查找,該方法的使用方法和 find() 方法類似:

In [33]: c = doc('div').children('p')In [34]: print(c) <p class="book_author" id="author">王者之勢(shì)</p><p class="time" id="time">2019/01/13</p>

??當(dāng) children() 方法不給參數(shù)的時(shí)候會(huì)默認(rèn)查找出所有的子節(jié)點(diǎn),請(qǐng)按需使用。


5.6 has_class() 方法

??有時(shí)候我們尋找某一節(jié)點(diǎn)需要用到 class 但每次都單獨(dú)去取該屬性再進(jìn)行判斷有些太麻煩了,PyQuery 為我們提供了 has_class() 方法,該方法可以快速的對(duì)節(jié)點(diǎn)是否擁有指定 class 屬性進(jìn)行判斷:

In [35]: tags = doc.find('a').has_class('book_title')...: print(tags) True

5.7 is_() 方法

??有的時(shí)候我們并不能只驗(yàn)證 class 屬性,還有其他的屬性需要我們進(jìn)行驗(yàn)證,或者使用其它屬性來(lái)進(jìn)行驗(yàn)證會(huì)更加的方便,這個(gè)時(shí)候我們就需要使用 is_() 方法。這個(gè)方法可以匹配節(jié)點(diǎn)中的任意屬性:

In [12]: tags = doc('p').eq(0).is_('[id="author"]')...: print(tags) True

5.9 對(duì)上述方法的總結(jié)

??總的來(lái)說(shuō),我覺(jué)得 pyquery 其實(shí)并沒(méi)有像想像中的那么好用,使用起來(lái)手感和 Xpath 差不了多少,甚至我個(gè)人認(rèn)為 Xpaht 更加好用一些,其實(shí)如果你仔細(xì)地看 pyquery 的源碼你就會(huì)發(fā)現(xiàn),其實(shí)它也使用了 Xpaht ,比較諷刺吧,但是 pyquery 確實(shí)是在 Xpath 的基礎(chǔ)上又做出了很大的改進(jìn),比如 偽類選擇器 這在一定情況下確實(shí)是要比 Xpath 要好用的多,所以其實(shí)解析并沒(méi)有什么難易,看你是否找對(duì)了適合的工具,就好比是否找到了適合腳的鞋子。找對(duì)了工具,事半功倍,找錯(cuò)了工具,事倍功半。希望你能夠靈活運(yùn)用。


下期預(yù)告

??Xpath 也講了,BeautifulSoup也講了,甚至PyQuery你也講了,怎么就是不講 re 正則呢??別著急,重頭戲總是在最后出場(chǎng),下一次我們就來(lái)講述,如何用 re 正則來(lái)獲取我們想要的內(nèi)容。敬請(qǐng)期待下期-- Python爬蟲十六式 - 第七式:正則的藝術(shù)

??好了,這就是今天的內(nèi)容了,不知道你今天又學(xué)會(huì)了多少內(nèi)容。我是 Connor,一個(gè)從無(wú)到有的技術(shù)小白,愿你能在前進(jìn)的道路上與我一同前行!

學(xué)習(xí)一時(shí)爽,一直學(xué)習(xí)一直爽!


系列文章連接:

Python 爬蟲十六式 - 第一式:HTTP協(xié)議 >>>
Python 爬蟲十六式 - 第二式:urllib 與 urllib3 >>>
Python 爬蟲十六式 - 第三式:Requests的用法 >>>
Python 爬蟲十六式 - 第四式: 使用Xpath提取網(wǎng)頁(yè)內(nèi)容 >>
Python 爬蟲十六式 - 第五式:BeautifulSoup-美味的湯 >>>
Python 爬蟲十六式 - 第七式:正則的藝術(shù) >>>

轉(zhuǎn)載于:https://www.cnblogs.com/miss85246/p/10397601.html

總結(jié)

以上是生活随笔為你收集整理的Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。