【自用】Python爬虫学习(二):网页解析的三种方式(re、bs4、xpath)

embedded/2024/10/9 7:58:21/

Python爬虫学习(二)

  • 网页解析的三种方式
    • 1.正则表达式-re解析
      • 常用表达:
      • re常用函数:
      • 在html中的运用:
    • 2.BeautifulSoup解析
      • 常用语法:
      • 用法举例:
    • 3.xpath解析
      • 示例代码1:
      • 示例代码2:


网页解析的三种方式

1.正则表达式-re解析

常用表达:

正则表达式常用字符:
===============常用元字符:===============
.       匹配除换行符以外的任意字符
\w      匹配字母或数字或下划线
\s      匹配任意的空白符
\d      匹配数字
\n      匹配一个换行符
\t      匹配一个制表符^       匹配字符串的开始
$       匹配字符串的结尾\W      匹配非字母或数字或下划线
\D      匹配非数字
\S      匹配非空白符a|b     匹配字符a或字符b
()      匹配括号内的表达式,也表示一个组
[...]   匹配字符组中的字符
[^...]  匹配除了字符组中字符的所有字符===============量词:控制前面的元字符出现的次数===============
*       重复零次或更多次
+       重复一次或更多次
?       重复零次或一次
{n}     重复n次
{n,}    重复n次或更多次
{n,m}   重复n到m次===============贪婪匹配和情性匹配===============
.*      贪婪匹配
.*?     情性匹配

re常用函数:

python">import re# re.findall(正则表达式,字符串),:匹配字符串中所有的符合正则的内容,返回的结果是一个列表
print("===============findall():===============")
lis = re.findall(r'\d+', '我的电话号码是10086,小明的电话是10010')
print(lis)
# ['10086', '10010']# finditer():匹配字符串中所有的内容【返回的是选代器】,从迭代器中拿到内容需要:group(),效率更高
print("===============finditer():===============")
it = re.finditer(r'\d+', "我的电话号是:10086,小明的电话是:10010")
for i in it:print(i.group())
# 10086
# 10010# search()找到一个结果就返回,返回的是match对象,拿数据需要.group()
print("===============search():===============")
s = re.search(r'\d+', "我的电话号是:10086,小明的电话是:10010")
print(s.group())
# 10086# match是从头开始匹配
print("===============match():===============")
m = re.match(r'\d+', "10086,小明的电话是:10010")
print(m.group())
# 10086# 预加载正则表达式
print("===============预加载正则表达式:===============")
obj = re.compile(r"\d+")
ret = obj.finditer("我的电话号是:10085,小明的电话是:10000")
for it in ret:print(it.group())
# 10085
# 10000

在html中的运用:

python">import retext = """
<div class='jay'><span id='1′>郭某某</span></div>
<div class='jj'><span id='2′>宋某某</span></div>
<div class='jolin'><span id='3′>李某某</span></div>
<div class='sylar'><span id='4′>范某某</span></div>
<div class='tory'><span id='5′>刘某某</span></div>"""
# (?P<分组名字>正则)可以单独从正则匹配的内容中进一步提取内容,re.S的作用是让.能匹配换行符
obj = re.compile(r"<div class='.*?><span id='(?P<num>\d+)′>(?P<name>.*?)</span></div>", re.S)result = obj.finditer(text)
for it in result:print(it.group())# <div class ='jay' > < span id='1′>郭某某</span></div>print(it.group('name'))# 郭某某print(it.group('num'))# 1

2.BeautifulSoup解析

常用语法:

"""
-如何实例化BeautifulSoup对象:-from bs4 import BeautifulSoup-对象的实例化:-1.将本地的htmL文档中的数据加载到该对象中fp=open('./test.html','r',encoding='utf-8')soup=BeautifulSoup(fp,'lxml')2.将互联所网上获取的页面源码加载到该对象中page_text=response.textsoup=BeautifulSoup(page_text,'lxml')-提供的用于数据解析的方法和属性:-soup.tagName:返回的是文档中第一次出现的tagName对应的标签-soup.find():-find('tagName'):等同于soup.div-属性定位-soup.find('div',class_/id/attr='song')-soup.find_all('tagName'):返回符合要求的所有标签(列表)-select:-select('某种选择器(id,class,标签……选择器)'),返回的是一个列表。-层级选择器:-soup.select('.tang>ul>li>a'):>表示的是一个层级-soup.select('.tang>ul a'):空格表示的多个层级-获取标签之间的文本数据:-soup.a.text/string/get_text()-text/get_text():可以获取某一个标签中所有的文本内容-string:只可以获取该标签下面直系的文本内容·-获取标签中属性值:-soup.a['href']"""

