Python爬蟲利器之PyQuery的用法

前言

你是否覺得 XPath 的用法多少有點晦澀難記呢?

你是否覺得 BeautifulSoup 的語法多少有些慳吝難懂呢?

你是否甚至還在苦苦研究正則表達式卻因為少些了一個點而抓狂呢?

你是否已經有了一些前端基礎了解選擇器卻與另外一些奇怪的選擇器語法混淆了呢?

嗯,那麼,前端大大們的福音來了,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 pqdoc = pq("<html></html>")

pq 參數可以直接傳入 HTML 代碼,doc 現在就相當於 jQuery 裡面的 $ 符號了。

(2)lxml.etree

from lxml import etreedoc = pq(etree.fromstring("<html></html>"))

可以首先用 lxml 的 etree 處理一下代碼,這樣如果你的 HTML 代碼出現一些不完整或者疏漏,都會自動轉化為完整清晰結構的 HTML代碼。

(3)直接傳URL

from pyquery import PyQuery as pqdoc = pq("http://www.baidu.com")

這裡就像直接請求了一個網頁一樣,類似用 urllib2 來直接請求這個鏈接,得到 HTML 代碼。

(4)傳文件

from pyquery import PyQuery as pqdoc = pq(filename="hello.html")

可以直接傳某個路徑的文件名。

快速體驗

現在我們以本地文件為例,傳入一個名字為 hello.html 的文件,文件內容為

<div><ul><li class="item-0">first item</li><li class="item-1"><a href="https://ask.hellobi.com/link2.html">second item</a></li><li class="item-0 active"><a href="https://ask.hellobi.com/link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li><li class="item-0"><a href="https://ask.hellobi.com/link5.html">fifth item</a></li></ul></div>

編寫如下程序

from pyquery import PyQuery as pqdoc = 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="https://ask.hellobi.com/link2.html">second item</a></li><li class="item-0 active"><a href="https://ask.hellobi.com/link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li><li class="item-0"><a href="https://ask.hellobi.com/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 pqp = 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 pqp = 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 是一直在原來的結果上變化的。

因此執行上述操作之後,p 本身也發生了變化。

DOM操作

同樣的原汁原味的 jQuery 語法

from pyquery import PyQuery as pqp = 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 pprint dd.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 pqdoc = 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="https://ask.hellobi.com/link2.html">second item</a><a href="https://ask.hellobi.com/link3.html"><span class="bold">third item</span></a><a href="https://ask.hellobi.com/link4.html">fourth item</a><a href="https://ask.hellobi.com/link5.html">fifth item</a><li class="item-0">first item</li> <li class="item-1"><a href="https://ask.hellobi.com/link2.html">second item</a></li> <li class="item-0 active"><a href="https://ask.hellobi.com/link3.html"><span class="bold">third item</span></a></li> <li class="item-1 active"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li> <li class="item-0"><a href="https://ask.hellobi.com/link5.html">fifth item</a></li>

不過最常用的還是 items 方法

網頁請求

PyQuery 本身還有網頁請求功能,而且會把請求下來的網頁代碼轉為 PyQuery 對象。

from pyquery import PyQuery as pqprint 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 來做網路請求,僅僅是用來解析。

PyQueryAjax

API

最後少不了的,API大放送。

API

原汁原味最全的API,都在裡面了!如果你對 jQuery 語法不熟,強烈建議先學習下 jQuery,再回來看 PyQuery,你會感到異常親切!

結語

用完了 PyQuery,我已經深深愛上了他!

你呢?

作者:崔慶才

出處:崔慶才的個人博客

最近很多人私信問我問題,平常知乎評論看到不多,如果沒有及時回復,大家也可以加小編微信:tszhihu,進知乎大數據分析挖掘交流群,可以跟各位老師互相交流。謝謝。


推薦閱讀:

Python 家族有多龐大
Python數據分析及可視化實例之CentOS7.2+Python3x+Flask部署標準化配置流程
Flask 實現小說網站 (二)
Python實現3D建模工具
Flask模板引擎:Jinja2語法介紹

TAG:Python | Python开发 | 爬虫 |