介绍

  parsel这个库可以解析HTML和XML,并支持使用XPath和CSS选择器对内容进行提取和修改,同时还融合了正则表达式的提取功能。parsel灵活强大,同时也是Python最流行的爬虫框架的底层支持。

parsel的API和Scrapy选择器的API极其相似,因为Scrapy的选择器就是基于parsel做的二次封装。

准备工作

可以使用pip3安装:

pip install parsel

初始化

声明html变量:

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

使用parsel库里的Selector这个类声明一个Selector对象:

from parsel import Selector
selector = Selector(text=html)

  创建Selector对象后,传入text参数,内容就是刚才声明的HTML字符串,然后把创建的对象赋值为selector变量。

  有了Selector对象后,可以使用css和xpath对象方法分别传入CSS选择器和XPath进行内容提取,例如提取class包含item-0的节点:

items = selector.css('.item-0')
print(len(items),type(items))
items2 = selector.xpath('//li[contains(@class,"item-0")]')
print(len(items2),type(items2),items2)

  先用css方法进行节点提取,然后输出了提取结果的长度和内容。xpath方法写法一样。

运行结果:

3 <class 'parsel.selector.SelectorList'> [<Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0">first item</li>'>, <Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0 active"><a href="li...'>, <Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0"><a href="link5.htm...'>]
3 <class 'parsel.selector.SelectorList'> [<Selector query='//li[contains(@class,"item-0")]' data='<li class="item-0">first item</li>'>, <Selector query='//li[contains(@class,"item-0")]' data='<li class="item-0 active"><a href="li...'>, <Selector query='//li[contains(@class,"item-0")]' data='<li class="item-0"><a href="link5.htm...'>]

  两个结果都是SelectorList对象,这其实是一个可迭代对象。用len方法获取了结果的长度,都是3。另外,提取结果代表的解读也是一一样的,都是第1、3、5个li节点,每个节点还是以Selector对象的形式返回,其中每个Selector对象的data属性里面包含对应提取节点的HTML代码。

  第一次用cs方法提取的节点,结果中的Selector对象输出的是xpath属性而不是css属性。这是因为在css方法的背后,传入的CSS选择器首先是被转成了XPath,真正用于节点提取的是XPath。其中CSS选择器准换为XPath的过程是由底层的cssselect这个库实现的,例如 .item-0 这个CSS选择器转换为XPath的结果就是 descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' item-0')],因此输出的Selector对象就有了XPath属性。

提取文本

  提取的结果是一个可迭代对象SelectorList,那么想要获取提取到的所有li节点的文本内容,就要对结果进行遍历:

from parsel import Selector
selector = Selector(text=html)
items = selector.css('.item-0')
for item in items:
text = item.xpath('.//text()').get()
print(text)

  遍历items变量,并赋值为item,于是这里的item变成了一个Selector对象,此时又可以调用其css或xpath方法进行内容提取。这里用.//text()这个XPath写法提取了当前节点的所有内容,此时如果不在调用其他方法,那么返回结果依然为Selector构成的可迭代对象SelectorList。SelectorList中有一个get()方法,可以将SelectorList包含的Selector对象中的内容提取出来。

运行结果:

first item
third item
fifth item

get方法的作用是从SelectorList里面提取第一个Selector对象,然后输出其中的结果。

实例:

result = selector.xpath('//li[contains(@class,"item-0")]//text()').get()
print(result)

运行结果:

first item

  使用//li[contains(@class,"item-0")]//text()选取了所有class包含item-0的li节点的文本内容。准确来说返回结果SelectorList应该对应三个li对象,而这里get方法仅仅返回第一个li对象的文本内容,因为他其实只会提取第一个Selector对象的结果。

  若想提取所有Selector对应内容,可以使用getall方法:

result = selector.xpath('//li[contains(@class,"item-0")]//text()').getall()
print(result)

运行结果:

['first item', 'third item', 'fifth item']

  得到的是列表类型的结果,其中的每一项和Selector对象时一一对应的。

  如果要提取SelectorList里面对应的结果,可以使用get或getall方法,前者会获取第一个Selector对象里面的内容,后者会依次获取每个Selector对象对应的结果。

  把xpath方法改写成css方法:

result = selector.css('.item-0 *::text').getall()
print(result)

  用*提取所有子节点(包括纯文本节点),提取文本需要再加上::text,最终的运行结果和上面是一样。

提取属性

  直接在XPath或者CSS选择器中表示出即可。

  例如提取第三个li节点内部的a节点的href属性:

from parsel import Selector
selector = Selector(text=html)
items = selector.css('.item-0')
result = selector.css('.item-0.active a::attr(href)').get()
print(result)
result = selector.xpath('//li[contains(@class,"item-0") and contains(@class,"active")]/a/@href').get()
print(result)

  分别用css和xpath方法实现。以同时包含item-0和active两个class为依据,来选取第三个li节点,然后进一步选取了里面的a节点。对于CSS选择器,选取属性需要添加::attr(),并传入对应的属性名称才可以选取;对于XPath,直接用/@再加属性名称即可选取。最后统一用get方法提取结果。

运行结果:

link3.html
link3.html

两种方法都正确提取了href属性。

正则提取

  除了常用的css和xpath方法,Selector对象还提供了正则表达式提取方法:

from parsel import Selector
selector = Selector(text=html)
result = selector.css('.item-0').re('link.*')
print(result)

  用css方法提取所有class半酣item-0的节点,然后使用re方法传入link.*,用来匹配包含link的所有结果。

运行结果:

['link3.html"><span class="bold">third item</span></a></li>', 'link5.html">fifth item</a></li>']

  re方法遍历了所有提取到的Selector对象,然后根据re方法传入的正则表达式,查找出符合规则的节点源码并以列表形式返回。

  如果在调用css方法时,已经提取了进一步的结果,例如提取了节点文本值,那么re方法就只针对节点文本值进行提取:

from parsel import Selector
selector = Selector(text=html)
# result = selector.css('.item-0').re('link.*')
result = selector.css('.item-0 *::text').re('.*item')
print(result)

运行结果:

['first item', 'third item', 'fifth item']

也可以使用re_first方法来提取第一个符合规则的结果:

from parsel import Selector
selector = Selector(text=html)
# result = selector.css('.item-0').re('link.*')
# result = selector.css('.item-0 *::text').re('.*item')
result = selector.css('.item-0').re_first('<span class="bold">(.*?)</span>')
print(result)

  调用re_first方法,提取的是被span标签包含的文本值,提取结果是用小括号括起来表示一个提取分组,最后输出的结果就是小括号包围的部分

运行结果:

third item

总结

  parsel官方文档:

https://parsel.readthedocs.io/

