百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python3爬虫基础:正则表达式爬取猫眼信息写入txt,csv

off999 2024-10-04 00:20 42 浏览 0 评论

前言

正则表达式是对字符串的一种逻辑公式,用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则的字符串”,此字符串用来表示对字符串的一种“过滤”逻辑。正在在很多开发语言中都存在,而非python独有。对其知识点进行总结后,会写一个demo。

有需要Python学习资料的小伙伴吗?小编整理【一套Python资料、源码和PDF】,感兴趣者可以关注小编后私信学习资料(是关注后私信哦)反正闲着也是闲着呢,不如学点东西啦

1.正则表达式

python是自1.5开始引进re模块进行处理正则的。我先把正则的匹配规则总结一下,再总结re模块相应的方法。

1.1匹配规则

对于一个特殊字符在正则表达式中是不能正常识别的,如果接触过其他语言我们就这到有一个叫做转移字符的东西的存在,在特殊字符前加用反斜杠接口。比如\n换行\\为反斜杠,在这不再累述。下面来介绍一下re这个模块。

1.2.re模块

此模块主要方法如下

re.match()#尝试从字符串的起始位置匹配一个模式(pattern),如果不是起始位置匹配成功的话,match()就返回None
re.search()#函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。
re.findall()#遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。
re.compile()#编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
re.sub()#使用re替换string中每一个匹配的子串后返回替换后的字符串。
re.subn()#返回替换次数
re.split()#按照能够匹配的子串将string分割后返回列表。

1.2.1.re.match()

方法: re.match(pattern, string, flags=0) # pattern:正则表达式(或者正则表达式对象)string:要匹配的字符串flags:修饰符

先看一个最简单的用法

import re
content ='Hello 123 4567 wangyanling REDome'
print(len(content))
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*Dome
, content) print(result) print(result.group()) print(result.span())

结果:

匹配规则就不在累述,以上需要注意的是

(1) .group() 表示的是返回正则匹配的结果

(2) .span() 表示返回正则匹配的范围

使用:

以上我们已经知道re.matcha()的具体方法,那么接下我来看一下具体使用,对此我们要理解以下几种匹配的感念。

1.泛匹配(.*):匹配所有字符

import re
content ='Hello 123 4567 wangyanling REDome'
result = re.match('^Hello.*Dome
, content) print(result) print(result.group()) print(result.span())

它的结果是和上面的输出结果完全一样的。

2.目标匹配(()):将需要的字符匹配出来

import re
content ='Hello 123 4567 wangyanling REDome'
result = re.match('^Hello\s\d\d(\d)\s\d{4}\s\w{10}.*Dome
, content) print(result) print(result.group(1)) import re content ='Hello 123 4567 wangyanling REDome' result = re.match('^Hello\s(\d+)\s\d{4}\s\w{10}.*Dome
, content) print(result) print(result.group(1))

结果

以上可以看出:

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

(2) + 匹配1个或多个的表达式

*匹配0个或多个的表达式

(3) .group(1) —输出第一个带有()的目标

3.贪婪匹配(.*()):匹配尽可能少的的结果

import re
content ='Hello 123 4567 wangyanling REDome'
result = re.match('^H.*(\d+).*Dome
, content) print(result) print(result.group(1))

结果

4.贪婪匹配(.*?()):匹配尽可能多的结果

import re
content ='Hello 123 4567 wangyanling REDome'
result = re.match('^H.*?(\d+).*?Dome
, content) print(result) print(result.group(1))

结果

以上3,4两个匹配方式请尽量采用非贪婪匹配

5.其他

换行:

import re
content ='''Hello 123 4567 
 wangyanling REDome'''
result = re.match('^H.*?(\d+).*?Dome
, content,re.S)#re.S print(result.group(1)) result = re.match('^H.*?(\d+).*?Dome, content) print(result.group(1))

结果:

转义字符:

import re
content = 'price is $5.00'
result = re.match('price is $5.00', content)
print(result)
result = re.match('price is \$5\.00', content)
print(result)

结果:

