前言
Python
之所以很适合写爬虫, 其中一个原因是拥有丰富的解析器Lib
以HTML
解析为例就有XPATH
,Beautiful Soup
和PyQuery
等等
想用哪个用哪个
那么今天我们就来介绍其中PyQuery
这个解析器的用法, PyQuery
的语法和jquery
大同小异, 如果你熟悉jquery
的使用, 那么这款解析器绝对适合你
组件安装
1 | pip install pyquery |
组件引入
1 | from pyquery import PyQuery as pq |
三个小示例
假设我们有这么一个HTML
文本:
1 | <div id="wrap"> |
如果我们要获取div
标签下的所有内容(包含div标签), 那么我们可以这样:
1 | from pyquery import PyQuery as pq |
得到的结果为:
1 | <div id="wrap"> |
如果我们要获取div
标签下的所有元素(不包含div标签),, 那么我们可以使用children()
函数, 如下:
1 | from pyquery import PyQuery as pq |
那么得到的结果为:
1 | <ul class="s_from"> |
如果我们要获取ul
标签下的所有内容, 我们可以这样:
1 | from pyquery import PyQuery as pq |
那么得到的结果为:
1 | 我是测试文本 |
通过上面三个小例子示范我们大致感受了一下PyQuery
的使用, 但是依然无法深入了解, 接下来我们对其用法进行总结
使用总结
通过
id
获取html
使用#
1
pq(html)("#xxx")
通过
class
获取html
使用’.`1
pq(html)(".xxx")
通过标签名获取
html
直接使用标签1
pq(html)("div")
查找父元素使用
parent()
1
pq(html)("#xxx").parent()
获取目标位置下包裹的所有的元素
1
pq(html)("#xxx").children()
获取目标位置下包裹的所有的
html
内容1
pq(html)("#xxx").html()
获取目标位置下包裹的所有的文本内容
1
pq(html)("#xxx").text()
注意: 我们要和
html()
与children()
进行区分, 我们用一个例子来解释:如果使用
html()
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<link href="http://aaa.com">aaa</link>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("#wrap").html()
print(result)得到的结果为:
1
2
3
4我是测试文本
<link href="http://aaa.com"/><p>aaa</p>
<link href="http://bbb.com"/>bbb
<link href="http://ccc.com"/>ccc如果使用
children()
:1
2
3doc = pq(html)
result=doc(".s_from").children()
print(result)得到结果为:
1
2
3<link href="http://aaa.com"/><p>aaa</p>
<link href="http://bbb.com"/>bbb
<link href="http://ccc.com"/>ccc如果使用
text()
:1
2
3doc = pq(html)
result=doc(".s_from").text()
print(result)得到结果为:
1
2
3
4我是测试文本
aaa
bbb
ccc一目了然
查找兄弟元素使用
siblings()
1
pq(html)("#xxx").siblings()
将所有获取到的元素组成数组
items()
1
pq(html)("#xxx").items()
比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<link href="http://aaa.com">aaa</link>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("link")
print(result)那么得到的结果为:
1
2
3
4<link href="http://aaa.com"/>aaa
<link href="http://bbb.com"/>bbb
<link href="http://ccc.com"/>ccc
<link href="http://ddd.com"/>ccc如果我们想对其进行遍历获取其中某一个元素, 那么可以这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<link href="http://aaa.com">aaa</link>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("link").items()
for i in result:
print(i)获取标签属性信息使用
attr()
还是上面的例子, 如果我们要获取
link
标签中href
的值, 那么可以这样:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<link href="http://aaa.com">aaa</link>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("link").items()
for i in result:
print(i.attr('href'))
#或者
print(i.attr.href)
# 上面两种获取href的方法任选其一精确查找使用空格
啥意思呢, 我们还是用一个例子来说明:
如果我们要利用层级关系精确查找, 那么可以这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<link id="first" "href="http://aaa.com">111<p>aaa</p></link>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("#wrap .s_from #first")
print(result)层级之间使用空格进行分隔, 得到的结果为:
1
<link id="first"/>111
我们惊奇地发现, 查找到的内容有缺失,居然没有打印
<p>aaa</p>
, 如果我们将link
标签改为a
标签:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# coding:utf-8
from pyquery import PyQuery as pq
html = '''
<div id="wrap">
<ul class="s_from">
我是测试文本
<a id="first" "href="http://aaa.com">111<p>aaa</p></a>
<link href="http://bbb.com">bbb</link>
<link href="http://ccc.com">ccc</link>
</ul>
</div>
<link href="http://ddd.com">ccc</link>
</ul>
'''
doc = pq(html)
result=doc("#wrap .s_from #first")
print(result)则结果为:
1
<a id="first">111<p>aaa</p></a>
你可能会说之前写的语法有问题
link
标签怎么能又嵌套其他标签呢, 事实上, 你也难保会碰上诸如此类的情况, 毕竟前端鱼龙混杂, 当我们获取不到值的时候, 需要特殊注意一下
根据标签属性精确查找
比如 我们要查找
itemprop
属性值为keywords
的meta
标签, 可以这样写:1
2doc = pq(html)
doc('meta[itemprop="keywords"]')如果需要嵌套查找 比如查找
itemprop
属性值为author
的div
标签下的itemprop
属性值为name
的meta
标签 可以这样写:1
2doc = pq(html)
d('div[itemprop="author"]')('meta[itemprop="name"]')更多层级的嵌套也是类的写法
给元素添加
class
1
pq(html)("#xxx").addClass('active')
如果
class
已经存在, 则不重复添加移除元素的
class
1
pq(html)("#xxx").removeClass('active')
给元素添加
css
样式1
pq(html)("#xxx").css('font-size','14px')
移除某个标签
1
pq(html)("#xxx").remove('ul')
伪类选择器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26from pyquery import PyQuery as pq
html = '''
<div href="wrap">
hello nihao
<ul class="s_from">
asdasd
<link class='active1 a123' href="http://asda.com"><a>helloasdadasdad12312</a></link>
<link class='active2' href="http://asda1.com">asdadasdad12312</link>
<link class='movie1' href="http://asda2.com">asdadasdad12312</link>
</ul>
</div>
'''
doc = pq(html)
its=doc("link:first-child")
print('第一个标签:%s'%its)
its=doc("link:last-child")
print('最后一个标签:%s'%its)
its=doc("link:nth-child(2)")
print('第二个标签:%s'%its)
its=doc("link:gt(0)") #从零开始
print("获取0以后的标签:%s"%its)
its=doc("link:nth-child(2n-1)")
print("获取奇数标签:%s"%its)
its=doc("link:contains('hello')")
print("获取文本包含hello的标签:%s"%its)多选查找, 用逗号分隔
1
pq(html)("h1,h2") #表示查找h1和h2标签
过滤查找
filter
1
pq(html).filter(".fisrt") #过滤出class为.fisrt的内容
使用
find
方法查找上面我们介绍的查找都是
pq(html)("xxx")
列表形式, 除此之外我们还可以用使用调用函数的形式进行查找, 效果也是一样的:1
2
3pq(html)("#xxx")
#或者用
pq(html).find("#xxx")
最后
以上只是该库的一部分使用方法, 一边用一边掌握, 我个人还是比较喜欢使用这一套解析库, 能解决大部分的应用场景
本文为作者原创转载时请注明出处 谢谢