爬虫--pyquery解析器的使用
pyquery的一些操作方法,可类比jQuery
一、快速使用示例:
from pyquery import PyQuery as pq text = ''' <p name='p1'>第一个p标签<span>第一个span标签</span></p> <p>第二个p标签<span>第二个span标签</span></p> ''' html = pq(text) print(html('p').text()) # 获取标签内纯文本,多个标签文本间通过空格分开,返回'第一个p标签第一span标签 第二个p标签第二span标签' print(html('p:gt(0)').text()) # 获取第二个及之后的p标签内的文本,返回'第二个p标签第二个span标签' # 通过遍历依次获取 for p in html('p').items(): print(p.text()) # 获取文本,分别返回:'第一个p标签第一span标签'和'第二个p标签第二个span标签' print(p.attr('name')) # 获取属性,没有则返回None,分别返回:'p1'和None
二、安装
pip3 install pyquery
三、导入
from pyquery import PyQuery as pq
四、实例化PyQuery对象
-
传入字符串
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) print(html('span')) #传入css选择器参数 print(type(html)) print(type(html('span')))
-
运行结果:
<span class="bold">third item</span> <class 'pyquery.pyquery.PyQuery'> <class 'pyquery.pyquery.PyQuery'>
-
-
传入url
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq html = pq(url='https://www.cnblogs.com/eliwang/') print(html('title')) #传入css选择器参数
-
运行结果:
<title>eliwang - 博客园</title>
-
-
传入文件名
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq html = pq(filename='test.html') print(html('#test')) #传入css选择器参数
-
运行结果:
<p id="test">this is a test item</p>
-
五、查找节点
-
传入css选择器参数
-
find()
- 需要传入css选择器参数
- 查找范围是所有子孙节点,并返回所有符合的节点
-
children()
- 查找所有子节点
- 传入css选择器参数,可以筛选子节点
-
parent()
- 获取某个节点的父节点
-
parents()
- 返回某个节点的所有祖先节点
- 传入css选择器参数,可以筛选特定的祖先节点
-
siblings()
- 返回所有兄弟节点
- 传入css选择器参数,筛选特定兄弟节点
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) print(html('p')) #传入css选择器 print(html.find('span')) print(html('.item-inactive').children()) #查找所有子节点 print(html('.item-inactive').children('p')) #筛选子节点 print(html('p').parent()) #父节点 print(html('.item-inactive').parents()) #祖先节点 print(html('p').siblings()) #兄弟节点
-
运行结果
<p>这是p标签里面的内容</p> <span class="bold">third item</span> <p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a> <p>这是p标签里面的内容</p> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> <a href="link3.html"><span class="bold">third item</span></a>
六、遍历
- pyquery的选择结果可能是单个节点,也可能是多个节点,但都是pyquery类型,并不会返回列表
-
单个节点
- 可以直接打印输出
- 也可以通过str方法转换成字符串
-
多个节点
- 需要调用items()方法,使其变成生成器,然后再进行遍历
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) print(html('span')) #打印单个节点 lis = html('li') for li in lis.items(): #遍历所有li节点 print(li)
-
运行结果:
<span class="bold">third item</span> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li>
-
七、获取信息
-
获取属性
-
attr('属性名')
- 有则返回数值值,没有则返回None
- 当选中多个节点时,调用attr方法获取属性,只会得到第一个节点的属性
- 如果想要获取所有节点的属性,就需要通过遍历来依次获取每个节点的属性
-
或对象.attr.属性名
- 同上
-
-
获取文本
-
text()
- 会忽略节点内部的html,只会返回纯文字的内容
- 如果选中的是多个节点,则会返回所有节点内部文字构成的字符串,中间用空格分割
-
html()
- 返回内部的html文本
- 如果选中的是多个节点,则只会返回第一个节点内部的html文本内容
- 可通过遍历获取每个节点内部的html
-
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) print(html('a').attr('href')) #多个节点,只返回第一个a节点的href属性值 print([item.attr.href for item in html('a').items()]) #获取所有a节点href属性值 print(html('.item-inactive').text()) #忽略节点内部html,返回纯文本 print(html('a').text()) #多个节点,返回所有节点内部文本构成的字符串,以空格连接 print(html('li').html()) #多个节点,只返回第一个节点内部的html print([item.html() for item in html('li').items()]) #获取所有li节点内部的html
-
运行结果:
link1.html ['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html'] 这是p标签里面的内容 third item first item second item third item fourth item fifth item <a href="link1.html">first item</a> ['<a href="link1.html">first item</a>', '<a href="link2.html">second item</a>', '<p>这是p标签里面的内容</p><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>']
八、节点操作
pyquery提供了一系列方法对节点进行动态修改,常用的如下:
-
addClass()
- 添加样式类
-
removeClass()
- 删除样式类
-
attr()
- 传入两个参数,修改或添加属性
-
text()
- 传入参数,则会给节点赋值文本
-
html()
- 传入参数,则会给节点内部重新赋值html文本
-
append()
- 单个节点,则在该节点内尾部追加内容
- 多个节点,则每个节点都会从尾部追加该内容
-
prepend()
- 单个节点,则在该节点内首部添加该内容
- 多个节点,则每个节点首部都会添加该内容
-
empty()
- 清空节点
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><p>这是p标签里面的内容</p><a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) p = html('p') p.addClass('ppp') # 添加样式类 p.addClass('testP') print(p) p.removeClass('ppp') # 删除样式类 print(p) p.attr('name','p') #添加name属性 p.text('p标签中的内容已修改') #修改文本内容 print(p) p.html('<span>pppppp</span>') #重新赋值内部html print(p) p.prepend('<b>在首部添加</b>') #节点内首部添加节点 print(p) p.append('<b>在尾部添加</b>') #节点内尾部添加节点 print(p) p.empty() #清空节点内容 print(p)
-
运行结果:
<p class="ppp testP">这是p标签里面的内容</p> <p class="testP">这是p标签里面的内容</p> <p class="testP" name="p">p标签中的内容已修改</p> <p class="testP" name="p"><span>pppppp</span></p> <p class="testP" name="p"><b>在首部添加</b><span>pppppp</span></p> <p class="testP" name="p"><b>在首部添加</b><span>pppppp</span><b>在尾部添加</b></p> <p class="testP" name="p"/>
九、丰富的css选择器
比如:
-
E:first-child 第一个节点
-
E:last-child 最后一个节点
-
E:nth-child(n) 第n个节点
-
E:nth-last-child(n) 倒数第n个节点
-
E:nth-child(2n) 偶数节点
-
E:nth-child(2n+1) 奇数节点
-
E:gt(n) 第n+1个之后的节点,注意这里的n指的是索引
-
E:contains(xx) 包含某文本内容的节点
-
示例:
# coding:utf-8 from pyquery import PyQuery as pq text = ''' <div> <ul> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive">这是li里面的内容<a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> </ul> </div> ''' html = pq(text) print(html('li:first-child')) print(html('li:nth-child(3)')) print(html('li:nth-child(2n)')) print(html('li:nth-child(2n+1)')) print(html('li:gt(1)')) print(html('li:contains(fourth)'))
-
运行结果
<li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-inactive">这是li里面的内容<a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0" id="first"><a href="link1.html">first item</a></li> <li class="item-inactive">这是li里面的内容<a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> <li class="item-inactive">这是li里面的内容<a href="link3.html"><span class="bold">third item</span></a></li> <li class="item-1"><a href="link4.html">fourth item</a></li> <li class="item-0"><a href="link5.html">fifth item</a></li> <li class="item-1"><a href="link4.html">fourth item</a></li>