介绍

  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. DataWorks 功能实践速览

    ​简介: DataWorks功能实践系列,帮助您解析业务实现过程中的痛点,提高业务功能使用效率! 功能推荐:独享数据集成资源组 如上期数据同步解决方案介绍,数据集成的批数据同步任务运行时,需要占用一定 ...

  2. 2018-2-13-win10-uwp-从StorageFile获取文件大小

    title author date CreateTime categories win10 uwp 从StorageFile获取文件大小 lindexi 2018-2-13 17:23:3 +0800 ...

  3. 2019-8-31-dotnet-线程静态字段

    title author date CreateTime categories dotnet 线程静态字段 lindexi 2019-08-31 16:55:58 +0800 2019-06-13 0 ...

  4. vue+element设置选择日期最大范围(优秀版)

    element的选择日期组件里没有像移动端vant直接设置max-date的api,因此在不能动态设置选择的第二个时间(需要分别选择起止时间和结束时间,但可以加上关联), 看了很多博客有的效果直接出不 ...

  5. EXCEL-统计sheet个数、统计指定单元格个数

    Excel的函数,可以直接在里面执行 1.统计sheet个数 =SHEETS() 参考:https://office.tqzw.net.cn/excel/excel/8168.html 2.统计单元格 ...

  6. JUC并发编程学习笔记(二)Lock锁(重点)

    Lock锁(重点) 传统的synchronized 传统的解决多线程并发导致的一些问题我们会使用synchronized关键字来解决,synchronized的本质就是队列.锁. Lock的实现类有: ...

  7. Python中强大的通用ORM框架:SQLAlchemy

    Python中强大的通用ORM框架:SQLAlchemy https://zhuanlan.zhihu.com/p/444930067

  8. Ruby on Rails Active Record数据库常用操作

    目录 创建 批量插入 判断是否存在 Ruby on Rails 日期查询方法 文档地址: https://freed.gitee.io/rails-guides/active_record_query ...

  9. iOS LLVM 中的宏定义

    在阅读 Objc 库源码时常常会遇到很多宏定义,比如宏 SUPPORT_INDEXED_ISA.SUPPORT_PACKED_ISA,代码如下所示: // Define SUPPORT_INDEXED ...

  10. fastposter v2.9.3 简单易用的海报生成器

    fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像)即可生成海报. 点击代码直接生成各种语言的调用代码,方便快速开发. 现已服务众 ...