python爬虫学习记录解析库的使用——pyquery
Posted 玛卡巴卡巴巴亚卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python爬虫学习记录解析库的使用——pyquery相关的知识,希望对你有一定的参考价值。
一、简介
CSS选择器,jQuery
二、初始化
1、字符串初始化
from pyquery import PyQuery as pq
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>
"""
doc = pq(html)
print(doc('li'))
先引入pyQuery,再取别名为pq,声明html字符春,当做参数传给PyQuery,完成初始化,将初始化对象传给css选择器,获取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="link5.html">fifth item</a></li>
2、URL初始化
PyQuery指定参数是url即可。PyQuery会首先请求这个url,用得到的html内容完成初始化,相当于用网页源代码以字符串形式传递给PyQuery类来初始化。与用request.get('http://www.xxxxx.com').text传入PyQuery对象一样。
from pyquery import PyQuery as pq
doc = pq(url='http://cuiqingcai.com')
print(doc('title'))
<title> 静觅丨崔庆才的个人博客 </title>
3、文件初始化
可以传递本地文件,将参数指定为filename
from pyquery import PyQuery as pq
doc = pq(filename='demo.html')
print(doc('li'))
二、基本CSS选择器
初始化pyquery对象,传入css选择器#container .list li。可以获取所有符合条件的节点。
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
print(doc('#container .list li'))
<li class="item-0">第一项</li>
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项 span></span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
三、查找节点
使用find()方法,传入参数是css选择器。find查找范围是所有子孙节点。
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
items = doc('.list')
print(type(items))
print(items)
lis = items.find('li')
print(type(lis))
print(lis)
<class 'pyquery.pyquery.PyQuery'>
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项 span></span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
</ul><class 'pyquery.pyquery.PyQuery'>
<li class="item-0">第一项</li>
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项 span></span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
如果只查找子节点,可以使用children()方法
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
items = doc('.list')
lis = items.children()
print(lis)
<li class="item-0">第一项</li>
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项 span></span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
要选择符合条件的节点,如向选出class节点中的active节点,可以向children方法中传入css选择器.active
lis = items.children('.active')
print(lis)
此外,父节点的获取使用parent()祖先节点使用parents()。这两个方法都是返回所有符合条件的父节点和祖先节点,这里可以使用css选择器,选中符合选择器的节点。
获取兄弟节点使用siblings()方法。
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
li = doc('.list .item-0.active')#选择class为list的节点内部class为item-0.active的节点
print(li.siblings())
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0">第一项</li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
要筛选某个兄弟节点,我们依然可以向 siblings 方法传入 CSS 选择器,这样就会从所有兄弟节点中挑选出符合条件的节点。
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))
四、遍历
pyquery选择结果可能是多个节点,也可能是单个几点,类型都是pyquery类型,没有bs那样的列表。
对当节点来说,可以直接打印输出,也可以直接转换成字符串。
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(str(li))
对多个节点的获取需要遍历获取。
这把每个li节点遍历,需要调用items()方法
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">第一项</li>
<li class="item-1"><a href ="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项</ span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0" ><a href="link5.html">第五项</a></li>
</ul>
</div>
'''
doc = pq(html)
lis = doc('li').items()#调用item后会得到一个生成器,遍历后就可逐个得到li节点对象
print(type(lis))
for li in lis:
print(li)
<class 'generator'>
<li class="item-0">第一项</li>
<li class="item-1"><a href="link2.html">第二项</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">第三项 span></span></a></li>
<li class="item-1 active"><a href="link4.html">第四项</a></li>
<li class="item-0"><a href="link5.html">第五项</a></li>
五、获取信息
1、获取属性
获取某个pyquery类型节点后,可以调用attr()方法获取属性
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
doc = pq(html)
a = doc('.item-0.active a')#选中class为item-0和active的li节点内的a节点
print(a,type(a))
print(a.attr('href'))
<a href="link3.html"><span class="bold">third item</span></a> <class 'pyquery.pyquery.PyQuery'>
link3.html
也可以使用,结果相同
print(a.attr.href)
当返回结果包含多个节点时,调用 attr 方法,只会得到第一个节点的属性。想获取所有的 a 节点的属性,就要用到前面所说的遍历了:
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
a = doc('a')
for item in a.items():
print(item.attr('href'))
link2.html
link3.html
link4.html
link5.html
2、获取文本
使用text()属性
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
a = doc('.item-0.active a')
print(a)
print(a.text())
<a href="link3.html"><span class="bold">third item</span></a>
third item
但如果想要获取这个节点内部的 HTML 文本,就要用 html 方法。
如果得到的结果是多个节点,并且想要获取每个节点的内部 HTML 文本,则需要遍历每个节点。而 text() 方法不需要遍历就可以获取,它将所有节点取文本之后合并成一个字符串。
六、节点操作
pyquery可以为某个节点添加一个 class,移除某个节点等。
1、addClass 和 removeClass
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
a = doc('.item-0.active')
print(a)
a.remove_class('active')
print(a)
a.add_class('active')
print(a)
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
2、attr、text、html
attr 方法对属性进行操作,text 和 html 方法来改变节点内部的内容。
attr 方法来修改属性,其中该方法的第一个参数为属性名,第二个参数为属性值。接着,调用 text 和 html 方法来改变节点内部的内容
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.attr('name', 'link')
print(li)
li.text('changed item')
print(li)
li.html('<span>changed item</span>')
print(li)
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link">changed item</li>
<li class="item-0 active" name="link"><span>changed item</span></li>
调用 attr 方法后,li 节点多了一个原本不存在的属性 name,其值为 link。接着调用 text 方法,传入文本之后,li 节点内部的文本全被改为传入的字符串文本了。最后,调用 html 方法传入 HTML 文本后,li 节点内部又变为传入的 HTML 文本了。
所以说,如果 attr 方法只传入第一个参数的属性名,则是获取这个属性值;如果传入第二个参数,可以用来修改属性值。text 和 html 方法如果不传参数,则是获取节点内纯文本和 HTML 文本;如果传入参数,则进行赋值。
3、remove
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
Hello, World
<p>This is a paragraph.</p>
</div>
'''
doc = pq(html)
wrap = doc('.wrap')
wrap.find('p').remove()
print(wrap.text())
Hello, World
首先选中 p 节点,然后调用了 remove() 方法将其移除,然后这时 wrap 内部就只剩下 Hello, World 这句话了,然后再利用 text() 方法提取即可
七、伪类选择器
from pyquery import PyQuery as pq
html = '''
<div class="wrap">
<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="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
doc = pq(html)
doc = pq(html)
li = doc('li:first-child')
print(li)
li = doc('li:last-child')
print(li)
li = doc('li:nth-child(2)')
print(li)
li = doc('li:gt(2)')
print(li)
li = doc('li:nth-child(2n)')
print(li)
li = doc('li:contains(second)')
print(li)
这里我们使用了 CSS3 的伪类选择器,依次选择了第一个 li 节点、最后一个 li 节点、第二个 li 节点、第三个 li 之后的 li 节点、偶数位置的 li 节点、包含 second 文本的 li 节点
以上是关于python爬虫学习记录解析库的使用——pyquery的主要内容,如果未能解决你的问题,请参考以下文章