Python爬虫篇二之利用re正则爬取豆瓣页面练习
在我的爬虫一篇中,咱了解到了大概的爬虫思路,那么咱带着思路进一步研究爬虫技术
今天我们要用到re这个模块,对爬取到的内容进行清洗,拿到具体想要的内容
首先我们要了解re这个模块的功能,主要就是利用正则表达式,来提取内容
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
这次主要简单介绍一下常用的正则表达式处理函数
正则表达式量词
* 重复0次或多次
+ 重复1次或多次
? 重复0次或1次
{ n} 重复n次
{ n,3 重复n次或多次
{ n,m}重复n到m次
.*贪婪匹配
.*?惰性匹配
re.findall:在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表
练习案例
lis =re.findall('\d+','你试试啊100428,你的1093989')
print(lis)
re.finditer:和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回,这个功能我们用的比较多
练习案例
it = re.finditer(r"\d+","我的电话号是10086,我女朋友的电话是:10010")
for i in it:
print(i.group())
re.match是从头开始匹配
练习案例
s= re.match(r"\d+","我的电话号是:10086,我女朋友的电话是:10010")
print(s.group())
re.search,找到一个结果就返回,返回的结果是match对象,拿数据需要.group()
练习案列
s= re.search(r"\d+","我的电话号是:10086,我女朋友的电话是:10010")
print(s.group())
re.compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
练习案例
obj =re.compile(r"\d+")
ret = obj.finditer("我的电话号是:10086,我女朋友的电话号是:10010")
我们现在进行的练习需要用到re.compile预加载,和re.finditer居多
现在开始练习爬取豆瓣250 url =https://movie.douban.com/top250
分析页面,拿到剧名,年份,评分,评价人数,影评
打开谷歌浏览器,利用开发者工具(F12)对页面进行检查可以发现,需要的内容都存放在li中
分析完找到内容和规律后,可以发现每个li内容的格式都是一样的,现在可以进行爬取
只想要想要的内容,而不想要其他的东西应该怎么处理呢?
在这个案例当中,我们需要了解,贪婪模式 .* ,和非贪婪模式.*?
贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。
在提取数据时,可以用.?来替代不要的数据,想要的东西也可以用(?P<名字>.?)这种格式拿到数据
了解完大家去试一下吧
源码如下
#导入正则,处理页面
import re
#导入requests模块进行页面爬取
import requests
#导入csv模块为了存储csv文件,方便后续的数据分析
import csv
# 设置伪装头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'
}
# 指定url地址
# url = "https://movie.douban.com/top250?start=%s&filter="%index
url = "https://movie.douban.com/top250"
reps = requests.get(headers=headers, url=url)
#根据页面的字符集设置字符编码
reps.encoding = "UTF-8"
aaa = reps.text
#爬取到内容后进行数据处理,拿想要的东西
obj = re.compile(
r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<p class="">.*?<br>(?P<tt>.*?) .*?</p>'
r'.*?<span class="rating_num" property="v:average">(?P<pf>.*?)</span>.*?<span>(?P<pj>.*?)</span>'
r'.*?<span class="inq">(?P<py>.*?)</span>.*?', re.S)
ss = obj.finditer(aaa)
#在这里我们进行csv文件存储
f = open("pc.csv", mode="a+", encoding="UTF8")
csvwj = csv.writer(f)
for it in ss:
#拿到处理好的数据后,进行输出,看看又没有爬取到内容
# print(it.group("name"))
#print(it.group("tt").strip())
# print(it.group("pf"))
# print(it.group("pj"))
# print(it.group("py"))
#最后我们想要把数据存起来,最好用字典的形式将数据封装起来
#因为日期后面有空行,这里我们要特别处理,所以可以单独存放
dic = it.groupdict()
dic["tt"] = dic["tt"].strip()
csvwj.writerow(dic.values())
我把步骤都打在注释里了,大家试着消化一下。
在进行爬取的时候尝试着看看想要的内容是否在HTML页面当中,如果是就可以进行爬取,本次案例显然可以。
如果基础还不错,可以分析页面,实现多页面爬取。
还没有评论,来说两句吧...