其中re.I使匹配对大小不敏感,re.S匹配包括换行符在内的所有字符,\进行处理转义字符。匹配规则中有详细介绍。

1.2.2.re.search()

方法:

re.search(pattern, string, flags=0)#pattern:正则表达式(或者正则表达式对象)string:要匹配的字符串flags:修饰符
 #re.match()和re.search()用法类似唯一的区别在于re.match()从字符串头开始匹配,若头匹配不成功,则返回None 

对比一下与match()

import re
content ='Hello 123 4567 wangyanling REDome'
result = re.match('(\d+)\s\d{4}\s\w{10}.*Dome, content)
print(result)#从开头开始查找,不能匹配返回None
result = re.search('(\d+)\s\d{4}\s\w{10}.*Dome, content)
print(result)
print(result.group())

结果:

可以看出两个使用基本一致,search从头开始匹配,如果匹配不到就返回none.

1.2.3.re.findall()

方法: re.finditer(pattern, string, flags=0) # pattern:正则表达式(或者正则表达式对象)string:要匹配的字符串flags:修饰符

与re.search()类似区别在于re.findall()搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。

import re
html = '''
 <div>
 <li><a href="" singer="鲁迅">呐喊</a></li>
 <li><a href="#" singer="贾平凹">废都</a></li>
 <li class="active"><a href="#" singer="路遥">平凡世界</a></li>
 <span class="rightSpan">谢谢支持</span>
 </div>
'''
regex_4='<a.*?>(.*?)</a>'
results=re.findall(regex_4,html,re.S)
print(results)
for result in results:
 print(result)

结果:

1.2.4.re.compile()

编译正则表达式模式,返回一个对象的模式。

方法: re.compile(pattern,flags=0) # pattern:正则表达式(或者正则表达式对象);flags:修饰符

看一个demo

import re
content ='Hello 123 4567 wangyanling REDome wangyanling 那小子很帅'
rr = re.compile(r'\w*wang\w*')
result =rr.findall(content)
print(result)

结果:

我们可以看出compile 我们可以把它理解为封装了一个公用的正则,类似于方法,然后功用。

1.2.5.其他

re.sub 替换字符

方法: re.sub(pattern, repl, string, count=0, flags=0) # pattern:正则表达式(或者正则表达式对象)repl:替换的字符串string:要匹配的字符串count:要替换的个数flags:修饰符

re.subn 替换次数

方法: re.subn(pattern, repl, string, count=0, flags=0) # pattern:正则表达式(或者正则表达式对象)repl:替换的字符串string:要匹配的字符串count:要替换的个数flags:修饰符

re.split()分隔字符

方法

re.split(pattern, string,[maxsplit])#正则表达式(或者正则表达式对象)string:要匹配的字符串;maxsplit:用于指定最大分割次数,不指定将全部分割

2.案例:爬取猫眼信息,写入txt,csv,下载图片

2.1.获取单页面信息

def get_one_page(html):
 pattern= re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
 + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)#这里就用到了我们上述提到的一些知识点,非贪婪匹配,对象匹配,修饰符
 items = re.findall(pattern,html)
 for item in items:
 yield {
 'rank' :item[0],
 'img': item[1],
 'title':item[2],
 '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] + item[6]
 }

对于上面的信息我们可以看出是存到一个对象中那么接下来我们应该把它们存到文件当中去。

2.2.保存文件

我写了两种方式保存到txt和csv这些在python都有涉及,不懂得可以去翻看一下。

2.2.1.保存到txt

def write_txtfile(content):
 with open("Maoyan.txt",'a',encoding='utf-8') as f:
 #要引入json,利用json.dumps()方法将字典序列化,存入中文要把ensure_ascii编码方式关掉
 f.write(json.dumps(content,ensure_ascii=False) + "\n")
 f.close()

结果:


以上看到并非按顺序排列因为我用的是多线程。

2.2.2.保存到csv

def write_csvRows(content,fieldnames):
 '''写入csv文件内容'''
 with open("Maoyao.csv",'a',encoding='gb18030',newline='') as f:
 #将字段名传给Dictwriter来初始化一个字典写入对象
 writer = csv.DictWriter(f,fieldnames=fieldnames)
 #调用writeheader方法写入字段名
 writer.writerows(content)
 f.close()

结果:

那么还有一部就是我们要把图片下载下来。

2.2.3.下载图片

def download_img(title,url):
 r=requests.get(url)
 with open(title+".jpg",'wb') as f:
 f.write(r.content)

2.3.整体代码

这里面又到了多线程在这不在叙述后面会有相关介绍。这个demo仅做一案例,主要是对正则能有个认知。上面写的知识点有不足的地方望大家多多指教。

#抓取猫眼电影TOP100榜
from multiprocessing import Pool
from requests.exceptions import RequestException
import requests
import json
import time
import csv
import re
def get_one_page(url):
 '''获取单页源码'''
 try:
 headers = {
 "User-Agent":"Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36"
 }
 res = requests.get(url, headers=headers)
 # 判断响应是否成功,若成功打印响应内容,否则返回None
 if res.status_code == 200:
 return res.text
 return None
 except RequestException:
 return None
def parse_one_page(html):
 '''解析单页源码'''
 pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
 + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)
 items = re.findall(pattern,html)
 #采用遍历的方式提取信息
 for item in items:
 yield {
 'rank' :item[0],
 'img': item[1],
 'title':item[2],
 'actor':item[3].strip()[3:] if len(item[3])>3 else '', #判断是否大于3个字符
 'time' :item[4].strip()[5:] if len(item[4])>5 else '',
 'score':item[5] + item[6]
 }