parsel的使用的更多相关文章

  1. python爬虫网页解析之parsel模块

    08.06自我总结 python爬虫网页解析之parsel模块 一.parsel模块安装 官网链接https://pypi.org/project/parsel/1.0.2/ pip install ...

  2. Python中使用requests和parsel爬取喜马拉雅电台音频

    场景 喜马拉雅电台: https://www.ximalaya.com/ 找到一步小说音频,这里以下面为例 https://www.ximalaya.com/youshengshu/16411402/ ...

  3. 求助:我需要用Python中parsel模块提取文章的文本内容,有什么办法

    求助: 像这样 我想提取小说文章内容 怎么提取 我要用的模块有parsel <!DOCTYPE html> <html lang="en"> <hea ...

  4. Python之路【第二十三篇】爬虫

    difference between urllib and urllib2 自己翻译的装逼必备 What is the difference between urllib and urllib2 mo ...

  5. Windows平台下,Scrapy Installation,安装问题解决

    按理说直接:pip install scrapy 就可以成功,但是出现了错误"libxml/xpath.h: No such file or directory" "er ...

  6. 在Pypi上发布自己的Python包

    使用Python编程的都知道,Python的包安装非常的方便,一般都是可以pip来安装搞定: sudo pip install <package name> pip的安装请移步:https ...

  7. win7中python3.4下安装scrapy爬虫框架(亲测可用)

    貌似最新的scrapy已经支持python3,但是错误挺多的,以下为在win7中的安装步骤: 1.首先需要安装Scrapy的依赖包,包括parsel, w3lib, cryptography, pyO ...

  8. Python爬虫从入门到放弃(十三)之 Scrapy框架的命令行详解

    这篇文章主要是对的scrapy命令行使用的一个介绍 创建爬虫项目 scrapy startproject 项目名例子如下: localhost:spider zhaofan$ scrapy start ...

  9. Python使用Scrapy框架爬取数据存入CSV文件(Python爬虫实战4)

    1. Scrapy框架 Scrapy是python下实现爬虫功能的框架,能够将数据解析.数据处理.数据存储合为一体功能的爬虫框架. 2. Scrapy安装 1. 安装依赖包 yum install g ...

  10. Flask 学习 六 大型程序结构

    pip freeze >requirement.txt 自动生成版本号 pip install -r requirement.txt 自动下载对应的库 梳理结构 config.py #!/usr ...

随机推荐

  1. [GPT] export, export default, import, module.exports, require

    ES6 规范:export 和 import 配对 import 的 {} 大括号里面指定要从其他模块导入的变量名, 如果 export 命令没有写 default,那么 import {} 大括号里 ...

  2. 02 Orcad设计环境讲解与工程创建

    02   Orcad设计环境讲解与工程创建 学习目标: 1)   掌握Orcad软件绘制元件库以及原理图的方法: 2)   掌握Allegro软件绘制PCB库以及PCB的方法: 3)   掌握Orca ...

  3. foreach更改element内容后this到data不生效导致页面数据无变化

    list.forEach(element => {  element = element.split('^')    console.log(element)  }) 数据已经被更改,但在外部t ...

  4. ES_CCS/R(三):跨集群复制 Cross-cluster replication(CCR)

    跨集群复制(CCR)功能支持将远程集群中的索引复制到本地集群. 可以在一些常见的生产用例中使用此功能: 灾难恢复(DR)/高可用性(HA):如果主群集发生故障,则进行灾难恢复. 辅助群集可以用作热备份 ...

  5. 五、Doris数据分布

    在 Doris 中,数据都以表(Table)的形式进行逻辑上的描述 名词解释 数据分布:数据分布是将数据划分为子集, 按一定规则, 均衡地分布在不同节点上,以期最大限度地利用集群的并发性能 短查询:s ...

  6. uniapp清除指定key缓存

    清除缓存 onLaunch: function () { console.log('App Launch') const preservedKeys = ['ishowFixPre', 'readTi ...

  7. istio sidecar 工作方式

    istio 是什么 Istio 是一个开放源代码的服务网格,它为基于微服务的应用程序提供了一种统一的方式来连接.保护.监控和管理服务.Istio 主要解决的是在微服务架构中的服务间通信的复杂性问题,它 ...

  8. java学习之旅(day.18)

    网络编程 概述 计算机网络:自己百度吧 网络编程的目的:传播交流信息.数据交换.通信 想要达到这个效果需要什么: 如何准确的定位网络上的一台主机 端口 定位到这个计算机上的某个资源 找到了这个主机,如 ...

  9. Dubbo SPI扩展机制源码详解(基于2.7.10)

    Dubbo SPI 一. 概述 本文主要分享 Dubbo 的拓展机制 SPI. 想要理解 Dubbo ,理解 Dubbo SPI 是非常必须的.在 Dubbo 中,提供了大量的拓展点,基于 Dubbo ...

  10. Anaconda 虚拟环境

    1. 查看虚拟环境 conda env list 2. 创建虚拟环境 conda create -n env_name python=3.8 --- env_name: 虚拟环境名 --- pytho ...