Python爬虫3-数据解析方法:正则表达式介绍及案例

news2024/11/15 12:42:16

目录标题

      • 1、正则表达式介绍
        • re库的主要功能函数
        • Re库的match对象
        • Re库的贪婪匹配和最小匹配
      • 2、正则表达式案例
        • 案例1:所有图片爬取
        • 案例2:分页爬取
        • 案例3:淘宝商品信息
        • 案例4:股票数据

1、正则表达式介绍

正则表达式re:简洁表达一组字符串的表达式。通用的字符串表达框架
优势:简洁
正则表达式在文本处理中十分常用

常用操作符:
在这里插入图片描述
在这里插入图片描述
Re库
正则表达式的表示类型:
1,raw string 类型(原生字符串类型)–不含有转义字符串
2,string类型,\会理解为转义符,更繁琐

re库的主要功能函数

在这里插入图片描述
re.search()
在这里插入图片描述
在这里插入图片描述
search例子:

import re
match = re.search(r"[1-9]\d{5}","BIT 10081") #邮政编码
if match:
	print(match.group(0))  #返回10081

re.match()
在这里插入图片描述

import re
match = re.match(r"[1-9]\d{5}","BIT 10081")
if match: #判断是否为空
	match.group(0) #输出10081

re.findall()
在这里插入图片描述

import re
ls = re.findall(r"[1-9]\d{5}","BIT 10081 TSU10084")
print(ls)  #输出:10081,10084

re.split()
在这里插入图片描述

import re
re.split(r"[1-9]\d{5}","BIT 10081 TSU10084") #输出:['BIT','TSU','']
#将一个正则表达式去匹配字符串,匹配的部分去掉,去掉之后的元素作为分割的字符串元素放在一个列表里

re.split(r"[1-9]\d{5}","BIT 10081 TSU10084",maxsplit =1) #输出['BIT','TSU10084']
#maxsplit =1造成只匹配第一个

re.finditer()

在这里插入图片描述

import re
for m in re.finditer(r"[1-9]\d{5}","BIT 10081 TSU10084"):
	if m:
		print(m.group(0)) 

#输出:
10081
10084
#迭代的获取每一个匹配的结果,并对其进行单独的处理

re.sbu()
在这里插入图片描述

import re
re.sub(r"[1-9]\d{5}",":zipcode","BIT 10081 TSU10084")
#输出:BIT :zipcode TSU:zipcode   即将匹配到的内容进行替换

re库的两种使用方法:
在这里插入图片描述
在这里插入图片描述

re.compile()
在这里插入图片描述
在这里插入图片描述

Re库的match对象

match对象:一次匹配的结果

import re
match = re.search(r"[1-9]\d{5}","BIT 10081")
if match:
	print(match.group(0)) #输出10081

type(match) #输出: <class '_sre.SRE_Match'>

Match对象的属性:
在这里插入图片描述
match对象常用方法:
在这里插入图片描述
在这里插入图片描述

group(0)只返回第一次匹配后的结果,要全部匹配结果,使用finditer()函数

Re库的贪婪匹配和最小匹配

Re库默认采用贪婪匹配,输出匹配最长的字串

match = re.search(r"py.*n",'pyanbncndn') #'pyan','pyanbn'等等都符合要求
match.group(0) #输出:'pyanbncndn'

如何输出最短的字串?–加一个?问号

match = re.search(r"py.*?n",'pyanbncndn') #'pyan','pyanbn'等等都符合要求
match.group(0) #输出:'pyanbncndn'

最小匹配操作符
在这里插入图片描述

2、正则表达式案例

案例1:所有图片爬取

需求:单一图片的加载和存储

#实现:单一图片的加载和存储
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
if __name__ == "__main__":
    #每个图片有对应的地址请求
    url = 'https://p0.ssl.img.360kuai.com/t013fed37710ef441ad.webp' #图片地址
    #content返回的是二进制形式的图片
    #text(字符串) content(二进制) json(对象)
    img_data= requests.get(url=url).content

    with open('./giutu.jpg','wb') as fp:
        fp.write(img_data)	

需求::糗事百科页面下的所有图片

#实现:糗事百科页面下的所有图片
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import re
import os
if __name__ == "__main__":
    #创建一个文件夹,保存所有的图片
    if not os.path.exists('./giutuLibs'):
        os.mkdir('./giutuLibs')
    #每个图片有对应的地址请求
    url = 'https://www.qiushibaike.com/pic/'  #网站打不开了所以没有结果
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    #使用通用爬虫对url对应的一整张页面进行爬取
    page_text = requests.get(url=url,headers=headers).text
    #使用聚焦爬虫
    ex = '<div class="thumb">.*?<img src="(.*?)"all.*?</div>'
    img_src_list = re.findall(ex,page_text,re.S)
    for src in img_src_list:
        src = 'https:'+src
        img_data = requests.get(url=src,headers=headers).content
        #生成图片名称(从图片地址的最后一部分作为名称)
        img_name = src.src.split('/')[-1]
        #图片存储的路径
        imgpath = './giutuLibbs'+img_name
        with open(imgPath,'wb') as fp:
            fp.write(img_data)
            print(img_name,'下载成功!')

案例2:分页爬取

上例中只爬取了第一页的图片,这次我们需要实现分页功能

#实现:糗事百科页面下的所有图片
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import re
import os
if __name__ == "__main__":
    #创建一个文件夹,保存所有的图片
    if not os.path.exists('./giutuLibs'):
        os.mkdir('./giutuLibs')
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    #每个图片有对应的地址请求
    #设置一个通用的url模板
    url = 'https://www.qiushibaike.com/pic/page/%d/?s=5184961' #%d要替换成具体的数
    #pageNum=2
    #取前两页
    for pageNum in range(1,3):
        #new_url是对应页码的url
        new_url = format(url%pageNum) #pageNum会替换%d部分

        #使用通用爬虫对url对应的一整张页面进行爬取
        page_text = requests.get(url=url,headers=headers).text
        #使用聚焦爬虫
        ex = '<div class="thumb">.*?<img src="(.*?)"all.*?</div>'
        img_src_list = re.findall(ex,page_text,re.S)
        for src in img_src_list:
            src = 'https:'+src
            img_data = requests.get(url=src,headers=headers).content
            #生成图片名称(从图片地址的最后一部分作为名称)
            img_name = src.src.split('/')[-1]
            #图片存储的路径
            imgpath = './giutuLibbs'+img_name
            with open(imgPath,'wb') as fp:
                fp.write(img_data)
                print(img_name,'下载成功!')

不同页面的url只有一个页数部分不同,其他地方都一样,所以加个循环替换掉不同的地方即可

案例3:淘宝商品信息

目标:获取淘宝搜索页面的信息,提取其中的商品名称和价格
在这里插入图片描述
步骤:
1,提取商品搜索请求,

import requests
import re
def getHTMLText(url):#获得页面
	try:
		r = requests.get(url,timeout=30)
		r.raise_for_status()
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return " "
def parsePage(ilt,html): #对每个页面进行解析 ,参数:结果的列表ilt和HTML信息
	#在查询过后发现,商品价格前面有一个参数view_price,名称前raw_title
	#异常处理很重要,保证了出现问题时不会异常退出
	try:
		plt = re.findall(r'\"view_price\"\:"[\d\.]*\"',html)
		tlt = re.findall(r'\"raw_title\"\:\".*?\"',html)
		for i in range(len(plt)):
			price = eval(plt[i].split(':')[1]) #按:分割后取后面的数值
			title = eval(tlt[i].split(':')[1])
			ilt.append([price,title])
		except:
			print("")
def printGoodsList(ilt):  #商品信息输出
	tplt = "{:4}\t{:8}\t{:16}"
	print(tplt.format("序号","价格","商品名称"))
	count = 0
	for g in ilt:
		count = count+1
		print(tplt.format(count,g[0],g[1]))
	
def main():  #主函数
	goods = "书包"
	depth = 2 #只爬取当前页和下一页
	start_url = "https://s.taobao.com/scarch?q="+goods
	infoList = [] #存储输出结果
	for i in range(depth):
		try:
			url = start_url + '&s='+str(44*i) #有一个参数s,第一页为0,第二页44,后面44的倍数
			html = getHtMLText(url)
			parsePage(infoList,html)
		except:
			continue  #如果出现问题,进入下一个循环
	printGoodsList(infoList)
	
main()	

在这里插入图片描述

案例4:股票数据

目标:获取上交所和深交所所有股票名称和交易信息,并保存到文件中
需要找到能获取股票的网站,网站也有要求:股票信息静态存在于HTML中,非js代码生成,没有robots协议限制

步骤:
1,获取股票列表
2,逐个股票信息
3,存储到文件中

import requests
from bs4 import BeautifulSoup
import traceback
import re
def getHTMLText(url):#获得url对应页面
	try:
		r = requests.get(url,timeout=30)
		r.raise_for_status()
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return " "