def write_txtfile(content):
 with open("Maoyan.txt",'a',encoding='utf-8') as f:
 #要引入json,利用json.dumps()方法将字典序列化,存入中文要把ensure_ascii编码方式关掉
 f.write(json.dumps(content,ensure_ascii=False) + "\n")
 f.close()
def write_csvRows(content,fieldnames):
 '''写入csv文件内容'''
 with open("Maoyao.csv",'a',encoding='gb18030',newline='') as f:
 #将字段名传给Dictwriter来初始化一个字典写入对象
 writer = csv.DictWriter(f,fieldnames=fieldnames)
 #调用writeheader方法写入字段名
 #writer.writeheader() ###这里写入字段的话会造成在抓取多个时重复.
 writer.writerows(content)
 f.close()
def download_img(title,url):
 r=requests.get(url)
 with open(title+".jpg",'wb') as f:
 f.write(r.content)
def main(offset):
 fieldnames = ["rank","img", "title", "actor", "time", "score"]
 url = "http://maoyan.com/board/4?offset={0}".format(offset)
 html = get_one_page(url)
 rows = []
 for item in parse_one_page(html):
 #download_img(item['rank']+item['title'],item['img'])
 write_txtfile(item)
 rows.append(item)
 write_csvRows(rows,fieldnames)
if __name__ == '__main__':
 pool = Pool()
 #map方法会把每个元素当做函数的参数,创建一个个进程,在进程池中运行.
 pool.map(main,[i*10 for i in range(10)])

有需要Python学习资料的小伙伴吗?小编整理【一套Python资料、源码和PDF】,感兴趣者可以关注小编后私信学习资料(是关注后私信哦)反正闲着也是闲着呢,不如学点东西啦

相关推荐

查看电脑ip地址的命令(查看电脑ip地址用什么命令)
查看电脑ip地址的命令(查看电脑ip地址用什么命令)

1、在“本地连接”的状态中查看。2、使用“ipconfig/all”命令查看。3、打开电脑网页,输入IP地址,点击确定,就能看到本机IP。扩展资料IP地址(InternetProtocolAddress),全称为网际协议地址,是一种在...

2025-12-30 10:03 off999

ie浏览器9(IE浏览器9.0如何升级)

1、首先,我们点击开始菜单,找到控制面板,点击一下。2、之后,找到程序和功能选项,点击一下。3、点击进入后,我们找到左边的打开或关闭windows功能,点击一下。4、点击进入后,找到Internet...

