python爬虫数据后正则表达式_python爬虫数据提起二之正则表达式

本文详细介绍了Python中正则表达式的使用,包括match()、group()、贪婪与非贪婪匹配、修饰符、转义匹配、search()、sub()、compile()等方法,以及正则匹配规则。通过实例演示了如何提取HTML文档中的歌曲信息,并展示了如何利用requests库和正则表达式抓取猫眼电影TOP100的数据。
摘要由CSDN通过智能技术生成

1 正则表达式简介

正则表达式(处理字符串强大的工具,有特定的语法结构) 功能:实现字符串的检索,替换,匹配验证

2 常用匹配方法

match() 从字符串起始位置匹配正则表达式,如果匹配,就返回匹配成功结果如果不匹配,就返回None。 参数1 正则表达式 参数2 要匹配的字符串

import re

content = 'Hello 123 4567 World_This is a Regex Demo'

print(len(content))

result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}',content)

print(result)

print(result.group())#输出匹配的内容

print(result.span())#输出匹配的范围

41

Hello 123 4567 World_This

(0, 25)

匹配目标 从字符串中提取一部分内容 可以使用()

import re

content = 'Hello 123 4567 World_This is a Regex Demo'

result = re.match('^Hello\s(\d+)\s(\d+)\sWorld',content)

print(result)

print(result.group())

print(result.group(1))

print(result.group(2))

print(result.span())

Hello 123 4567 World

123

4567

(0, 20)

通用匹配 . 匹配任意字符 除换行符

* 匹配前面的字符无限次

import re

content = 'Hello 123 4567 World_This is a Regex Demo'

result = re.match('^Hello.*Demo$',content)

print(result)

print(result.group())

Hello 123 4567 World_This is a Regex Demo

贪婪与非贪婪

# 贪婪模式,.*会匹配尽可能多的字符,直到剩下一个数字7和(\d+)匹配

import re

content = 'Hello 1234567 World_This is a Regex Demo'

result = re.match('^He.*(\d+).*Demo$',content)

print(result)

print(result.group(1))

7

贪婪匹配下,. 会尽可能多的匹配字符 使用.? 拒绝贪婪模式 尽可能少匹配字符

import re

content = 'Hello 1234567 World_This is a Regex Demo'

result = re.match('^He.*?(\d+).*Demo$',content)

print(result)

print(result.group(1))

1234567

3 修饰符

import re

content = '''Hello 1234567 World_This

is a Regex Demo'''

result = re.match('^He.*?(\d+).*?Demo$',content) # 匹配不了换行符,在每一行内进行匹配

print(result.group(1))

AttributeError: 'NoneType' object has no attribute 'group'

. 匹配换行符之外的任意字符 添加修饰符 re.S (使.匹配包括换行符在内的所有字符)

import re

content = '''Hello 1234567 World_This

is a Regex Demo'''

result = re.match('^He.*?(\d+).*?Demo$',content,re.S) # 添加re.S后将整个字符串视为一个整体

print(result.group(1))

1234567

re.I 使匹配对大小写不敏感

re.L 做本地化识别(locale-aware)匹配

re.M 多行匹配 ,影响^和$

re.S 使.匹配包括换行符在内的所有字符

re.U 根据Unicode字符集解析字符 影响 \w \W \b \B

网页匹配 常用 re.S re.L

4 转义匹配

.匹配除换行符以外的任意字符 如果目标字符串里面包含.

import re

content = '(百度)www.baidu.com'

result = re.match('\(百度\)www\.baidu\.com',content)

print(result)

遇到正则匹配模式的特殊字符 在前面加反斜杠转义

4.1 search()

search()匹配整个字符串 返回第一个成功匹配的结果 匹配失败 返回None match() 从字符串起始位置匹配正则表达式

import re

content = 'Auto Hello 1234567 World_This is a Regex Demo'

result = re.match('He.*?(\d+).*Demo',content)

print(result)#返回None

import re

content = 'Auto Hello 1234567 World_This is a Regex Demo'

result = re.search('He.*?(\d+).*Demo',content)

print(result)

None

4.1.1 实例:

利用search方法 提取 html文档中 齐秦 往事随风

查看文件 html.txt

import re

html = '''

经典老歌

经典老歌列表

'''

result = re.search('li.*?active.*?singer="(.*?)">(.*?)',html,re.S)

print(result)

print(result.group(1))

print(result.group(2))

(.*?)',html,re.S)

print(result)

[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]

遍历 依次获取每组内容

for results in result:

print(results)

('/2.mp3', '任贤齐', '沧海一声笑')

('/3.mp3', '齐秦', '往事随风')

('/4.mp3', 'beyond', '光辉岁月')

('/5.mp3', '陈慧琳', '记事本')

('/6.mp3', '邓丽君', '但愿人长久')

对应索引依次取出

for results in result:

print(results[0],results[1],results[2])

/2.mp3 任贤齐 沧海一声笑

/3.mp3 齐秦 往事随风

/4.mp3 beyond 光辉岁月

/5.mp3 陈慧琳 记事本

/6.mp3 邓丽君 但愿人长久

4.3 sub()

参数1 规则 参数2 规则 参数3 字符串

strs = '34iaU8hw9kcj2k3O0jc7oqqw8W'

去掉所有数字

import re

strs = '34iaU8hw9kcj2k3O0jc7oqqw8W'

strs = re.sub('\d+','',strs)

print(strs)

iaUhwkcjkOjcoqqwW

获取html文本 所有li节点的歌名

import re

html = '''

经典老歌

经典老歌列表

'''