def getStockList(lst,stockURL): #获得股票的信息列表,参数:列存储表,url网站
	html = getHTMLText(stockURL)
	soup = BeautifulSoup(html,'html.parser')
	a = soup.find_all('a')#查看代码后,发现信息在a标签下
	for i in a:
		try:
			href = i.attrs['href']
			lst.append(re.findall(r"[s][hz]\d{6}",href[0]))
		except:
			continue

def getStockInfo(lst,stockURL,fpath): #获取每个股票的信息,并存储在文件中,参数fpath文件路径
	for stock in lst:
		url = stockURL +stock+'.html'
		html = getHTMLText(url)
		try:
			if html == "":
				continue
			infoDict = {}
			soup = BeautifulSoup(html,'html.parser')
			stockInfo = soup.find('div',attrs={'class':'stock-bets'})
            name = stockInfo.find_all(attrs={'class':'bets-name'})[0]
            infoDict.update({'股票名称': name.text.split()[0]})
            keyList = stockInfo.find_all('dt')
            valueList = stockInfo.find_all('dd')
            for i in range(len(keyList)):
                key = keyList[i].text
                val = valueList[i].text
                infoDict[key] = val
            
            with open(fpath, 'a', encoding='utf-8') as f:
                f.write( str(infoDict) + '\n' )
        except:
            traceback.print_exc()
            continue

def main():
	stock_list_url = "http://quote.eastmoney.com/stocklist.html" #获取股票的
	stock_info_url = 'https://gupiao.baidu.com/stock/'
	outer_file = 'D://BaiduStockInfo.txt' #输出信息保存路径
	slist = []
	getStockList(slist,stock_info_url)
	getStockInfo(slist,stock_info_url,outer_file)
main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/193180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PCIe设备的配置过程

PCIe设备的配置过程 文章目录PCIe设备的配置过程参考资料&#xff1a;一、 PCIe系统硬件结构二、 PCIe系统软件层次三、事务层TLP格式3.1 Posted和Non-Posted3.2 TLP通用格式3.3 TLP头部四. 配置与RC直连的设备4.1 怎么访问直连的设备4.2 配置EendPoint五、 配置示例5.1 必备知…

PPT绘图笔记2:PPT导出图片结合ps处理图片

ppt导出的图片有透明背景怎么办&#xff1f;我使用的是组合图。 一开始以为是我的分辨率不行&#xff0c;按照官网的说明在注册表上进行修改1。 然后我在查资料的时候在B站看到一个方法可以用ps填充白色背景&#xff0c;并且修改分辨率.首先导入到ps调整的方法2&#xff0c;记…

AXI 总线协议学习笔记(3)

引言 上篇文章主要介绍了 AMBA以及AXI协议的基本内容&#xff0c;本文接续前文&#xff0c;继续介绍AXI协议的 原子访问、传输行为和事务顺序等。 AXI 总线协议学习笔记&#xff08;2&#xff09;https://blog.csdn.net/qq_43045275/article/details/128824643 原子访问 原子…

SpringBoot系列 整合MyBatisPlus入门

官网&#xff1a; https://mybatis.plus/ https://mp.baomidou.com/ 由于MyBatisPlus并未被收录到idea的系统内置配置&#xff0c;无法直接选择加入 pom <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-sta…

【string类的简单模拟实现】

目录 1 类中成员变量的声明 2 迭代器 3 一些常用接口 4 六大默认函数 4.1 构造 4.2 拷贝构造 4.3 赋值运算符重载 4.4 析构 5 开空间&&增删查改 6 其他运算符重载 1 类中成员变量的声明 通过上一篇文章对string类的简单使用相信大家对于string类中成员变量已…

Android so库开发——Swig工具使用(五)

SWIG 是一种软件开发工具&#xff0c;它将 C 和 C 编写的程序与各种高级编程语言连接起来。这里我们用它来将 C/C 转换成 Java。 一、Swig安装 1、下载 官网&#xff1a;SWIG官网下载 源码链接 GitHub&#xff1a;https://github.com/swig/swig.git 这两个地址可能会出现无…

关于Java中的BigDecimal

文章目录为什么用BigDecimalBigDecimal构造方法通过静态方法创建BigDecimal对象BigDecimal常用API关于除法运算的roundingMode将BigDecimal转换为基本类型代码展示小结其他文章为什么用BigDecimal 使用float、double及其对应的包装类时&#xff0c;运算精度可能不满足需求 flo…

scrollTo() 无效问题处理

需求&#xff1a; 实现访问当前页面直接滚动到最底部 方案&#xff1a;window对象的scrollTo()方法 API介绍&#xff1a; 参数接收一个点&#xff08;文档坐标&#xff09;&#xff0c;让该点位于左上角。 可选参数为behavior(设置滚动的效果&#xff09; 错误案例&#xff1a;…

【My Electronic Notes系列——数制与编码】

目录 序言&#xff1a; &#x1f3c6;&#x1f3c6;人生在世&#xff0c;成功并非易事&#xff0c;他需要破茧而出的决心&#xff0c;他需要永不放弃的信念&#xff0c;他需要水滴石穿的坚持&#xff0c;他需要自强不息的勇气&#xff0c;他需要无畏无惧的凛然。要想成功&…

剑指 Offer II 005单词长度的最大乘积

给定一个字符串数组 words&#xff0c;请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时&#xff0c;它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串&#xff0c;返回 0。 示例 1: 输入: words ["abcw"…

前端CSS第二阶段-001

&#x1f60a;博主页面&#xff1a;鱿年年 &#x1f449;博主推荐专栏&#xff1a;《WEB前端》&#x1f448; ​&#x1f493;博主格言&#xff1a;追风赶月莫停留&#xff0c;平芜尽处是春山❤️ 目录 第二阶段学习目标 一、Emmet语法 1.快速生成HTML结构语法 2.快速生成…

在Runtime下,IL2CPP与Mono打包对应的PSS内存占用问题

1&#xff09;在Runtime下&#xff0c;IL2CPP与Mono打包对应的PSS内存占用问题 ​2&#xff09;获得AssetBundle内部依赖关系的方法 3&#xff09;Unity 2019 Streaming Mipmap在某些情况下采样等级错误 4&#xff09;根据RenderDoc的数据&#xff0c;计算渲染量 这是第322篇UW…

2024年部分MBA/MEM项目提面日程已经开启,气氛已然开始渐涨了

进入到二月份&#xff0c;一切都将愈发生机盎然&#xff01;全国范围内的MBA/MEM/MPA项目都有各自的招生节奏和特点&#xff0c;提前批面试作为项目招考的重要方式之一&#xff0c;每年都会从年初开始陆续开放申请&#xff0c;而对于像浙大等名校来说&#xff0c;提前批面试的批…

mysql:数据库调优策略,sql调优

mysql&#xff1a;数据库调优策略。 硬件&#xff0c;系统配置&#xff0c;数据库表结构&#xff0c;sql及索引通过这些方面来优化项目的数据库层面。 越往后成本越低&#xff0c;但是效果确实越好。 第1步&#xff1a;选择适合的 DBMS第2步&#xff1a;优化表设计第3步&#…

【Java】面向对象笔记(下)

static关键字 static 静态 什么是静态 主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象&#xff0c;也能使用属性和调用方法&#xff01; static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何…

数字授权如何满足工业软件多样化需求?

前言数字化转型的洪流正在不断对工业软件提出新的要求。在包括“智能工厂”、“智能生产”以及“智能物流”在内的主要领域里&#xff0c;工业软件正逐渐向智能化、嵌入式、分布式、互联化的方向演进。传统的软件保护和授权方式并不能适应工业软件新形式的需求。一方面&#xf…

蓝桥杯 stm32 RTC实时时钟

文章代码使用 HAL 库。 文章目录前言一、RTC 重要特性&#xff1a;二、CubeMX 创建工程。三、读取系统日期 函数。四、读取系统时间 函数。四、在 LCD 上显示 时间。总结实验效果前言 RTC (Real Time Clock)&#xff1a; 实时时钟。 RTC 模块拥有一个连续计数的 计数器&#…

mysql:有哪些索引,什么时候创建索引,什么时候不创建索引,创建索引的原则有哪些。

最近学习mysql&#xff0c;学习的索引的一些总结。 1.哪些索引 普通索引唯一性索引主键索引单列索引多列(组合、联合)索引全文索引补充&#xff1a;空间索引 小结&#xff1a;不同的存储引擎支持的索引类型也不一样 InnoDB &#xff1a;支持 B树。MyISAM &#xff1a; 支持…

基于JavaWeb的校园故障报修系统

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

Java里面为什么搞了双重检查锁,写完这篇文章终于真相大白了

双重检查锁定与延迟初始化 在 java 程序中&#xff0c;有时候可能需要推迟一些高开销的对象初始化操作&#xff0c;并且只有在使用这些对象时才进行初始化。此时程序员可能会采用延迟初始化。但要正确实现线程安全的延迟初始化需要一些技巧&#xff0c;否则很容易出现问题。比如…