hp1020打印机驱动怎么下载(hp1020打印机驱动怎么下载)

惠普1020打印机驱动怎么安装:  1.首先到下载软件名称:惠普1020打印机驱动程序官方版(支持win7/8)32位/64位软件大小:5.09MB更新时间:2014-09-05立即下载  2.然后...

win2003是windows7系统(win2003哪个版本好)

win2003是专门用于服务器的操作系统,现在最主流的windows服务器系统主要是win2003server和win2008server,winXP是个人电脑专用的操作系统,现在微软已经不再提供XP...

路由器账号和密码忘了怎么办

你好,如果你忘记了路由器的用户名和密码,你可以尝试重置一下路由器,大多数路由器都配备了一个复位按键。在重置路由器之后,用户名和密码将被还原为默认值,你可以在路由器的用户手册或厂家网站上找到默认的用户名...

win10永久禁止自动更新(win10禁止自动更新彻底)

阻止Windows10自动更新的方法如下:使用“本地组策略编辑器”:按下“Win+R”键,输入“gpedit.msc”打开本地组策略编辑器,找到“计算机配置”>“管理模板”>“W...

联想笔记本怎么看配置和型号

联想笔记本看配置的方法如下1、打开电脑,点击桌面的计算机,右键菜单里选择【属性】;打开后,即可看到电脑系统的大概信息;2、如果要看比较详细的设备相关信息,点击桌面的计算机,点击右键,在菜单里选择【系统...

怎样把打印机连接到电脑上(怎么把打印机连接电脑上)
  • 怎样把打印机连接到电脑上(怎么把打印机连接电脑上)
  • 怎样把打印机连接到电脑上(怎么把打印机连接电脑上)
  • 怎样把打印机连接到电脑上(怎么把打印机连接电脑上)
  • 怎样把打印机连接到电脑上(怎么把打印机连接电脑上)
photoshop6序列号(photoshop8.01序列号)
  • photoshop6序列号(photoshop8.01序列号)
  • photoshop6序列号(photoshop8.01序列号)
  • photoshop6序列号(photoshop8.01序列号)
  • photoshop6序列号(photoshop8.01序列号)
win10下载应用商店(win10应用商店打不开)

1、点击Win10系统的开始菜单,然后在点击应用商店;2、打开Win10应用商店后,在搜索框里输入想要搜索的应用软件,然后点击检索;3、点击搜索到的应用,点击安装;4、点击安装后,系统会提示要切换到这...

dell电脑重装系统win10(dell 重装win10系统)

戴尔笔记本重装系统win10的步骤如下:制作好wepe启动盘之后,将win10系统iso镜像直接复制到U盘。在需要重装系统的戴尔电脑上插入pe启动盘,重启后不停按F12启动快捷键,调出启动菜单对话框,...

android升级包下载安装(android 升级包)

打开手机系统更新升级,前提是官方有新系统推送才能更新  哪个大不一定,但一般规律如下:  1、小版本的更新,通常越更新越大。比如3.1更新到3.2,通常是修复bug,代码量通常会增大,体积就会增大。 ...

hdd硬盘和ssd(ssd硬盘和hdd硬盘是什么意思)

HDD硬盘和SSD硬盘是两种不同类型的电脑存储设备,它们有着以下区别:1.工作原理:HDD硬盘使用机械旋转的磁盘和读写磁头来存储和读取数据,而SSD硬盘则使用闪存存储数据,类似于USB闪存盘。2....

电脑免费软件下载大全(电脑上免费的下载软件)

正常情况下,如果我们想要在自己的电脑上面下载一个不要钱的单机游戏,那么我们是可以直接在我们的软件管理中心进行一个下载的,这个时候我们只需要通过一个权限就能够正常的下载,当然我们也是可以在一些小游戏的软...

mpp文件转换excel(mpp转换成pdf)

要将Excel表格转换为MPP格式,您可以按照以下步骤操作:1.打开Excel表格并确保数据按照项目的不同阶段或任务进行组织。2.将Excel表格中的数据复制到一个新的MicrosoftProj...

取消回复欢迎 发表评论: