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

python 爬虫 入门 二、数据解析(正则、bs4、xpath)

目录

一、待匹配数据获取

二、正则

三、bs4

(一)、访问属性

(二)、获取标签的值

 (三)、查询方法

 四、xpath

后续:登录和代理


        上一节我们已经知道了如何向服务器发送请求以获得数据,今天我们就来学习如何从获得的数据中找到自己需要的东西,使用数据解析的三种工具:正则、bs4、xpath

一、待匹配数据获取

我们今天来试试国家数据网页,尝试获取下面这个框里面所有链接的url。

        我们先右键网页,查看页面源代码(ps:F12元素里面的代码是网页的实时代码,和源代码有差异。)然后Ctrl+F搜索: 2020年投入产出表,可以看到有结果,前面的超链接就是我们需要的url。这表明数据是直接在网页源码中的,而不是通过脚本二次请求服务器生成的,可以直接通过页面源码找到。

接下来,使用上一节的代码来获取页面源代码。

import requestsurl = "https://data.stats.gov.cn/"
headers = {# 用户代理,某些网站验证用户代理,微微改一下,如果提示要验证码之类的,使用它"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
}
with requests.get(url=url, headers=headers,) as resp:resp.encoding = "utf-8"print(resp)with open("国家数据.html", mode="w",encoding="utf-8") as f:f.write(resp.text)  # 读取到网页的页面源代码"

 我们下面的操作就只读取下载的html文件,而不反复请求服务器。

二、正则

        使用正则表达式来匹配数据在很多python基础中都有,速度快,能适应复杂的需求,但是复杂的正则表达式不好写,难维护,容易出错。不过那些大语言模型写正则是一把好手。这里主要爬虫,关于正则表达式,给几个表看一看,用用就会了。这里贴一下python文档链接和几个表以待后续查看:正则表达式指南 — Python 3.11.10 文档

import re  # 正则

findall()

以列表形式返回所有满足数据,没有返回空列表

finditer()

返回所有匹配结果的迭代器,建议使用for+group提取

search()

返回第一个匹配结果的match对象,使用group提取,没有返回None

match()

从头开始匹配,返回match对象。

相当于在正则表达式前面加了^,没有返回None

compile()预加载正则表达式

量词

意义

*

0~∞次

+

1~∞次

?

0~1次

{n}

n次

{n,}

n~∞次

{n,m}

n~m次

元字符意义
.换行符以外任意字符
\w字母数字下划线
\s空白字符(空格 换行符 制表符)
\d数字
\W非字母数字下划线
\S非空白字符
\D非数字
\n换行符
\t制表符
^字符串开始
$字符串结尾
a|b字符a或字符b
()匹配括号内的表达式
[abc]匹配字符a或b或c
[^abc]匹配除了a、b、c的字符
规则意义
re.I忽略大小写
re.L不建议使用,改用re.U
re.M多行匹配
re.S令 . 可以匹配换行符
re.U使用unicode字符集
re.X忽略匹配表达式中的空白符和#,除非加\,令你可以在正则表达式中加注释

        一个小细节,.*会贪婪匹配,越多越好,.*?会非贪婪匹配越少越好

        好,基础知识都在上面,现在我们来尝试匹配网页吧。 通过在网页中查看,我们发现需要获取的url前后有<li><a href="和.+产出表</a><span>,所以我们可以根据这一点来写正则表达式,最终形成如下代码:

import re
path = "国家数据.html"
with open(path,mode="r", encoding="utf-8") as f: # 下载源码data = f.read()
regular = re.compile(r'<li><a href="(?P<url>.*)">(?P<year>.*)投入产出表</a><span>')
result_1 = regular.findall(data)
result_2 = regular.finditer(data)
result_3 = regular.search(data)
result_4 = regular.match(data)
print(result_1)
for i in result_2:print(i.group())print(i.group("url"))print(i.group("year"))
print(result_3.group())
print(result_4)

         这里面()划定了一个组,而?P<name>给组起了一个名字,结果如下:

         finditer返回的迭代器是我最常用,也是我觉着最好用的。

三、bs4

        bs4全称beautifulsoup4。它主要是创建解析树,用来导航、搜索、修改HTML和XML文档,效率可能比其他的略低,但比较健壮,不易出错。

from bs4 import BeautifulSoup  # bs

        基础用法就是先使用  bs = BeautifulSoup(data, "html.parser")  将html代码交给bs4处理为树形结构,然后在得到的bs对象中查找需要的数据。

        处理后数据是一个BeautifulSoup,即文档,文档中有许多tag(标签),标签也能够包含标签,就像上图的<div>、<a>、<li>一样。我们可以通过bs.ul来访问第一个ul标签。有的标签具有属性,像是最外层的div标签就有id属性、第一个a有href属性一样。可以像是访问字典一样,通过bs.ul.li.a["href"]或者bs.ul.li.a.get("href")来访问属性的值。如果属性有多个值或者属性名字为class,会返回列表。

除了tag以外,还有NavigableString(标签的值)以及Comment(注释和特殊字符串),标签的值一般是字符串,字符串中无法包含其他标签,同时无法编辑,只能替换。可以通过.string.text获取标签的字符串。若标签内非字符串,第一种返回None,第二种会将内容转化为纯文本输出

我们要筛查的话,可以使用find()或者find_all()方法来的到一个对象或者所以符合要求的对象,

find_all比find只多了一个limit参数,其他的参数相同

 好,总结一下。

(一)、访问属性

标签["属性名"]

标签("属性名")

class返回列表,其他的返回字符串

(二)、获取标签的值

.string                        空返回None

.text                            返回内容纯文本

 (三)、查询方法

find(name , attrs , recursive , string)       

find_all(name , attrs , recursive , string, limit)

标签名,属性名和属性值(class_特殊),搜索全部子孙节点,字符串内容,最大返回数

        除此之外,还有css选择器,但我没看,觉得不够用的可以再去学习一下。

        利用上述知识,我们可以使用下面代码获得所需数据了:

from bs4 import BeautifulSoup  # bspath = "国家数据.html"
with open(path, mode="r", encoding="utf-8") as f:  # 下载源码data = f.read()
bs = BeautifulSoup(data, "html.parser")  # html代码交给bs处理'
ul = bs.find("ul", class_="active clearfix")  # 查找标签名为ul,属性class值为”active clearfix“的tag
data = ul.find_all("a")  # 查找所有a标签
for i in data:print(i["href"], i.string)

 很简短,不是吗。

 四、xpath

        这东西比bs快点,而且有开发工具加持,能够精准定位。它和bs4挺像的,是一种专门用于XML文档定位和选择节点的语言。但用起来也挺难,这里说点简单的先用上。

from lxml import etree        # 导入

        xpath的节点就像是上面的tag,树形结构,跟文件夹似的,使用etree.HTML(data)来处理数据。

        首先是xpath支持路径表达式,和我们常见的文件路径相似:

/根节点开始
//不考虑位置
.当前节点
..父节点
@选取属性
*通配符,任何
|
nodename所有子节点
text()获取文本

        我们可以通过.xpath来执行路径表达式。比如还是上文中的登录部分,我们想获取登录的文本,可以使用tree.xpath("/html/body/div[2]/div/div/ul/li[1]/a/text()")来得到结果,什么?很长,长就对了,这就就不是给人数的。(注意,它的下标从1开始)

        这就要说到上面的开发工具加持了,打开开发工具的元素页面,右键需要的元素,就能够直接复制元素的Xpath地址了。

        我们再来看看这条代码:tree.xpath("//*[@id='top']/div/div/ul/li[1]/a/text()")照样能找到位置,它用了谓语表达式,[@id='top']代表标签有个叫id的属性,值为'top',还能写出一些其他的谓语表达式,比如[last()]表示最后一个节点,[text()="登录"]选择文本为登录的节点,[id>1]选择id值大于1的节点等。

        xpath还有一些接口:

xpath()路径表达式获取节点列表
find()查第一个匹配的节点
findall()查所有匹配节点
text获取文本内容
attrib获取节点属性

        好的,现在我们开始获取所需数据吧,要获得想要元素的位置,一点点找太麻烦了,我们可以使用左上角的检查工具,然后鼠标移动到所需的数据上,就能知道这个数据是从哪段代码中显示的了。

from lxml import etreepath = "国家数据.html"
with open(path, mode="r", encoding="utf-8") as f:  # 下载源码data = f.read()
tree = etree.HTML(data)
ul1 = tree.xpath("/html/body/div[6]/div[3]/div[2]/div[2]/ul[1]")[0]
ul2 = tree.xpath('//ul[@class="active clearfix"]')[0]
print(ul1 == ul2)
out_data = ul1.xpath('./li/a')
print(out_data == ul1.findall("li/a"))
print(out_data == tree.xpath('//ul[@class="active clearfix"]//a'))
for i in out_data:print(i.attrib["href"],i.text)

方法很多,选种喜欢的用就行。 

注意上面获得的url前面拼接上原网址才是完整url。

后续:登录和代理

改天写如何处理登录以及代理,详情见三、登录以及代理。

相关文章:

python 爬虫 入门 二、数据解析(正则、bs4、xpath)

目录 一、待匹配数据获取 二、正则 三、bs4 &#xff08;一&#xff09;、访问属性 &#xff08;二&#xff09;、获取标签的值 &#xff08;三&#xff09;、查询方法 四、xpath 后续&#xff1a;登录和代理 上一节我们已经知道了如何向服务器发送请求以获得数据&#x…...

PTX 汇编代码语法

PTX&#xff08;Parallel Thread Execution&#xff09;汇编是 NVIDIA 为其 GPU 提供的一种并行指令集架构&#xff08;ISA&#xff09;&#xff0c;用于编写 GPU 设备代码。PTX 是一种中间表示&#xff08;IR&#xff09;&#xff0c;在 CUDA 代码编译时生成&#xff0c;之后会…...

【mysql】统计两个相邻任务/事件的间隔时间以及每个任务的平均用时

准备步骤1. 设置查询参数部分1.1 设置需要分析的起始时间1.2. 设置需要分析的时间的长度&#xff08;分析的结束时间&#xff09;1.3. 设置分析内容1.4. 设置需要分析的表和字段 2. 自动计算分析2.1 设置起始序号2.2. 筛选user_log表数据并生成带序号的临时表temp_ria2.3. 通过…...

RHCE——笔记

第一章——例行性工作 1&#xff1a;单一致性的例行性工作 仅处理执行一次就结束 at命令 /etc/at.allow —— 写在该文件的人可以使用at命令 /etc/at.deny —— 黑名单 两个文件都不存在&#xff0c;则只有root可以使用 #at工作调度对应的系统服务 [rootlocalhost ~]# p…...

Spring Boot在知识管理中的应用

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…...

OpenCV高级图形用户界面(14)交互式地选择一个或多个感兴趣区域函数selectROIs()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 允许用户在给定的图像上选择多个 ROI。 该函数创建一个窗口&#xff0c;并允许用户使用鼠标来选择多个 ROI。控制方式&#xff1a;使用空格键或…...

字节青训营入营考核部分题解

​ 题库链接&#xff1a;https://juejin.cn/problemset?utm_sourceschool&utm_mediumyouthcamp&utm_campaignexamine 1. 计算从x到y的最小步数 问题描述 AB 实验同学每天都很苦恼如何可以更好地进行 AB 实验&#xff0c;每一步的流程很重要&#xff0c;我们目标为了…...

Android调用系统打印图片

拍摄和分享照片是移动设备最受欢迎的用途之一。如果您的应用 拍摄照片、展示照片或允许用户分享图片&#xff0c;则应考虑启用打印功能 和图片。Android 支持库提供了一个便捷的功能&#xff0c;支持使用 只需编写极少的代码和一组简单的打印版式选项。 本节课介绍如何使用 v4…...

网络最快的速度光速,因此‘‘光网络‘‘由此产生

世界上有一种最快的速度又是光,以前传统以太网络规划满足不了现在的需求。 一 有线网规划 二 无线网规划...

WPF -- LiveCharts的使用和源码

LiveCharts 是一个开源的 .NET 图表库&#xff0c;特别适用于 WPF、WinForms 和其他 .NET 平台。它提供了丰富的图表类型和功能&#xff0c;使开发者能够轻松地在应用程序中创建动态和交互式图表。下面我将使用WPF平台创建一个测试实例。 一、LiveCharts的安装和使用 1.安装N…...

