当前位置: 首页 > news >正文

python contains类似函数_Python爬虫系列之解析库详解

990e428e14d6090221ffef7c743a9c39.png

在之前的文章中我们介绍了Python爬虫的基本原理、怎么通过Python的第三方模块发起基本的HTTP请求,今天咱们接着爬虫网络请求之后剩余的流程进行讲解。咱们已经清楚爬虫的流程:发起请求、返回响应、响应解析、数据存储。以上是基本爬虫的标准流程,接下来咱们详细介绍一下在Python爬虫中响应解析库的使用。

对前端稍有了解的朋友就能知道,对于网页的节点来说,它可以定义id、class等属性,而且节点标签之前有很强的层次关系,在解析网页时,我们可以通过xpath、css选择器来实现对一个或多个节点的定位。最主要的是,正向咱们前面说的那样,Python中针对这些常用的功能,都有成熟的第三方模块,我们可直接引入使用,例如lxml、BeautifulSoup、pyquery等。

1、Xpath用法

Xpath全称XML Path Language(xml路径语言),它是一门在XML文档中查找信息的语言,原始用法是用来搜索XML文档的,但是在HTML文档中同样适用。在爬虫中,我们就可以通过Xpath来解析HTML网页获取我们想要得到的数据。

1.1 XPath常用规则

表达式描述说明
Nodename获取此节点的所有子节点
/获取当前节点的直接子节点
//获取当前节点的子孙节点
.选取当前节点
..选取当前节点的父节点
@设置属性选取

以上就是XPath比较常用的几条规则,一般的选取规则都可以通过以上几条规则转换而来。例如:

//title[@lang=’eng’] 说明:获取当前节点下面属性lang为eng的所有title子节点。

1.2 环境搭建

Pip install lxml

1.3 示例说明

1.3.1 XPath用法举例说明

from lxml import etree
stext = """
<div>
<ul>
<li class='t0'><a href="d1.html">d1</a></li>
<li class='t1'><a href="d2.html">d2</a></li>
<li class='t2'><a href="d3.html">d3</a></li>
<li class='t3'><a href="d4.html">d4</a></li>
</ul>
</div>
"""
hmtlContent = etree.HTML(stext)
rs = etree.tostring(hmtlContent)
print(rs)

以上是简单说明,首先导入lxml支持模块,将手动定义的html源代码通过初始化构建成一个XPath解析对象。Etree的HTML用法会自动补全代码中的标签缺失。Tostring显示修正后的html源代码,但格式部位字符串,而是bytes。

1.3.2 读取文件进行解析

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
htmlBytes = etree.tostring(hmtlContent)

1.3.3 获取所有节点

获取所有节点指获取html代码中的所有子节点,通常使用“//”规则开头来获取我们想提取的节点,同样以上述html源代码为例:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
allLabels = hmtlContent.xpath("//*")
print(allLabels)

这里使用“*”代表匹配html代码中的所有节点,返回的allLabels为list类型,list中包含上述文件中的所有ul、li、a标签。

也可以通过指定节点标签名来获取指定所有标签:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
allLabels = hmtlContent.xpath("//li")
print(allLabels)

上述代码即获取html文件代码中的所有“li”标签。即“//”代表获取所有当前节点。

1.3.4 获取子节点

我们可通过“/”、“//”来查找元素的子节点或者子孙节点。例如获取li节点xia的所有直接a节点:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
allLabels = hmtlContent.xpath("//li/a")
print(allLabels)

如果想获取节点下的所有子孙节点,则直接通过“//”即可实现,例如获取“ul”节点下的所有“a”节点:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
allLabels = hmtlContent.xpath("//ul//a")
print(allLabels)

在此主要区别“/”和“//”的用法,“/”用于获取直接子节点,“//”用于获取节点下的所有子孙节点。

1.3.4 获取父节点

通过上述举例我们了解到XPath可通过连续的“/”、“//”获取直接子节点或子孙节点,同样我们可通过子节点来获取其父节点。例如:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//a[@href="d4.html"]/../@class')
print(result)

上述代码含义:先获取href属性为“d4.html”的a节点,然后通过“..”获取到其父节点,赞通过“@”用法获取到其父节点的class属性值。

也可通过“parent::”来达到上述目的:

hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//a[@href="d4.html"]/parent::*/@class')
print(result)

1.3.5 属性匹配

当我们在选取节点标签的时候,我们可以通过“@”来进行属性的过滤。比如现在我们要实现获取class为t3的li节点:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//li[@class="t3"]')
print(result)

1.3.6 获取节点文本

获取节点的本质是想获取节点标签间的数据,所以此实现方法是比较重要的。接下来实现1.3.5中获取到的li节点的文本:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//li[@class="t3"]//text()')
print(result)

1.3.7 节点属性获取

很多时候页面中有一部分数据比较隐蔽,并不是存在于节点标签文本域中的,儿事存在于节点属性中的,怎么获取?

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//li/a/@href')
print(result)

上述代码实现内容,获取所有li节点的直接子节点a的href属性。

1.3.8 属性多值匹配

有的时候节点的某个属性可能有多个值,例如:

stext = """
<div>
<ul>
<li class='t0 show' name="l0"><a href="d1.html">d1</a></li>
<li class='t1 show' name="l1"><a href="d2.html">d2</a></li>
<li class='t2 show' name="l2"><a href="d3.html">d3</a></li>
<li class='t3 show' name="l3"><a href="d4.html">d4</a></li>
</ul>
</div>
"""

这个时候我们就不能用上述的@方式来获取属性值了,这样只会获取到“”,此时我们可通过“contains()”函数来实现获取。“contains”,顾名思义就是包含的意思,写法为:contains(@class, ‘t0’)

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//li[contains(class,"t2")]/a/text()')
print(result)

含义:获取class属性包含有t2的li节点的直接a节点的文本。

还可进行多属性值匹配:

from lxml import etree
hmtlContent = etree.parse("test.html",etree.HTMLParser())
result = hmtlContent.xpath('//li[contains(class,"t2") and @name="l2"]/a/text()')
print(result)

2、BeautifulSoup用法

BeautifulSoup是python的一个HTML和XML的解析库,依赖于第三方模块lxml,通过它同样可以实现XPath的功能,很方便的从网页中提取到相关的节点并获取其数据。但是其在解析时实际还依赖与其他解析器,如下表。

解析器使用说明
Python标准解析BeautifulSoup(markup,”html.parser”)
Lxml html解析器BeautifulSoup(markup,”lxml”)
Lxml xml解析器BeautifulSoup(markup,”xml”)
Html5liBeautifulSoup(markup,”html5lib”)

此处讲解我们使用以下html示例代码:

<div id='demo'>
<ul name=’uld’>
<li class='t0 show'><a href="d1.html">d1</a></li>
<li class='t1 show'><a href="d2.html">d2</a></li>
<li class='t2 show'><a href="d3.html">d3</a></li>
<li class='t3 show'><a href="d4.html">d4</a></li>
</ul>
</div>

2.1 节点选择器基本用法:

from bs4 import BeautifulSoup
soup = BeautifulSoup(stext,"lxml")

Print(soup.div.id)

以上就是获取html代码中的div标签的id属性。

还可以获取节点的所有属性:

Print(soup.div.attrs)

Print(soup.div.attrs[‘id’])

获取节点标签的文本:

Print(soup.p.string)

通过节点关系进行嵌套获取:

Print(soup.div.ul.attrs[‘name’])

2.2 方法选择器基本用法

2.2.1 find_all()

通过方法名可直译,获取满足某个条件的所有节点:

例如,获取上述代码中的所有li节点:

Lis = soup.find_all(“li”)

可通过名称查询:

Print(soup.find_all(name=”uld”))

属性名查找:

Print(soup.find__all(attrs={“name”:”uld”}))

2.2.2 find()

和上述find_all()方法对应,只是find_all()返回的是结果列表,而find()返回的是单个结果。

3、pyquery用法

获取web页面节点获取数据出了上述两种解析方法之外还有一种比较常见的方法:pyquery()。

安装:pip install pyquery

3.1基本用法:

from pyquery import PyQuery as pq
doc = pq(stext)
print(doc('ul'))

3.2 通过链接进行初始化

除了直接解析本地HTML代码段之外,还可直接同构链接进行网页内容解析:

from pyquery import PyQuery as pq
doc = pq(url="https://afcentry.cn")
print(doc('title'))

结果:<title>我的技术成长史</title>

3.3 通过本地文件进行初始化

from pyquery import PyQuery as pq
doc = pq(url="de.html")
print(doc('title'))

3.4 选择器说明

Pyquery选择器是基于css选择器来进行节点筛选的,通过‘#’和‘.’来分别指定id和类名进行主区域选择。

例如:

from pyquery import PyQuery as pq
doc = pq(stext)
print(doc('.t0 a'))

含义:获取类包含‘t0’下的a标签节点。

3.5 子节点查找

进行子节点查找时同样使用find()方法,

from pyquery import PyQuery as pq
doc = pq(stext)
print(doc.find(‘li’))

3.6 父节点查询

可通过已知节点.parent()方法获取其父节点:

from pyquery import PyQuery as pq
doc = pq(stext)
item = doc.find(‘li’)

Print(item.parent())

3.7 属性获取

通过attr()方法获取属性

from pyquery import PyQuery as pq
doc = pq(stext)
item = doc.find(‘li’)

3.8 文本获取

通过text()方法获取节点文本

From pyquery import PyQuery as pq

Doc = pq(stext)

A = doc.find(“li” “a”)

Print(A.text())

相关文章:

  • gradle 构建完成自动删除_【翻译】使用Gradle脚本为每次构建自动生成唯一的构建版本号
  • python2转python3代码_python 内置2to3工具将python2代码转换为python3代码
  • python装饰器实现单例模式_Python中的单例模式——装饰器实现剖析
  • python图像边缘检测报告_python数字图像处理(三)边缘检测常用算子
  • jsp value设置为函数的返回值_QT中的消息传递与函数回调机制:信号(signal)和槽(slot)...
  • python exit 0_详解python中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
  • python内置数据结构_python 内置数据结构之列表
  • z变换公式表_小白学物理之狭义相对论(1)——洛伦兹变换
  • python中调用什么模块的什么函数_在Python中如何使用使用其名称(字符串)调用模块的函数...
  • python configparser模块_Python 之ConfigParser模块
  • python的意思是什么_python中**是啥什么意思?
  • 苹果python文件执行怎么运行_Mac下怎么运行python3的py文件
  • java arraylist 初始化_Java集合详解8:Java集合类细节精讲
  • 学生a3制图标题栏尺寸手绘_机械制图基本知识点
  • c语言sort函数_C语言没灵感了?来这18个经典程序里找找吧
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • mysql 数据库四种事务隔离级别
  • python_bomb----数据类型总结
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 漂亮刷新控件-iOS
  • 鱼骨图 - 如何绘制?
  • 做一名精致的JavaScripter 01:JavaScript简介
  • Android开发者必备:推荐一款助力开发的开源APP
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • !!java web学习笔记(一到五)
  • #include<初见C语言之指针(5)>
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (04)odoo视图操作
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (C语言)球球大作战
  • (二)pulsar安装在独立的docker中,python测试
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转载)hibernate缓存
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .naturalWidth 和naturalHeight属性,
  • .NET DataGridView数据绑定说明
  • .net 程序发生了一个不可捕获的异常
  • .NET运行机制
  • .net中我喜欢的两种验证码
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件
  • [C/C++]数据结构----顺序表的实现(增删查改)
  • [CentOs7]图形界面
  • [CISCN2021 Quals]upload(PNG-IDAT块嵌入马)
  • [CSS3备忘] transform animation 等
  • [C语言]——函数递归
  • [Git].gitignore失效的原因
  • [Gym-102091E] How Many Groups