1. 程式人生 > >python爬蟲pyquery庫詳解

python爬蟲pyquery庫詳解

PyQuery庫也是一個非常強大又靈活的網頁解析庫,如果你有前端開發經驗的,都應該接觸過jQuery,那麼PyQuery就是你非常絕佳的選擇,PyQuery 是 Python 仿照 jQuery 的嚴格實現。語法與 jQuery 幾乎完全相同,所以不用再去費心去記一些奇怪的方法了。

官網地址:http://pyquery.readthedocs.io/en/latest/
jQuery參考文件: http://jquery.cuishifeng.cn/

初始化

初始化的時候一般有三種傳入方式:傳入字串,傳入url,傳入檔案

字串初始化

複製程式碼
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)
print(type(doc))
print(doc('li'))
複製程式碼

結果如下:

由於PyQuery寫起來比較麻煩,所以我們匯入的時候都會新增別名:
from pyquery import PyQuery as pq

這裡我們可以知道上述程式碼中的doc其實就是一個pyquery物件,我們可以通過doc可以進行元素的選擇,其實這裡就是一個css選擇器,所以CSS選擇器的規則都可以用,直接doc(標籤名)就可以獲取所有的該標籤的內容,如果想要獲取class 則doc('.class_name'),如果是id則doc('#id_name')....

URL初始化

from pyquery import PyQuery as pq

doc = pq(url="http://www.baidu.com",encoding='utf-8')
print(doc('head'))

檔案初始化

我們在pq()這裡可以傳入url引數也可以傳入檔案引數,當然這裡的檔案通常是一個html檔案,例如:pq(filename='index.html')

基本的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'))
複製程式碼

這裡我們需要注意的一個地方是doc('#container .list li'),這裡的三者之間的並不是必須要挨著,只要是層級關係就可以,下面是常用的CSS選擇器方法:

查詢元素

子元素
children,find
程式碼例子:

複製程式碼
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)
items = doc('.list')
print(type(items))
print(items)
lis = items.find('li')
print(type(lis))
print(lis)
複製程式碼

執行結果如下

從結果裡我們也可以看出通過pyquery找到結果其實還是一個pyquery物件,可以繼續查詢,上述中的程式碼中的items.find('li') 則表示查詢ul裡的所有的li標籤
當然這裡通過children可以實現同樣的效果,並且通過.children方法得到的結果也是一個pyquery物件

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

同時在children裡也可以用CSS選擇器

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

父元素
parent,parents方法

通過.parent就可以找到父元素的內容,例子如下:

複製程式碼
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)
items = doc('.list')
container = items.parent()
print(type(container))
print(container)
複製程式碼

通過.parents就可以找到祖先節點的內容,例子如下:

複製程式碼
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')
parents = items.parents()
print(type(parents))
print(parents)
複製程式碼

結果如下:從結果我們可以看出返回了兩部分內容,一個是的父節點的資訊,一個是父節點的父節點的資訊即祖先節點的資訊

同樣我們通過.parents查詢的時候也可以新增css選擇器來進行內容的篩選

兄弟元素
siblings

複製程式碼
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)
li = doc('.list .item-0.active')
print(li.siblings())
複製程式碼

程式碼中doc('.list .item-0.active') 中的.tem-0和.active是緊挨著的,所以表示是並的關係,這樣滿足條件的就剩下一個了:thired item的那個標籤了
這樣在通過.siblings就可以獲取所有的兄弟標籤,當然這裡是不包括自己的
同樣的在.siblings()裡也是可以通過CSS選擇器進行篩選

遍歷

單個元素

複製程式碼
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)
li = doc('.item-0.active')
print(li)

lis = doc('li').items()
print(type(lis))
for li in lis:
    print(type(li))
    print(li)
複製程式碼

執行結果如下:從結果中我們可以看出通過items()可以得到一個生成器,並且我們通過for迴圈得到的每個元素依然是一個pyquery物件。

獲取資訊

獲取屬性
pyquery物件.attr(屬性名)
pyquery物件.attr.屬性名

複製程式碼
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)
a = doc('.item-0.active a')
print(a)
print(a.attr('href'))
print(a.attr.href)
複製程式碼

所以這裡我們也可以知道獲得屬性值的時候可以直接a.attr(屬性名)或者a.attr.屬性名

獲取文字
在很多時候我們是需要獲取被html標籤包含的文字資訊,通過.text()就可以獲取文字資訊

複製程式碼
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)
a = doc('.item-0.active a')
print(a)
print(a.text())
複製程式碼

結果如下:

獲取html
我們通過.html()的方式可以獲取當前標籤所包含的html資訊,例子如下:

複製程式碼
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)
li = doc('.item-0.active')
print(li)
print(li.html())
複製程式碼

結果如下:

DOM操作

addClass、removeClass
熟悉前端操作的話,通過這兩個操作可以新增和刪除屬性

複製程式碼
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)
li = doc('.item-0.active')
print(li)
li.removeClass('active')
print(li)
li.addClass('active')
print(li)
複製程式碼

attr,css
同樣的我們可以通過attr給標籤新增和修改屬性,
如果之前沒有該屬性則是新增,如果有則是修改
我們也可以通過css新增一些css屬性,這個時候,標籤的屬性裡會多一個style屬性

複製程式碼
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)
li = doc('.item-0.active')
print(li)
li.attr('name', 'link')
print(li)
li.css('font-size', '14px')
print(li)
複製程式碼

結果如下:

 

remove
有時候我們獲取文字資訊的時候可能並列的會有一些其他標籤干擾,這個時候通過remove就可以將無用的或者干擾的標籤直接刪除,從而方便操作

複製程式碼
html = '''
<div class="wrap">
    Hello, World
    <p>This is a paragraph.</p>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
print(wrap.text())
wrap.find('p').remove()
print(wrap.text())
複製程式碼

結果如下:

pyquery中DOM的其他api操作參考:
http://pyquery.readthedocs.io/en/latest/api.html

部落格參考:https://www.cnblogs.com/zhaof/p/6935473.html