强大的pyquery解析器详解

简介: 强大的pyquery解析器详解

在本文中博主将介绍pyquery的知识点,如果你认为BeautifulSoup这个CSS选择器不是那么强大,来认识一下pyquery的强大吧,个人认为BeautifulSoup是一个比较的老的库,已经很久没有更新了,但是现在市面上大多都是BeautifulSoup的文章,所以小编将在这里介绍pyquery的用法。

首先下载解析库

打开PyCharm的右下角的终端,在PyCharm中安装是为了防止安装到别的版本的Python

如果你没有下载对应的汉化包,点击terminal即可

然后直接在终端 中输入命令 pip install pyquery

如果最后终端最后一行显示Successful .......就安装成功了,如果是因为链接的问题

换成以下命令即可 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyquery

这里博主就不讲解如何永久换成清华源了,如果需要可以在评论区回复一下

下面开始正式讲解pyquery的用法

我们解析将一直用以下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>
'''

看一下代码

from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li'))

首先导入PyQuery这个对象取别名为pq,接着将你要解析的HTML字符串传给PyQuery类做参数,这样就完成了初始化,接着向初始化对象中传入CSS选择器在本例中传入了li节点,就可以选择所有的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>

在初始化的参数中还可以传入url,这将自动对目标网址发送请求得到HTML字符串

pq(url = '*****************')

如果你要传入本地文件,操作也很简单

pq(filename=文件名)

查找结点

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('ul'))

选中了所有的ul节点,想要获取此节点下所有的子孙节点

list = doc.find('li')

即可获得所有的li子节点

如果只想要获取子节点

list = doc.children('li')

获取其兄弟节点

list = doc.siblings('对应的css选择器')

以上方法可以都不用记,直接用下面方法也可以

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)
ul = doc('ul')
li = ul('li')

在找到ul节点之后在找li节点

遍历节点

注意pyquery选择的节点,无论时多个节点,还是单个节点,并没有像BeauyifulSoup那样返回一个列表,如果想要将其像列表一样遍历,使用items()方法获取一个生成器即可,代码如下

doc = pq(html)
a = doc('li')
for item in a.items():
    print(item.attr('class'))

输出如下

item-0
item-1
item-0 active
item-1 active
item-0

但是如果你直接输出print(item)会出现换行符,因为每一个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>

解决方法也很简单

str(item).replace('\n','')

因为通过pyqury提取出来的节点都是<class 'pyquery.pyquery.PyQuery'>类形的,所以需要转换成字符串

也可以通过正则来写正则表达式如下

re.sub('\n+','',str(item))

\n+的意思是匹配多个换行符。

获取其文本还有属性也很简单

获取节点文本

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('a')
print(a.text())

即可获取全部所有a节点及其所以内部节点的文本内容

运行结果如下

second item third item fourth item fifth item

如果你选择的是li节点再使用li.text()结果如下

first item second item third item fourth item fifth item

获取节点属性

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')
#调用attr方法在传入属性的名字即可获取对应的属性值
print(a.attr('href'))
#也可以这样写
print(a.attr.href)
#以上两种写法一致

注意看下面代码

from pyquery import PyQuery as pq
doc = pq(html)
a = doc('a')
#调用attr方法在传入属性的名字即可获取对应的属性值
print(a.attr('href'))

运行结果如下

link2.html

结果中只有第一个节点的属性值

这是和text方法的区别,如果你想要获取全部节点的属性遍历即可

pyquery还有一个强大的功能是可以使用伪类选择器

代码如下

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中的第一个节点
li = doc('li:first-child')
print(li)
# 获取li中的最后一个节点
li = doc('li:last-child')
print(li)
# 其中数字是几就获取第几个节点
li = doc('li:nth-child(2)')
print(li)
# 获取偶数节点
li = str(doc('li:nth-child(2n)'))
print(li)
# 获取带second文本的节点
li = doc('li:contains(second)')
print(li)

其中的伪类写法常用的就这几种,各位在写的时候套用即可,其中的伪类选择器nth-child(n)非长的有用处,当你只想要在众多li标签的第一个或者第一个li就可以通过伪类选择器

如下例

<th>代理IP地址</th>&#13;
            <th>端口</th>&#13;
            <th>匿名度</th>&#13;
            <th>类型</th>&#13;
            <th>get/post支持</th>&#13;
            <th>位置</th>&#13;
            <th>响应速度</th>&#13;
            <th>最后验证时间</th>&#13;

我们在用代理ip的时候在提取ip和端口的号的时候可以直接通过nth-child(1),nth-child(2)获得

还有个BeautifulSoup没有的强大用法,可以对选中的节点进行操作

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)

运行结果如下

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

另外attr和text方法也可以改变节点内容

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 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">change item</li>

注意事项

pyquery在找不到节点的时候并不会报错,只会打印一个空白行

例如

import requests
from pyquery import PyQuery as pq
ip_port = []
url = '*******************'
doc = pq(requests.get(url).content.decode('gb2312'))
print(doc('abc'))

在这段代码中最后的prinnt(doc('abc'))中一定能看出来我这里的CSS选择器是瞎写的吧但是

来看一下控制台的输出内容

就只打印了一个空白行,所以如果遇到空白行的时候一定要特别注意,是不是自己的CSS选择器写错了。

以上就是pyquery的基本用法,想要了解其更详细的内容请查阅官方文档

https://pyquery.readthedocs.io

早点了解官方文档的使用对技术的精进非常有好处

如果我的内容有错误请各位在评论中指出

目录
相关文章
|
2月前
|
前端开发 JavaScript
pyquery:一个灵活方便的 HTML 解析库
pyquery:一个灵活方便的 HTML 解析库
30 1
|
数据采集 Python
Python爬虫:pyquery模块解析网页
Python爬虫:pyquery模块解析网页
146 0
|
数据采集 前端开发 Python
Python爬虫:pyquery模块解析网页
Python爬虫:pyquery模块解析网页
154 0
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
81 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
65 0
|
2月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
69 0
|
2月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
92 0
|
2天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
2天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

热门文章

最新文章

推荐镜像

更多