自从有了pyquery,我手里的xpath瞬间他就不香了

自从有了pyquery,我手里的xpath瞬间他就不香了

📢 大家好,我是小菜狗同学,一名大一的后端爱好者

📢 这篇文章将讲解爬虫中解析pysquery的用法

📢 非常感谢你的阅读,不对的地方欢迎指正 😘😘

📢 愿你忠于自己,热爱生活,生活中不仅要有技术,更有诗和远方。

📢本文内容参考 崔庆才<网络爬虫开发实战第二版>

1.如何安装pyquery

pip install pyquery

更加详细的安装可以参考崔庆才大佬,https://cuiqingcai.com/5186.htm

2. 为何选择使用pyquery

我们知道目前主流的爬虫解析库:

  • PyQuery
  • Beautifulsoup
  • Scrapy Selectors
  • 正则表达式
  • xpath

PyQueryscrapy Selectors都是基于lxml模块,xlml和正则是基于C写的,只有Beautifulsoup是用纯python写的,所以解析速度,毫无疑问Beautifulsoup比其它解析满了五倍以上。而正则表达式比较复杂 容易出错,pyquery相较于xpath更简洁。你信不信当你看完,你会觉得你手里的这些他都不香了

不信?下面来用一个实例感受一下

# 引入对象 取别名
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)
# 传入li节点 这样就可以选取所有li节点了
print(doc('li'))


out:     <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>

URL初始化

初始化的参数除了可以用字符串还可以使用url的方式传递,只需要指定Pyquery的对象参数为url即可

doc = pq(url='https://cuiqingcai.com')
print(doc('title'))


out:/ <title>静觅丨崔庆才的个人站点<\title>

这段代码是什么意思呢?首先Pyquery对象会去请求这个url,然后得到URL返回的内容初始化给pq类

文件初始化

doc = pq(filename='demo.html')
print(doc('li'))

这样它会先读取本地的文件内容,然后将文件内容以字符串的形式传递给 pyquery 类来初始化。

基本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')))

out: 	 <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>

这里我们初始化后,给doc传入了一个CSS选择器#container .list li 意思是先选取id为container的节点,再选取其内部class为list的所有li节点

下面,我们直接遍历这些节点,然后调用 text 方法,就可以获取节点的文本内容

doc = pq(html)
lis = doc('#container .list li')

for item in lis.items():
    # 提取li节点的所有文本内容
    print(item.text())

查找子节点

doc = pq(html)
# 选取class为list的节点
items = doc('.list')

print(items)
lis = items.find('li')
print(type(lis))
print(lis)

find 的查找范围是节点的所有子孙节点,而如果我们只想查找子节点,那可以用 children 方法:

lis = items.children()
print(type(lis))
print(lis)

如果要筛选所有子节点中符合条件的节点,比如想筛选出子节点中 class 为 active 的节点,可以向 children 方法传入 CSS 选择器 .active,代码如下:

doc = pq(html)
items = doc('.list')
a = items.children('.item-1')
print(a)

我们看到输出的结果已经做了筛选,留下了 class 为 .item-1 的节点。

父节点

items.parent()方法 返回所有的 父辈节点 如果需要筛选 在其中传入CSS选择器

如果想返回祖先节点 ites.parents()即可*

兄弟节点

doc = pq(html)
# 这里需要注意 这两种是截然不同的意义
#在这个例子中我们首先选择 class 为 list 的节点,内部 class 为 item-0 和 active 的节点,也就是第 3 个 li 节点。很明显,它的兄弟节点有 4 个,那就是第 1、2、4、5 个 li 节点。
li = doc('.list .item-0.active')
# 这个写法表明首先取class为list的节点,内部class为item-0的节点,之后再选取其内部为active的节点
li = doc('.list .item-0 .active')
# 对兄弟节点再做筛选
print(li.siblings('.active'))
print(li.siblings())

遍历

pyquery 的选择结果既可能是多个节点,也可能是单个节点,类型都是 pyquery 类型,并没有返回列表。

对于单个节点来说,可以直接打印输出,也可以直接转成字符串

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(str(li))

对于有多个节点的结果,我们就需要用遍历来获取了。例如,如果要把每一个 li 节点进行遍历,需要调用 items 方法:

lis = doc('li').items()

调用 items 方法后,会得到一个生成器,遍历一下,就可以逐个得到 li 节点对象了,每个对象非常灵活,可以继续使用如上的方法。

doc = pq(html)
lis = doc("li").items()
for i in lis:
    print(i.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>
    '''
    
    doc = pq(html)
    a = doc('.item-0.active a')
    # print(a, type(a))
    print(a.attr('href'))
    
    
    # link3.html
    

    当返回结果包含多个节点时,调用 attr 方法,只会得到第 1 个节点的属性。

  • 获取文本

    很简单

    print(a.text())
    

    但如果你想要获取这个节点内部的 HTML 文本,就要用 html 方法了:

    print(a.html())
    

    text 方法不需要遍历就可以获取,它将所有节点取文本之后合并成一个字符串。

    html 需要遍历获取 不然只能返回一个

remove

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怎么办,直接使用text()全部提取了

这时 remove 方法就可以派上用场了

wrap.remove('p')  # 选中p节点 remove移除即可

伪类选择器

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)') #包含文本second的节点
print(li)

THE LAST

关于 CSS 选择器的更多用法,可以参考:http://pyquery.readthedocs.io/en/latest/api.html

怎么样 是不是感觉手里的xpath瞬间他就不香了

求👍求💗

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小 澜 同 学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值