Python网络爬虫案例实战:解析网页:PyQuery 解析库
前面介绍了BeautifulSoup 的用法,它是一个非常强大的网页解析库,你是否觉得它的一些方法用起来有点不适用?有没有觉得它的CSS选择器的功能没有那么强大?
下面来介绍一个更适合的解析库—PyQuery。PyQuery库是jQuery的Python实现,能够以jQuery的语法来操作解析HTML 文档,易用性和解析速度都很好,使用起来还是可以的,有些地方用起来很方便简洁。
5.4.1使用PyQuery
如果之前没有安装PyQuery,可在命令窗口中直接使用pip install PyQuery进行安装。
1.初始化
像 BeautifulSoup 一样,初始化PyQuery的时候,也需要传人HTML 文本来初始化一个PyQuery对象,它的初始化方式有多种,比如直接传入字符串、传入URL、传人文件名,等等。下面详细介绍。
1)字符串初始化
首先,通过一个实例来感受一下:
from pyquery import PyQuery as pq
# 定义 HTML 字符串
html = """
<html lang="en">
<head>
简单好用的
<title>PyQuery</title>
</head>
<body>
<ul id="container">
<li class="object-1">Python</li>
<li class="object-2">爬虫</li>
<li class="object-3">好</li>
</ul>
</body>
</html>
"""
# 初始化为 PyQuery 对象
doc = pq(html)
# 打印对象的类型
print(type(doc))
# 打印 PyQuery 对象的内容
print(doc)
运行程序,输出如下:
<class 'pyquery.pyquery.PyQuery'>
<html lang="en">
<head>
简单好用的
<title>PyQuery</title>
</head>
<body>
<ul id="container">
<li class="object-1">Python</li>
<li class="object-2">爬虫</li>
<li class="object-3">好</li>
</ul>
</body>
</html>
这里首先引入PyQuery这个对象,取别名为pq,然后声明了一个长HTML字符串,并将其当作参数传递给PyQuery类,这样就成功完成了初始化。接下来,将初始化的对象传入 CSS选择器。在这个实例中,传入li节点,这样就可以选择所有的1i节点。
2)对网址响应进行初始化
初始化的参数不仅可以以字符串的形式传递,还可以传入网页的URL,此时只需要指定参数为url 即可:
from pyquery import PyQuery as pq
#初始化为 PyQuery对象
response = pq(url ='https://www.baidu.com')
print(type(response))
print(response)
运行程序,输出如下:
<class 'pyquery.pyquery.PyQuery'>
<html> <head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><meta content="always" name="referrer"/><link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css"/><title>ç¾åº¦ä¸ä¸ï¼ä½ å°±ç¥é</title></head> <body link="#0000cc"> <div id="wrapper">
2.CSS 选择器
首先,用一个实例来感受PyQuery的 CSS选择器的用法:
# 定义 HTML 字符串
html = """
<html lang="en">
<head>
简单好用的
<title>PyQuery</title>
</head>
<body>
<ul id="container">
<li class="object-1">Python</li>
<li class="object-2">爬虫</li>
<li class="object-3">好</li>
</ul>
</body>
</html>
"""
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container'))
print(type(doc('#container')))
运行程序,输出如下:
<ul id="container">
<li class="object-1">Python</li>
<li class="object-2">爬虫</li>
<li class="object-3">好</li>
</ul>
<class 'pyquery.pyquery.PyQuery'>
这里初始化 PyQuery对象之后,传入了一个CSS选择器井container.list li,它的意思为选取id为 container的节点,然后再选取其内部的class为list的节点内部的所有li节点。然后,打印输出,可以看到,成功获取了符合条件的节点。最后,将它的类型打印输出,可以看到,它的类型依然是PyQuery类型。
再例如,打印 class为object-l的标签:
print(doc('.object-1'))
输出如下:
<li class="object-1">Python</li>
打印标签名为body的标签:
print(doc('body'))
输出如下:
<body>
<ul id="container">
<li class="object-1">Python</li>
<li class="object-2">爬虫</li>
<li class="object-3">好</li>
</ul>
</body>
3.查找节点
下面介绍一些常用的查询函数。
1)子节点
查找子节点时,需要用到find()方法,此时传入的参数是CSS选择器。
from pyquery import PyQuery as pq
# 定义 HTML 字符串
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>
"""
# 初始化为 PyQuery 对象
doc = pq(html)
# 查询所有 <li> 元素
items = doc('li')
print(type(items)) # 输出 items 的类型
print(items) # 输出 items
# 查找所有 <li> 元素的子元素
lis = items.find('li')
print(type(lis)) # 输出 lis 的类型
print(lis) # 输出 lis
运行程序,输出如下:
<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 'pyquery.pyquery.PyQuery'>
首先,选取class为list的节点,然后调用了 find()方法,传入 CSS选择器,选取其内部的1i节点,最后打印输出。可以发现,find()方法会将符合条件的所有节点选择出来,结果的类型是PyQuery类型。
其实 find()的查找范围是节点的所有子孙节点,而如果只想查找子节点,那么可以用children()方法:
lis = items.children()
print(type(lis))
print(lis)
输出如下:
<class 'pyquery.pyquery.PyQuery'>
<a href="link2.html">second item</a><a href