文章目录
前言
解析网页的常见方式有re,bs4,xpath,其中re即正则表达式匹配,在爬虫方面使用较多的有贪婪匹配和惰性匹配,该文中我们就用re的知识来完成提取top250电影信息的实例,获取信息包括(电影名,首映年份,评分,评分人数)。
提示:以下是本篇文章正文内容,下面内容可供参考
一、re预备知识
事实上,re正则表达式的用法很多且很复杂,了解大概即可。网站:https://tool.oschina.net/regex可以帮助了解和测验正则表达式。
1.re.complie()
语法结构:
re.compile(pattern, flags=0)
pattern:指定编译时的表达式字符串
flags:编译标志位,用来修改正则表达式的匹配方式。支持 re.L|re.M 同时匹配,其中re.I(忽略大小写),re.M(多行模式),re.S(点任意匹配模式,改变.的行为)
相关代码:
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="">.*?<br>(?P<year>.*?) .*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>',
re.S)
re.compile() 是 Python 中 re 模块的一个函数,用于将正则表达式模式编译成一个正则表达式对象。这个对象可以用来进行更高效的匹配操作。编译后的正则表达式对象可以重复使用,减少了每次匹配时重新解析模式的开销。
2.re.finditer()
在使用 re.finditer() 函数时,需要先通过 re.compile() 函数创建一个模式对象,再使用模式对象调用 finditer() 方法。
相关代码:
for it in obj.finditer(page_content):
print(it.group("name"))
print(it.group("year").strip())
print(it.group("score"))
print(it.group("num"))
finditer()可以快速匹配长字符串中符合要求的子字符串。
3.re中group方法
在 Python 的 re 模块中,group 是 re.Match 对象的方法,用于从匹配的结果中提取信息。具体用法如下:
group(): 返回整个匹配的字符串。
group(n): 返回第 n 个捕获组(子匹配)的内容。捕获组是正则表达式中的括号 () 定义的部分。
group(*groupnumbers): 返回指定捕获组的内容,可以同时指定多个组。
二、问题分析、代码及优化
1.问题分析
需要获取top250电影的名称,首映日期,评分,及评分人数。首先,检查页面,需要获取的网页内容在页面可直观看到。
然后,使用抓包工具可以获得请求头相关信息,例如代码中:
url = 'https://movie.douban.com/top250'
headers = {"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 "
"SLBrowser/9.0.3.5211 SLBChan/105"
}
再者,结合惰性匹配:.*?,它会尽可能少地匹配字符,以满足整个正则表达式的其他部分,我们借助正则表达式格式一步步得到所需信息对应的正则表达式格式:
r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<p class="">.*?<br>(?P<year>.*?) .*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>'
最后,我们整合代码,借助requests库向网站发起请求,re分析页面,即可筛选到目标信息。
2.代码(基础完整)
代码如下(示例):
import requests
import re
url = f'https://movie.douban.com/top250'
headers = {"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 "
"SLBrowser/9.0.3.5211 SLBChan/105"
}
resp = requests.get(url, headers=headers)
page_content = resp.text
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="">.*?<br>(?P<year>.*?) .*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>',
re.S)
for it in obj.finditer(page_content):
print(it.group("name"))
print(it.group("year").strip())
print(it.group("score"))
print(it.group("num"))
resp.close()
2.1运行结果
我们发现运行结果中只得到前25个电影的相关信息,这是因为页面信息做了分页处理,共十页。借助for循环以及拼接URL即可拓展获得top250的所有信息(优化代码)。
3.优化——拓展top250以及csv文件格式化(延伸)
优化代码如下:
import requests
import re
import csv
f = open('data.csv', 'w')
csvwriter = csv.writer(f)
csvwriter.writerow(['name', 'year', 'score', 'num'])
for n in range(0,250,25):
url = f'https://movie.douban.com/top250?start={n}'
headers = {"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 "
"SLBrowser/9.0.3.5211 SLBChan/105"
}
resp = requests.get(url, headers=headers)
page_content = resp.text
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="">.*?<br>(?P<year>.*?) .*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价</span>',
re.S)
for it in obj.finditer(page_content):
dic = it.groupdict()
dic['year'] = dic['year'].strip()
csvwriter.writerow(dic.values())
resp.close()
该处为示例代码的优化,我们借助for循环以及URL拼接遍历分页的所有页面信息,并将数据存入了csv文件(注意:不要频繁发起请求,数据获取失败可以尝试更换user-agent)。csv文件格式化有助于后续进行数据分析操作,csv文件储存数据是一种方便快捷的方式。
三、注意事项
1.避免多次请求
请不要多次刷新网站页面,不要高频次向网站发起请求
另外可在代码中限制爬虫申请的频率,避免频繁访问。请遵循网站robots.txt协议,合理获取相关信息。
上图是网站对异常请求IP的跳转检验。
2.释放请求
在爬取信息完成后,代码一定要释放请求:
resp.close()
在处理 HTTP 请求时(例如使用 requests 库),resp是一个响应对象。当你完成处理 HTTP 响应后,应该关闭连接以释放资源。
3.合理使用
合理使用爬虫涉及遵守法律法规、尊重网站资源、保护隐私以及正确处理数据。在有效收集数据的同时,请避免潜在的问题和风险。
总结
本文介绍了一个基于re解析网站信息的操作实例,借助re我们获得了解析网站信息的路径,感兴趣的读者可以动手试一试。