PyQuery 詳解

PyQuery 庫是一個(gè)非常強(qiáng)大又靈活的網(wǎng)頁解析庫,如果你有前端開發(fā)經(jīng)驗(yàn),那么你應(yīng)該接觸過 jQuery ,那么PyQuery就是你非常絕佳的選擇,PyQuery 是 Python 仿照 jQuery 的嚴(yán)格實(shí)現(xiàn),語法與 jQuery 幾乎完全相同。

安裝

跟安裝其他庫一樣:

>>> pip3 install pyquery

安裝了之后,在程序里面就可以引用了,引用方法跟其他庫類似:

from pyquery import PyQuery as pq

初始化

PyQuery 可以將 HTML 字符串初始化為對(duì)象,也可以將 HTML 文件初始化為對(duì)象,甚至可以將請(qǐng)求的響應(yīng)初始化為對(duì)象。下面我們一個(gè)個(gè)來介紹。

初始化字符串

對(duì)于一個(gè)標(biāo)準(zhǔn)的 HTML 字符串,PyQuery 可以直接初始化為對(duì)象:

html = """
<html>
    <head>
        我愛我的祖國
        <title>China</title>
    </head>
    <body>
        <ul id="container">
            <li class="li1">五星</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)</li>
        </ul>
    </body>
</html>
"""

doc = pq(html)
print(type(doc))
print(doc)

#返回
<class 'pyquery.pyquery.PyQuery'>
<html>
    <head>
        我愛我的祖國
        <title>China</title>
    </head>
    <body>
        <ul id="container">
            <li class="li1">五星</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)</li>
        </ul>
    </body>
</html>

我們可以看到,HTML 字符串初始化后,打印出來的是一個(gè) PyQuery 對(duì)象。

如果我們的字符串不是 HTML 格式內(nèi)容,PyQuery 會(huì)自動(dòng)加上段落標(biāo)簽將字符串內(nèi)容包裝成 HTML 內(nèi)容。例如:

test = '''
this is a string
this is second row
'''

doc = pq(test)
print(type(doc))
print(doc)

#返回
<class 'pyquery.pyquery.PyQuery'>
<p>this is a string
this is second row
</p>

初始化 HTML 文件

初始化文件,只需要加個(gè) filename 參數(shù),指明 文件路徑即可:

#filename參數(shù)為html文件路徑
test_html = pq(filename='test.html')
print(type(test_html))
print(test_html)

#返回
<class 'pyquery.pyquery.PyQuery'>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>

</body>
</html>

如果文件不是 HTML 文件,那么初始化的時(shí)候會(huì)自動(dòng)加上 HTML 標(biāo)簽。例如:

#filename參數(shù)為html文件路徑
test_txt = pq(filename='test.txt')
print(type(test_txt))
print(test_txt)

#返回
<class 'pyquery.pyquery.PyQuery'>
<html><body><p>this is a txt</p></body></html>

我的 test.txt 文件中只有一行內(nèi)容: this is a txt。初始化完后,自動(dòng)添加了 HTML 標(biāo)簽。

初始化請(qǐng)求響應(yīng)

我們可以把請(qǐng)求的網(wǎng)址內(nèi)容初始化為 PyQuery 對(duì)象,只需要加個(gè)參數(shù) url ,將網(wǎng)址賦值給它即可。例如:

response = pq(url='https://www.baidu.com')
print(type(response))
print(response)

#返回
<class 'pyquery.pyquery.PyQuery'>
<html> <head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><meta content="always" name="referrer"/><link
...

我們請(qǐng)求百度的首頁,然后初始化為對(duì)象,后面內(nèi)容較多,因此省略。

常用 CSS 選擇器

PyQuery 里面 CSS 選擇器的用法跟 jQuery 里面是一樣的,例如,針對(duì)上面的 HTML 字符串內(nèi)容,我們獲取 id 為 container 的標(biāo)簽,然后打印出來:

doc = pq(html)
print(type(doc('#container')))
print(doc('#container'))

#返回
<class 'pyquery.pyquery.PyQuery'>
<ul id="container">
            <li class="li1">五星</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)</li>
        </ul>

我們也可以用 class 選擇器,例如:

print(type(doc('.li2')))
print(doc('.li2'))

#返回
<class 'pyquery.pyquery.PyQuery'>
<li class="li2">紅旗</li>

再復(fù)雜一點(diǎn),我們可以使用多層選擇器,例如:

print(doc('html #container'))

#返回
<ul id="container">
            <li class="li1">五星</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)</li>
        </ul>

當(dāng)然,我們同樣可以根據(jù) CSS 選擇器修改 HTML 標(biāo)簽的內(nèi)容:

li2 = doc('.li2')
li2.css('font-size', '18px')
print(li2)

#返回
<li class="li2" style="font-size: 18px">紅旗</li>

這里我們給 class 為“l(fā)i2”的標(biāo)簽加了字體的大小,可以看到返回的內(nèi)容中有了 style 屬性。

雖然 PyQuery 有修改 HTML 內(nèi)容的方法,但是我們一般不會(huì)用到,因?yàn)槲覀円话闶墙馕?HTML 內(nèi)容,而不是去修改它,大家了解一下即可。

偽類選擇器

偽類(Pseudo-classes)是指在 HTML 中,同一個(gè)標(biāo)簽,根據(jù)其不同的狀態(tài),有不同的顯示樣式。詳細(xì)的用法可以參考: https://www.runoob.com/css/css-pseudo-classes.html ,里面有詳細(xì)的介紹。

我們主要應(yīng)用偽類選擇器來解析 HTML,獲取我們所需的數(shù)據(jù)。例如:

pseudo_doc = pq(html)
print(pseudo_doc('li:nth-child(2)'))
#打印第一個(gè)li標(biāo)簽
print(pseudo_doc('li:first-child'))
#打印最后一個(gè)標(biāo)簽
print(pseudo_doc('li:last-child'))

#返回
<li class="li2">紅旗</li>
            
<li class="li1">五星</li>
            
<li class="li3">迎風(fēng)飄揚(yáng)</li>

我們也可以用 contains 方法來篩選內(nèi)容,例如:

html = """
<html>
    <head>
        我愛我的祖國
        <title>China</title>
    </head>
    <body>
        <ul id="container">
            <li class="li1">五星啊</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>
        </ul>
    </body>
</html>
"""

pseudo_doc = pq(html)

#找到含有Python的li標(biāo)簽
print(pseudo_doc("li:contains('五星')"))

#找到含有好的li標(biāo)簽
print(pseudo_doc("li:contains('紅')"))

#找到含有啊的li標(biāo)簽
print(pseudo_doc("li:contains('啊')"))

#返回
<li class="li1">五星啊</li>
            
<li class="li2">紅旗</li>

<li class="li1">五星啊</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>

我們可以看到,如果查找的結(jié)果有多條記錄,那么結(jié)果會(huì)將多條記錄拼在一起。當(dāng)然,如果查找的內(nèi)容不存在,就會(huì)返回空。

查找標(biāo)簽

我們可以按照條件在 Pyquery 對(duì)象中查找符合條件的標(biāo)簽,類似于 BeautifulSoup 中的 find 方法。
例如,我要查找 id 為 container 的標(biāo)簽:

#打印id為container的標(biāo)簽
print(doc.find('#container'))

#返回
<ul id="container">
            <li class="li1">五星啊</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>
        </ul>

我要查找 id 為 container 的標(biāo)簽的子標(biāo)簽,使用 children 方法就可以實(shí)現(xiàn):

#打印id為container的標(biāo)簽的子標(biāo)簽
container = doc.find('#container')
print(container.children())

#返回
<li class="li1">五星啊</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>

查找父標(biāo)簽,我們可以用 parent 方法:

#打印id為container的標(biāo)簽的父標(biāo)簽
container = doc.find('#container')
print(container.parent())

#返回
<body>
        <ul id="container">
            <li class="li1">五星啊</li>
            <li class="li2">紅旗</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>
        </ul>
    </body>

查找兄弟標(biāo)簽,我們用 siblings 方法:

#打印class為li2的標(biāo)簽的兄弟標(biāo)簽
li2 = doc.find('.li2')
print(li2.siblings())

