1. 程式人生 > >【Python3 爬蟲學習筆記】解析庫的使用 8 —— 使用pyquery 1

【Python3 爬蟲學習筆記】解析庫的使用 8 —— 使用pyquery 1

先看示例:

html = '''
<div>
<ul>
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq doc = pq(html) print(doc('li'))

執行結果如下:

<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item<
/span></a></li> <li class="item-1 active"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li>

這裡首先引入PyQuery這個物件,取別名為pq。然後聲明瞭一個長HTML字串,並將其當作引數傳遞給PyQuery類,這樣就成功完成了初始化。接下來,將初始化的物件傳入CSS選擇器。在這個例項中,我們傳入li節點,這樣就可以選擇所有的li節點。

URL初始化

初始化的引數不僅可以以字串的形式傳遞,還可以傳入網頁的URL,此時只需要指定引數為url即可:

from pyquery import PyQuery as pq
doc = pq(url='https://cuiqingcai.com')
print(doc('title'))

執行結果如下:

<title>靜覓丨崔慶才的個人部落格</title>&#13;

它與下面的功能是相同的:

from pyquery import PyQuery as pq
import requests
doc = pq(requests.get('https://cuiqingcai.com').text)
print(doc('title'))

這樣的話,PyQuery物件會首先請求這個URL,然後用得到的HTML內容完成初始化,這其實就相當於用網頁的原始碼以字串的形式傳遞給PyQuery類來初始化。

檔案初始化

當然,除了傳遞URL,還可以傳遞本地的檔名,此時將引數指定為filename即可:

from pyquery import PyQuery as pq
doc = pq(filename='demo.html')
print(doc('li'))

當然,這裡需要有一個本地HTML檔案demo.html,其內容是待解析的HTML字串。這樣它會首先讀取本地的檔案內容,然後用檔案內容以字串的形式傳遞給PyQuery類來初始化。

基本CSS選擇器

html = '''
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))

執行結果如下:

<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>

<class 'pyquery.pyquery.PyQuery'>

這裡我們初始化PyQuery物件之後,傳入了一個CSS選擇器#container .list li,它的意思是先選取id為container的節點,然後再選取其內部的class為list的節點內部的所有li節點。然後,列印輸出。可以看到,我們成功獲取到了符合條件的節點。
最後,將它的型別列印輸出。可以看到,它的型別依然是PyQuery型別。

查詢節點

子節點

查詢子節點時,需要用到find()方法,此時傳入的引數是CSS選擇器。這裡還是以前面的HTML為例。

from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
print(type(items))
print(items)
lis = items.find('li')
print(type(lis))
print(lis)

執行結果如下:

<class 'pyquery.pyquery.PyQuery'>
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>

<class 'pyquery.pyquery.PyQuery'>
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>

首先,我們選取class為list的節點,然後呼叫了find()方法,傳入CSS選擇器,選取其內部的li節點,最後列印輸出。可以發現,find()方法將會符合條件的所有節點選擇出來,結果的型別是PyQuery型別。
其實find()的查詢範圍是節點的所有子孫節點,而如果我們只想查詢子節點,那麼可以用children()方法:

lis = items.children()
print(type(lis))
print(lis)

如果要篩選所有子節點中符合條件的節點,比如想篩選出子節點中class為active的節點,可以向children()方法傳入CSS選擇器.active:

lis = items.children('.active')
print(lis)

執行結果如下:

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>

可以看到,輸出結果已經做了篩選,留下了class為active的節點。

父節點

我們可以用parent()方法來獲取某個節點的父節點,示例如下:

html = '''
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
container = items.parent()
print(type(container))
print(container)

執行結果如下:

<class 'pyquery.pyquery.PyQuery'>
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>

這裡我們首先用.list選取class為list的節點,然後呼叫parent()方法得到其父節點,其型別依然是PyQuery型別。
這裡的父節點是該節點的直接父節點,如果要獲取祖先節點,可以使用parents()方法:

from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
parents = items.parents()
print(type(parents))
print(parents)

執行結果如下:

<class 'pyquery.pyquery.PyQuery'>
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div><div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>

可以看到,輸出結果有兩個:一個是class為wrap的節點,一個是id為container的節點。也就是時候,parents()方法會返回所有的祖先節點。
如果想要篩選某個祖先節點的話,可以向parents()方法傳入CSS選擇器,這樣就會返回祖先節點中符合CSS選擇器的節點:

parent = items.parents('.wrap')
print(parent)

執行結果如下:

<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>

可以看到,輸出結果少了一個節點,只保留了class為wrap的節點。

兄弟節點

如果要獲取兄弟節點,可以使用siblings()方法,示例如下:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings())

這裡首先選擇class為list的節點內部class為item-0和active的及誒按,也就是第三個li節點。那麼,很明顯,它的兄弟節點有4個。
執行結果如下:

<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0">first item</li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>

可以看到,正是我們所說的四個兄弟節點。
如果要篩選某個兄弟節點,我們依然可以向siblings方法傳入CSS選擇器,這樣就會從所有兄弟節點中挑選出符合條件的節點了:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))

這裡,我們篩選了class為active的節點,通過剛才的結果可以觀察到,class為active的兄弟節點只有第四個li節點,所以執行結果如下:

<li class="item-1 active"><a href="link4.html">fourth item</a></li>