python爬虫-PyQuery详解
Python爬虫解析库,主流的有
- PyQuery
- Beautifulsoup
- Scrapy Selectors
- 正则表达式。
PyQuery和scrapy Selectors都是基于lxml模块,而lxml和正则表达式都是C语言写的。
Beautifulsoup是用纯Python编写的。
正则表达式的构造稍微复杂一点,一般在结构化的网页中易出错。
我们声明一个长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>
1.初始化
1)字符串初始化
rom 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>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li'))
运行结果
传入 li 节点,这样就可以选择所有的 li 节点。
2)URL 初始化
传入网页的 URL,此时只需要指定参数为 url
from pyquery import PyQuery as pq
doc = pq(url='https://www.csdn.net/')
print(doc('head'))
运行结果PyQuery 对象会首先请求这个 URL,然后用得到的 HTML 内容完成初始化。
2.基本CSS选择器
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="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))
运行结果
我们传入了一个 CSS 选择器 #container .list li,它的意思是先选取 id 为 container 的节点,然后再选取其内部的 class 为 list 的节点内部的所有 li 节点。然后,打印输出
3.查找节点
1)子节点
find 的查找范围是节点的所有子孙节点
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="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
print(items)
lis = items.find('li')
print(lis)
输出结果
如果我们只想查找子节点,那可以用 children 方法
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
print(items)
lis = items.children()
print(lis)
运行结果
如果要筛选所有子节点中符合条件的节点,比如想筛选出子节点中 class 为 active 的节点,可以向 children() 方法传入 CSS 选择器.active:
lis = items.children('.active')
print(lis)
结果
<li class="item-0 active"><a href="link3.html"><spanclass="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li
2)父节点
我们可以用 parent 方法来获取某个节点的父节点
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="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
container = items.parent()
print(container)
运行结果
如果想获取某个祖先节点,这时可以用 parents 方法
3)兄弟节点
如果要获取兄弟节点,可以使用 siblings() 方法
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings())
运行结果
这正是我们刚才所说的 4 个兄弟节点。
如果要筛选某个兄弟节点,我们依然可以向 siblings 方法传入 CSS 选择器
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))
4.遍历
from pyquery import PyQuery as pq
doc = pq(html)
lis = doc('li').items()
print(type(lis))
for li in lis:
print(li, type(li))
运行结果
5.获取信息
1)获取属性
调用 attr() 方法来获取属性
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="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a.attr.herf)
运行结果
2)获取文本
调用 text 方法来实现
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>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a)
print(a.text())
运行结果
如果想要获取这个节点内部的 HTML 文本,就要用 html 方法
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(li.html())
运行结果
6.节点操作
1)addClass 和 removeClass
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>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.removeClass('active')
print(li)
li.addClass('active')
print(li)
运行结果
2)attr、text、html
html = '''
<ul class="list">
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
</ul>
'''
from pyquery import PyQuery as pq
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)
运行结果
attr 方法来修改属性,该方法的第一个参数为属性名,第二个参数为属性值
text 和 html 方法来改变节点内部的内容
3)remove
html = ''' <div class="wrap">
Hello, World
<p>This is a paragraph.</p>
</div> '''
from pyquery import PyQuery as pq
doc = pq(html) wrap = doc('.wrap')
print(wrap.text())
运行结果如下
Hello, World This is a paragraph.
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
wrap.find('p').remove()
print(wrap.text())
运行结果
7.伪选择器
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>
'''
from pyquery import PyQuery as pq
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 节点。
这里有更多伪选择器的用法
https://www.w3school.com.cn/css/index.asp
- 参考书籍:python3网络爬虫开发实战(崔庆华著)
来源:CSDN
作者:YOUNGBC
链接:https://blog.csdn.net/qq_43645530/article/details/104095623