spring 如何将mutipartFile转存到本地磁盘

两者的区别和联系 MutipartFile是spring的一部分&#xff0c;File则是java的标准类MutipartFile用于接收web传递的文件&#xff0c;File操作本地系统的文件 MutipartFile 转换File的三种方式 使用MutipartFile 自带的transferTo方法使用java自带的FileOutPutStream流使用java自…...

【学术会议-6】激发灵感-计算机科学与技术学术会议邀您参与,共享学术盛宴,塑造明天的科技梦想!

【学术会议-6】激发灵感-计算机科学与技术学术会议邀您参与&#xff0c;共享学术盛宴&#xff0c;塑造明天的科技梦想&#xff01; 【学术会议-6】激发灵感-计算机科学与技术学术会议邀您参与&#xff0c;共享学术盛宴&#xff0c;塑造明天的科技梦想&#xff01; 文章目录 【…...

模电基础(晶体管放大电路)

1.放大电路 1.1基本共射放大电路工作原理 1.1.1电路的组成和作用 各器件的作用 ​​​​​​&#xff08;1&#xff09;&#xff08;交流电源&#xff09;&#xff1a;输入电路的有用信号&#xff0c;也就是我们需要去放大的信号 &#xff08;2&#xff09;&#xff08;反馈…...

Python3 接口自动化测试,HTTPS下载文件(GET方法和POST方法)

Python3 接口自动化测试,HTTPS下载文件(GET方法和POST方法) requests-pkcs12 PyPI python中如何使用requests模块下载文件并获取进度提示 1、GET方法 1.1、调用 # 下载客户端(GET)def download_client_get(self, header_all):try:url = self.host + "/xxx/v1/xxx-mod…...

rhce:列行性(at和cron)

配置 at练习 设置时间提醒 定义一分钟后显示命令&#xff0c;使用atq查看 cron练习 配置 systemctl status crond 查看文件所在位置 ll /var/spool/cron/ 主要功能 开始操作 进入界面操作每天早上9点说hello crontab -e 五个星号分别代表分时日月周&#xff0c;其次是执…...

kubernetes给service动态增加服务端口

根据kubernetes官方文档的说明&#xff0c;service的ports规则支持merge操作&#xff1a; portsServicePort arraypatch strategy: mergepatch merge key: portThe list of ports that are exposed by this service. More info: https://kubernetes.io/docs/concepts/services-…...

如何将 html 渲染后的节点传递给后端?

问题 现在我有一个动态的 html 节点&#xff0c;我想用 vue 渲染后&#xff0c;传递给后端保存 思路 本来想给html的&#xff0c;发现样式是个问题 在一个是打印成pdf&#xff0c;然后上传&#xff0c;这个操作就变多了 最后的思路是通过 html2canvas 转化成 canvas 然后变成…...

ubuntu24 finalshell 无法连接ubuntu服务器, 客户端无法连接ubuntu, 无法远程连接ubuntu。

场景&#xff1a; 虚拟机新创建一个最小化的ubuntu服务器&#xff0c;使用finalshell连接服务&#xff0c;发现连接不上。 1. 查看防火墙ufw 是否开启&#xff0c;22端口是否放行 2. 查看是否安装openssh server, 并配置 我的问题是安装了openssh server 但是没有配置root可…...

牛客编程初学者入门训练——BC19 牛牛的对齐

BC19 牛牛的对齐 描述 读入 3 个整数&#xff0c;牛牛尝试以后两个数字占 8 个空格的宽度靠右对齐输出。 输入描述&#xff1a; 输入三个整数&#xff0c;用空格隔开。 输出描述&#xff1a; 输出 3 个整数以第二三个数字占 8 个空格靠右对齐输出 示例1 输入&#xff1a…...

log file sync 内部执行过程

通常oracle的log file sync执行大致印象是等待cpu、log file parallel write、等待cpu&#xff0c;遇到问题主要考虑lgwr自适应模式参数要关闭、io性能、cpu瓶颈、归档数量和大小等&#xff0c;但是内部执行内容其实很多&#xff0c;尤其是有ADG了以后。 log file sync主要执行…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...