用法举例:

python">import requests
from bs4 import BeautifulSoupurl = ''
hearders = {'User-Agent': ''
}
resp = requests.get(url=url, headers=hearders)
# 对象的实例化
soup = BeautifulSoup(resp.text, 'lxml')
# 标签定位
# 返回的是文档中第一次出现的tagName对应的标签
div_first1 = soup.find('div')
div_first2 = soup.div
# div_first1与div_first2效果一样# 属性定位
# 写法1,添加下划线'class_'规避关键字class
soup.find('div', class_='song')
# 写法2,写成字典形式
soup.find('div', attrs={"class": "song"})# 返回符合要求的所有标签(列表)
soup.find_all('tagName')# 层级选择器,返回的是一个列表
# >表示的是一个层级
soup.select('.tang > ul > li > a')
# 空格表示的多个层级
soup.select('.tang > ul a')# 获取标签之间的文本数据
"""
……
<div><p>段落</p>内容测试<a href='www.baidu.com'>百度</a><a href='www.bing.com'>必应</a>
</div>
……
"""
# 可以获取某一个标签中所有的文本内容
div_text1 = soup.div.text  # 结果包含:段落 内容测试 百度 必应
div_text2 = soup.div.get_text()  # 结果包含:段落 内容测试 百度 必应# 只可以获取该标签下面直系的文本内容
# <a href='wwww.baidu.com'>百度</a>
a_text3 = soup.a.string  # 百度# 获取标签中属性值:
# 获取<a href='wwww.baidu.com'>百度</a>中的href链接文本
# 方法1
web_links = soup.a['href']  # wwww.baidu.com
# 方法2
web_page = BeautifulSoup(resp.text, "html.parser")
div_list = web_page.find('div', class_='big-pic')
image_src = div_list.find('img').get('src')  # 用get拿到标签的对应属性

3.xpath解析

示例代码1:

python">from lxml import etreexml = """
<book><id>1</id><name>野花遍地香</name><price>1.23</price><nick>臭豆腐</nick><author><nick id="10086">周大强</nick><nick id="10010">周芷若</nick><nick class="joy">周杰伦</nick><nick class="jolin">蔡依林</nick><div><nick>惹了1</nick></div><span><nick>惹了2</nick><div><nick>惹了3</nick></div></span></author><partner><nick id="ppc">胖胖陈</nick><nick id="ppbc">胖胖不陈</nick></partner></book>"""tree = etree.XML(xml)
# result = tree.xpath("/book")
result = tree.xpath("/book/name/text()")  # ['野花遍地香']
# -/text()取的是标签中直系的文本内容;//text()标签中非直系的文本内容(所有的文本内容)result = tree.xpath("/book/author/nick/text()")
# ['周大强', '周芷若', '周杰伦', '蔡依林']
result = tree.xpath("/book/author/div/nick/text()")
# ['惹了1']
result = tree.xpath("/book/author//nick/text()")
# ['周大强', '周芷若', '周杰伦', '蔡依林', '惹了1', '惹了2', '惹了3']
result = tree.xpath("/book/author/*/nick/text()")
# *任意的节点,通配符,['惹了1', '惹了2']result = tree.xpath("/book//nick/text()")
# ['臭豆腐', '周大强', '周芷若', '周杰伦', '蔡依林', '惹了1', '惹了2', '惹了3', '胖胖陈', '胖胖不陈']print(result)

示例代码2:

"Test.html"文件内容如下所示:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Title</title>
</head>
<body>
<ul><li><a href="http://www.baidu.com">百度</a></li><li><a href="http://www.google.com">谷歌</a></li><li><a href="http://www.sogou.com">搜狗</a></li>
</ul>
<ol><li><a href="feiji">飞机</a></li><li><a href="dapao">大炮</a></li><li><a href="huoche">火车</a></li>
</ol><div class="job">李嘉诚</div>
<div class="common">胡辣汤</div></body>
</html>
python">from lxml import etree# 读取Test.html文件
tree = etree.parse("Test.html")
result = tree.xpath('/html')result1 = tree.xpath("/html/body/ul/li/a/text()")
# ['百度', '谷歌', '搜狗']
print(result1)# 注意这里的xpath的索引是从1开始的,li[1]代表取第一个,[]中数字代表索引
result2 = tree.xpath("/html/body/ul/li[1]/a/text()")
# ['百度']
print(result2)result3 = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")
# ['大炮']
print(result3)ol_li_list = tree.xpath("/html/body/ol/li")for li in ol_li_list:# 从每一个1i中提取到文字信息result = li.xpath("./a/text()")  # 在li中继续去寻找,相对查找,注意用./print(result)# 拿到属性值:@属性值result2 = li.xpath("./a/@href")  # 在li中继续去寻找,获取到属性href的值print(result2)print(tree.xpath("/html/body/ul/li/a/@href"))
# ['http://www.baidu.com', 'http://www.google.com', 'http://www.sogou.com']print(tree.xpath("/html/body/div/text()"))
# ['李嘉诚', '胡辣汤']

http://www.ppmy.cn/embedded/96325.html

相关文章

Eureka原理实践

Eureka是Netflix开源的服务发现框架&#xff0c;它实现了服务的注册与发现&#xff0c;是微服务架构中不可或缺的一部分。在微服务架构中&#xff0c;服务实例会动态地注册和注销&#xff0c;因此需要一个服务注册中心来管理这些服务实例的信息&#xff0c;Eureka就承担了这个角…

[Qt][Qt 文件]详细讲解

目录 1.输入输出设备类2.文件读写类3.文件和目录信息类 1.输入输出设备类 在Qt中&#xff0c;⽂件读写的类为QFile&#xff0c;其⽗类为QFileDevice QFileDevice提供了⽂件交互操作的底层功能QFileDevice的⽗类是QIODevice&#xff0c;其⽗类为QObject QIODevice是Qt中所有I/O…

RabbitMq如何确保消息不丢失

问题&#xff1a;在生产环境中由于一些不明原因&#xff0c;导致 rabbitmq 重启&#xff0c;在 RabbitMQ 重启期间生产者消息投递失败&#xff0c;导致消息丢失&#xff0c;需要手动处理和恢复。于是&#xff0c;我们开始思考&#xff0c;如何才能进行 RabbitMQ 的消息可靠投递…

Springboot 集成websocket 并支持服务集群

1、新增配置类声明 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;Configuration public class WebsocketConfig {/***…

01_理解网络编程和套接字

1.服务端 1.创建套接字 #include <sys/socket.h> int socket(int domain, int type, int protocol); // 成功时返回文件描述符&#xff0c;失败时返回-1&#xff1b; 2.套接字分配地址&#xff08;IP和端口号) #include <sys/socket.h> int bind(int sockfd, s…

基于javaEE的校园二手书交易平台的设计与实现

TOC springboot287基于javaEE的校园二手书交易平台的设计与实现 第1章 绪论 1.1 研究背景 互联网概念的产生到如今的蓬勃发展&#xff0c;用了短短的几十年时间就风靡全球&#xff0c;使得全球各个行业都进行了互联网的改造升级&#xff0c;标志着互联网浪潮的来临。在这个…

希尔排序,详细解析(附图解)

1.希尔排序思路 希尔排序是一种基于插入排序的算法&#xff0c;通过将原始数据分成若干个子序列&#xff0c;然后对子序列进行插入排序&#xff0c;逐渐减小子序列的间隔&#xff0c;最后对整个序列进行一次插入排序。 1.分组直接插入排序&#xff0c;目标接近有序--------…

wiota窄带通讯技术对于vu传统lora

WIoTa是一种针对广域无线物联网通信优化设计的通信协议&#xff0c;而LoRa则是一种广泛应用的低功耗广域网技术。两者在物联网领域都有广泛的应用&#xff0c;但它们在多个关键性能指标上存在显著差异。以下是从多个角度对WIoTa和LoRa进行详细对比&#xff1a; 覆盖范围 WIoTa…