python爬蟲神器PyQuery的使用方法
前言
前端大大們的福音來了,PyQuery
來了,乍聽名字,你一定聯想到了 jQuery
,如果你對 jQuery
熟悉,那麼 PyQuery
來解析文件就是不二之選!包括我在內!
PyQuery
是 Python
仿照 jQuery
的嚴格實現。語法與 jQuery
幾乎完全相同,所以不用再去費心去記一些奇怪的方法了。
天下竟然有這等好事?我都等不及了!
安裝
有這等神器還不趕緊安裝了!來!
pip install pyquery
參考來源
本文內容參考官方文件,更多內容,大家可以去官方文件學習,畢竟那裡才是最原汁原味的。
目前版本 1.2.4 (2016/3/24)
簡介
pyquery allows you to make jquery queries on xml documents. The API is
as much as possible the similar to jquery. pyquery uses lxml for fast
xml and html manipulation. This is not (or at least not yet) a library
to produce or interact with javascript code. I just liked the jquery
API and I missed it in python so I told myself “Hey let’s make jquery
in python”. This is the result. It can be used for many purposes, one
idea that I might try in the future is to use it for templating with
pure http templates that you modify using pyquery. I can also be used
for web scrapping or for theming applications with Deliverance.
pyquery 可讓你用 jQuery 的語法來對 xml 進行操作。這I和 jQuery 十分類似。如果利用 lxml,pyquery 對 xml 和 html 的處理將更快。
這個庫不是(至少還不是)一個可以和 JavaScript互動的程式碼庫,它只是非常像 jQuery API 而已。
初始化
在這裡介紹四種初始化方式。
(1)直接字串
from pyquery import PyQuery as pq
doc = pq("<html></html>")
pq
引數可以直接傳入 HTM
L 程式碼,doc
現在就相當於 jQuery
$
符號了。
(2)lxml.etree
from lxml import etree
doc = pq(etree.fromstring("<html></html>"))
可以首先用 lxml
的 etree
處理一下程式碼,這樣如果你的 HTML
程式碼出現一些不完整或者疏漏,都會自動轉化為完整清晰結構的 HTML
程式碼。
(3)直接傳URL
from pyquery import PyQuery as pq
doc = pq('http://www.baidu.com')
這裡就像直接請求了一個網頁一樣,類似用 urllib2
來直接請求這個連結,得到 HTML
程式碼。
(4)傳檔案
from pyquery import PyQuery as pq
doc = pq(filename='hello.html')
可以直接傳某個路徑的檔名。
快速體驗
現在我們以本地檔案為例,傳入一個名字為 hello.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(filename='hello.html')
print doc.html()
print type(doc)
li = doc('li')
print type(li)
print li.text()
執行結果
<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>
<class 'pyquery.pyquery.PyQuery'>
<class 'pyquery.pyquery.PyQuery'>
first item second item third item fourth item fifth item
看,回憶一下 jQuery
的語法,是不是執行結果都是一樣的呢?
在這裡我們注意到了一點,PyQuery
初始化之後,返回型別是 PyQuery
,利用了選擇器篩選一次之後,返回結果的型別依然還是 PyQuery
,這簡直和 jQuery
如出一轍,不能更贊!然而想一下 BeautifulSoup
和 XPath
返回的是什麼?列表!一種不能再進行二次篩選(在這裡指依然利用 BeautifulSoup
或者 XPath
語法)的物件!
然而比比 PyQuery
,哦我簡直太愛它了!
屬性操作
你可以完全按照 jQuery
的語法來進行 PyQuery
的操作。
from pyquery import PyQuery as pq
p = pq('<p id="hello" class="hello"></p>')('p')
print p.attr("id")
print p.attr("id", "plop")
print p.attr("id", "hello")
執行結果
hello
<p id="plop" class="hello"/>
<p id="hello" class="hello"/>
再來一發
from pyquery import PyQuery as pq
p = pq('<p id="hello" class="hello"></p>')('p')
print p.addClass('beauty')
print p.removeClass('hello')
print p.css('font-size', '16px')
print p.css({'background-color': 'yellow'})
執行結果
<p id="hello" class="hello beauty"/>
<p id="hello" class="beauty"/>
<p id="hello" class="beauty" style="font-size: 16px"/>
<p id="hello" class="beauty" style="font-size: 16px; background-color: yellow"/>
依舊是那麼優雅與自信!
在這裡我們發現了,這是一連串的操作,而 p
是一直在原來的結果上變化的。
因此執行上述操作之後,p
本身也發生了變化。
DOM操作
同樣的原汁原味的 jQuery
語法
from pyquery import PyQuery as pq
p = pq('<p id="hello" class="hello"></p>')('p')
print p.append(' check out <a href="http://reddit.com/r/python"><span>reddit</span></a>')
print p.prepend('Oh yes!')
d = pq('<div class="wrap"><div id="test"><a href="http://cuiqingcai.com">Germy</a></div></div>')
p.prependTo(d('#test'))
print p
print d
d.empty()
print d
執行結果
<p id="hello" class="hello"> check out <a href="http://reddit.com/r/python"><span>reddit</span></a></p>
<p id="hello" class="hello">Oh yes! check out <a href="http://reddit.com/r/python"><span>reddit</span></a></p>
<p id="hello" class="hello">Oh yes! check out <a href="http://reddit.com/r/python"><span>reddit</span></a></p>
<div class="wrap"><div id="test"><p id="hello" class="hello">Oh yes! check out <a href="http://reddit.com/r/python"><span>reddit</span></a></p><a href="http://cuiqingcai.com">Germy</a></div></div>
<div class="wrap"/>
這不需要多解釋了吧。
DOM
操作也是與 jQuery
如出一轍。
遍歷
遍歷用到 items
方法返回物件列表,或者用 lambda
from pyquery import PyQuery as pq
doc = pq(filename='hello.html')
lis = doc('li')
for li in lis.items():
print li.html()
print lis.each(lambda e: e)
執行結果
first item
<a href="link2.html">second item</a>
<a href="link3.html"><span class="bold">third item</span></a>
<a href="link4.html">fourth item</a>
<a href="link5.html">fifth item</a>
<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>
不過最常用的還是 items 方法
網頁請求
PyQuery 本身還有網頁請求功能,而且會把請求下來的網頁程式碼轉為 PyQuery 物件。
from pyquery import PyQuery as pq
print pq('http://cuiqingcai.com/', headers={'user-agent': 'pyquery'})
print pq('http://httpbin.org/post', {'foo': 'bar'}, method='post', verify=True)
感受一下,GET
,POST
,樣樣通。
Ajax
PyQuery
同樣支援 Ajax
操作,帶有 get
和 post
方法,不過不常用,一般我們不會用 PyQuery
來做網路請求,僅僅是用來解析。