results = re.findall('

\s*?()?(\w+)()?\s*?',html,re.S)

for result in results:

print(result[1])

一路上有你

沧海一声笑

往事随风

光辉岁月

记事本

但愿人长久

利用sub方法 去掉a节点 再用findall方法提取

import re

html = '''

经典老歌

经典老歌列表

'''

html = re.sub('|','',html) # 用参数2来替换参数1

# print(html)

results = re.findall('

(.*?)',html,re.S)

# print(results)

for result in results:

print(result.strip())#去掉字符串两边的空格或者换行符

一路上有你

沧海一声笑

往事随风

光辉岁月

记事本

但愿人长久

4.4 compile()

compile() 将正则字符串编译成正则表达式对象 以便复用 也可以传入修饰符 例如re.S 相当于做了一层封装

import re

str1 = '2016-12-25 12:00'

str2 = '2017-12-17 11:55'

str3 = '2018-12-23 15:00'

pattern = re.compile('\d{2}:\d{2}')

result1 = re.sub(pattern,'',str1)

result2 = re.sub(pattern,'',str2)

result3 = re.sub(pattern,'',str3)

print(result1,result2,result3)

2016-12-25 2017-12-17 2018-12-23

5 正则匹配规则

模式

描述

\w

匹配字母、数字、下划线

\W

匹配非字母、数字、下划线

\s

匹配任意空白字符,等价于[\t\n\r\f]

\S

匹配任意非空字符

\d

匹配任意数字,等价于[0-9]

\D

匹配任意非数字的字符

\A

匹配字符串开头

\Z

匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串

\z

匹配字符串结尾,如果存在换行,同时还会匹配换行符

\G

匹配最后匹配完成的位置

\n

匹配一个换行符

\t

匹配一个制表符

^

匹配一行字符串的开头

$

匹配一行字符串的结尾

.

匹配任意字符,除换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符串

[...]

用来表示一组字符,单独列出 例如[amk] 匹配a,m或k

[^...]

不在[]中的字符 例如[^abc] 匹配除了a,b,c之外的字符

*

匹配0个或多个表达式

+

匹配1个或多个表达式

?

匹配0个或1个前面的表达式定义的片段,非贪婪模式

{n}

精确匹配n个前面的表达式

{n,m}

匹配n到m次由前面表达式定义的片段,贪婪模式

a|b

匹配a或b

( )

匹配括号内的表达式,也表示一个组

6 实战

利用requests库和正则表达式 抓取猫眼电影TOP100

分析

offset 代表偏移量 如果为n 电影序号为n+1~n+10 每页显示10个

获取100 分开请求10次 offset 分别为0 10 20...90 利用正则提取相关信息

抓取页面

import requests

#爬取第一页 页面信息

def get_one_page(url):

header = {

"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16",

}

response = requests.get(url,headers=header)

if response.status_code == 200:#判断是否请求成功

return response.text

return None

def main():

url = 'http://maoyan.com/board/4'

html = get_one_page(url)#调用请求函数

print(html)

main()

分析页面

电影信息对应节点为

提取排名 class 为 board-index i节点内 正则

.*?board-index.*?>(.*?)

电影图片 查看为第二个img链接

.*?board-index.*?>(.*?).*?data-src="(.*?)"

电影名字 p节点 class 为name

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?)

主演

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

发布时间

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?).*?releasetime.*?>(.*?)

评分

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?).*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*?

定义分析页面的方法 parse_one_page()

import requests

import re

def get_one_page(url):

header = {

"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16",

}

response = requests.get(url,headers=header)

if response.status_code == 200:

return response.text

return None

def parse_one_page(html):

pattern = re.compile(

'

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?).*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*?',re.S

)

items = re.findall(pattern,html)

print(items)

# 定义一个main函数 调用get_one_page 发送请求 打印结果

def main():

url = 'http://maoyan.com/board/4'

html = get_one_page(url)

# print(html)

parse_one_page(html)

main()

将匹配结果遍历 生成字典,单页面电影提取

import requests

import re

import json

# 请求页面

def get_one_page(url):

header = {

"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16",

}

response = requests.get(url,headers=header)

if response.status_code == 200:

return response.text

return None

#解析页面

def parse_one_page(html):# html为网页源码

pattern = re.compile(

'

.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?).*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*?',re.S

)#定义规则

items = re.findall(pattern,html)#查找整个页面

# print(items)

#遍历结果生成字典

for item in items:

yield {

'index':item[0],

'image': item[1],

'title': item[2].strip(),

'actor': item[3].strip()[3:] if len(item[3]) > 3 else'',

'time': item[4].strip()[5:] if len(item[4]) > 5 else '',

'score': item[5].strip()+item[6].strip()

}

#返回一个生成器 yield

#写入文件

def write_to_file(content):

with open('result.txt','a',encoding='utf-8') as f:

print(type(json.dumps(content)))

f.write(json.dumps(content,ensure_ascii=False)+'\n')

# 定义一个main函数 调用get_one_page 发送请求 打印结果

def main():

url = 'http://maoyan.com/board/4'

html = get_one_page(url)

# print(html)

for item in parse_one_page(html):#遍历生成器

write_to_file(item)

main()

分页爬取 定义一个main函数 调用get_one_page 发送请求 打印结果

def main(offset):

url = 'http://maoyan.com/board/4?offset=' + str(offset)

html = get_one_page(url)

# print(html)

for item in parse_one_page(html):#遍历生成器

write_to_file(item)

if __name__ == '__main__':

for i in range(10):

main(offset = i *10)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值