#返回
<li class="li1">五星啊</li>
            <li class="li3">迎風(fēng)飄揚(yáng)啊</li>

標(biāo)簽信息的提取

前面我們講的都是怎么定位到標(biāo)簽,這只是我們解析數(shù)據(jù)的第一步,接下來我們需要從標(biāo)簽中提取我們需要的信息。

如果你需要提取標(biāo)簽的屬性值,可以用 .attr() 方法,例如:

#獲取li2的class屬性值
print(doc('.li2').attr('class'))

#返回
li2

如果你細(xì)腰提取標(biāo)簽內(nèi)的文本,我們可以用 .text() 方法,例如:

#獲取li2的文本
print(doc('.li2').text())

#返回
紅旗

如果要獲取某個(gè)標(biāo)簽下面的所有文本(包含子標(biāo)簽的),怎么做?我們來看下個(gè)例子:

#獲取html標(biāo)簽下面的所有文本
print(doc('html').text())

#返回
我愛我的祖國
China
五星啊
紅旗
迎風(fēng)飄揚(yáng)啊

很簡單,我們只需要找到這個(gè)標(biāo)簽,使用 .text() 方法。

如果我們要獲取某個(gè)標(biāo)簽下面的所有文本,但是要排除某些標(biāo)簽的文本,該怎么做?我們來看下個(gè)例子:

#排除部分標(biāo)簽文本
tag = doc('html')
tag.remove('title')
print(tag.text())

#返回
我愛我的祖國
五星啊
紅旗
迎風(fēng)飄揚(yáng)啊

我們可以用 .remove() 來刪除某些標(biāo)簽,上面例子中可以看到,我們把 title 標(biāo)簽去掉了,title 標(biāo)簽對(duì)應(yīng)的內(nèi)容 China 也就去掉了。

PyQuery 處理復(fù)雜的網(wǎng)址請(qǐng)求

前面我們介紹了 PyQuery 可以獲取網(wǎng)址請(qǐng)求的 HTML 內(nèi)容,并轉(zhuǎn)化為對(duì)象。我們在請(qǐng)求 URL 時(shí),或許會(huì)遇到需要附帶一些參數(shù)的情況,這些自定義的參數(shù)在 PyQuery 請(qǐng)求時(shí)也是支持的,例如 cookies 和 headers,我們看例子:

cookies = {'Cookie':'cookie'}
headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'}

response = pq(url='https://www.baidu.com',headers=headers,cookies=cookies)
print(response)

#返回(省略)
<head>
    
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
...

總結(jié)

這篇文章給大家介紹了 PyQuery 的常見使用方法,大家如果用的熟練的話,還是可以極大地節(jié)約我們解析 HTML 網(wǎng)頁內(nèi)容的時(shí)間的。PyQuery 可以稱得上是爬蟲神器,還有一些用法由于篇幅有限,沒有進(jìn)行介紹。大家可以去官網(wǎng)詳細(xì)查看,官網(wǎng)地址: https://pythonhosted.org/pyquery/ 。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在之前寫的爬蟲入門里,PyQuery一筆帶過,這次詳細(xì)地講一下。 為什么選擇PyQuery? Python爬蟲解析...
    Python從放棄到真香閱讀 13,412評(píng)論 0 1
  • 1.pyquery庫的了解 pyquery庫是jQuery的Python實(shí)現(xiàn),能夠以jQuery的語法來操作解析 ...
    田小田txt閱讀 6,456評(píng)論 0 1
  • 早上起來出門小跑到公交車站,剛好趕上18路,連續(xù)一個(gè)月公司加班,休息日家里有客,躺在床上睡我唯一的想法?;杌璩脸恋?..
    夏沫5159閱讀 258評(píng)論 0 0
  • Web前端開發(fā)規(guī)范文檔 規(guī)范目的: 使開發(fā)流程更加規(guī)范化。 通用規(guī)范: TAB鍵用兩個(gè)空格代替(WINDOWS下T...
    蕎葉閱讀 565評(píng)論 0 1

友情鏈接更多精彩內(nèi)容