Python公开课 - 页面解析之pyquery

前言

pyquery

pyquery是一个非常强大又灵活的网页解析库,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法,那么pyquery就是不错的选择。它允许您对xml文档进行jquery查询,API与与jquery类似,使用lxml进行快速xml和html操作。

安装

可以直接通过pip进行安装

pip3 install pyquery

基本使用

字符串初始化

from pyquery import PyQuery as pq
from lxml import etree
import urllib

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="links.html">fifth item</a></li>
    </ul>
  </div>
"""

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="links.html">fifth item</a></li>

这里首先引人PyQuery这个对象,取别名为pq。

然后声明了一个示例html内容作为参数传递给PyQuery 类,这样就成功完成了初始化。

我们对这个实例传入li节点,这样就可以选择所有的li节点。

URL来进行初始化

from pyquery import PyQuery as pq
doc = pq(url="http://www.xtuz.net")
print(doc('title'))

结果输出:

输出:
<title>兔子先生-技术栈</title>

PyQuery 对象会自动请求这个URL, 然后将想赢的 HTML 内容完成初始化。

文件初始化

from pyquery import PyQuery as pq 
doc = pq(filename='test.html')

首先读取本地test.html的文件内容,然后用文件内容以字符串的形式传递给PyQuery类来初始化。

CSS选择器

我们将上面的例子做一点修改

from pyquery import PyQuery as pq
from lxml import etree
import urllib

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="links.html">fifth item</a></li>
    </ul>
  </div>
"""

doc = pq(html)
#print(doc('li'))
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="links.html">fifth item</a></li>

<class 'pyquery.pyquery.PyQuery'>

代码解释

在完成PyQuery对象初始化后,传入了一个CSS选择器#container .list li,含义就是先寻找id为container的元素,然后在起子类寻找class为list的元素,最后将其子类的所有li节点找到。

规则说明

key value 说明
.class .list 选择class="list"的所有元素
id container 选择 id="container"元素
element p 选择所有p元素
element, element div, p 选择所有div元素和p元素
element, element div p 选择div元素内所有p元素
[attribute] target 选择带有target属性的所有元素
[attribute=target] [href="http://xtuz.net"] 选择链接到http://www.xtuz.net的元素


查找

find()查找

find()的查找范围是节点的所有子孙节点

print(doc.find('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="links.html">fifth item</a></li>

数据抽取

提取属性

调用attr()方法来获取属性:

print(doc.find('.item-0.active').attr('class'))

结果输出:

输出:
item-0 active

提取文本

调用text()方法来获取文本

print(doc.find('.item-0.active').text())

结果输出:

输出:
third item

text()方法会忽略节点内部html标记,只返回纯文字内容。 但如果想要获取该节点原始内容,就要用html()

print(doc.find('.item-0.active').html())

结果输出:

输出:
<a href="link3.html"><span class="bold">third item</span></a>

小结

pyquery还可以支持修改页面,通过addClass()removeClass()对节点的样式进行编辑。也可以通过attr(), text(), html()方法来对节点的属性和内容进行修改。

考虑到是从爬虫的角度来阐述,原则来说,不会对页面内容进行修改,所以本章不做更多介绍。

小技巧

怎么用pyquery取到第二个p节点。

from pyquery import PyQuery
content = PyQuery("str1")
two_class = content(".class:nth-child(2)") #选取的百是第二度个知class对象道

相关阅读