python3网络爬虫开发实战-抓取猫眼电影排行(正则表达式版)
抓取猫眼电影排行
目前没有学习HTML解析库,这里先选用正则表达式作为解析工具
目标
提取出猫眼电影top100的电影名称、时间、评分、图片等信息。提取的站点URL为http://maoyan.com/board/4,提取的结果以文件形式保存下来。
抓取分析
首页显示的是top10,点击下面的 [第二页],URL变成了 http://maoyan.com/board/4?offset=10,这时显示的是排行11-20名的电影。当我们分开请求10次,offset参数分别设置为0、10、20…90,获取不同页面之后,再用正则表达式提取出相关信息,就可以得到top100 的所有电影信息。
抓取首页
估计是由于学习此书的人比较多,猫眼对反爬的策略有所增强。header中如果只有User-Agent ,有时会被限制,跳转的猫眼验证页面。因此,还需要增加Cookie。
import requestsdef get_one_page(url):headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0','Cookie':'__mta=244153658.1609735789043.1609814345631.1609903887876.9; uuid_n_v=v1; uuid=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _lxsdk_cuid=176cbbad8c4c8-0687fad5143e0b-3e604000-144000-176cbbad8c4c8; _lxsdk=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _csrf=e80757462cd1516a77cd1805be934c54f7d4e90601451188280cb41fd6c4871a; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1609735788,1609764730,1609812449,1609903888; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1609903888; _lxsdk_s=176d5bfd5c7-e23-d69-9d%7C%7C2'}result = requests.get(url, headers=headers)if result.status_code==200:return result.textreturn Nonedef main():url = 'http://maoyan.com/board/4'html = get_one_page(url)print(html)main()
正则提取
在Network 监听组件中查看源代码
可以看到一部电影信息对应的是一个dd节点,我们用正则表达式来提取里面的电影信息(排名、电影图片链接、电影名称、主演、电影发布时间、评分)。
首先是排名:
<dd>.*?board-index.*?>(.*?)</i>
这时候代码:
import requests
import redef get_one_page(url):headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0','Cookie':'__mta=244153658.1609735789043.1609814345631.1609903887876.9; uuid_n_v=v1; uuid=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _lxsdk_cuid=176cbbad8c4c8-0687fad5143e0b-3e604000-144000-176cbbad8c4c8; _lxsdk=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _csrf=e80757462cd1516a77cd1805be934c54f7d4e90601451188280cb41fd6c4871a; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1609735788,1609764730,1609812449,1609903888; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1609903888; _lxsdk_s=176d5bfd5c7-e23-d69-9d%7C%7C2'}result = requests.get(url, headers=headers)if result.status_code==200:return result.textreturn Nonedef parse_one_page(html):pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>', re.S)items = re.findall(pattern,html)return itemsdef main():url = 'http://maoyan.com/board/4'html = get_one_page(url)print(parse_one_page(html))main()
运行结果:
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
然后看电影图片链接,可以看到后面有个a节点,内部有两个img节点。第二个img节点的data-src 属性是图片链接。正则表达式改写如下:
<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)"
这时运行结果:
然后看电影名。后面p节点内,class 为name。可以用name作为标志位,提取a节点的整文内容。正则表达式改写如下:
<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name"><.*?>(.*?)</a>
运行结果
提取主演、发布时间、评分也是一样的道理。最后的正则表达式为:
<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name"><.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>
这时程序的运行结果:
通过前面正则表达式那一节的学习我们可以知道,re.findall() 得到的是一个由元组组成的列表。当然,从上面的这个结果也可以看出来。此外我们发现数据比较乱(存在空格和换行),我们将匹配结果处理一下,遍历提取结果并生成字典。整体代码如下:
import requests
import redef get_one_page(url):headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0','Cookie':'__mta=244153658.1609735789043.1609814345631.1609903887876.9; uuid_n_v=v1; uuid=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _lxsdk_cuid=176cbbad8c4c8-0687fad5143e0b-3e604000-144000-176cbbad8c4c8; _lxsdk=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _csrf=e80757462cd1516a77cd1805be934c54f7d4e90601451188280cb41fd6c4871a; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1609735788,1609764730,1609812449,1609903888; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1609903888; _lxsdk_s=176d5bfd5c7-e23-d69-9d%7C%7C2'}result = requests.get(url, headers=headers)if result.status_code==200:return result.textreturn Nonedef parse_one_page(html):pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name"><.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>', re.S)items = re.findall(pattern,html)for item in items:yield {'index': item[0],'image': item[1],'title': item[2].strip(),'actor': item[3].strip()[3:],'time': item[4].strip()[5:],'score': item[5].strip() +item[6].strip()}def main():url = 'http://maoyan.com/board/4'html = get_one_page(url)for x in parse_one_page(html):print(x)main()
程序运行结果:
关于yield,在前一篇博文中有写:传送门
到此,我们就成功提取了单页的电影信息。
写入文件
我们将我们将提取的结果写入文本文件。通过JSON库的dumps() 方法实现字典的序列号,并指定ensure_ascii 参数为 False,这样可以保证输出结果是中文形式而不是Unicode编码。代码如下:
def write_to_file(content):with open('result.txt', 'a', encoding='utf-8') as f_obj:f_obj.write(json.dumps(content, ensure_ascii=False +'\n'))
此处的content 参数是一部电影的提取结果,是一个字典。
此时整体代码为:
import requests
import re
import jsondef get_one_page(url):headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0','Cookie':'__mta=244153658.1609735789043.1609814345631.1609903887876.9; uuid_n_v=v1; uuid=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _lxsdk_cuid=176cbbad8c4c8-0687fad5143e0b-3e604000-144000-176cbbad8c4c8; _lxsdk=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _csrf=e80757462cd1516a77cd1805be934c54f7d4e90601451188280cb41fd6c4871a; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1609735788,1609764730,1609812449,1609903888; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1609903888; _lxsdk_s=176d5bfd5c7-e23-d69-9d%7C%7C2'}result = requests.get(url, headers=headers)if result.status_code==200:return result.textreturn Nonedef parse_one_page(html):pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name"><.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>', re.S)items = re.findall(pattern,html)for item in items:yield {'index': item[0],'image': item[1],'title': item[2].strip(),'actor': item[3].strip()[3:],'time': item[4].strip()[5:],'score': item[5].strip() +item[6].strip()}def write_to_file(content):with open('result.txt', 'a', encoding='utf-8') as f_obj:f_obj.write(json.dumps(content, ensure_ascii=False)+'\n')def main():url = 'http://maoyan.com/board/4'html = get_one_page(url)for x in parse_one_page(html):write_to_file(x)main()
程序运行之后,成功输出了result.txt 文件
分页爬取
因为我们需要爬取的是猫眼电影的top100,所以还需要遍历,给链接传入offset 参数,此时添加如下调用:
if __name__=='__main__':for i in range(10):main(offset=i*10)
对main() 方法进行修改,接受一个offset 值作为偏移量,然后构造URL进行爬取。代码如下:
def main(offset):url = 'http://maoyan.com/board/4?offset='+str(offset)html = get_one_page(url)for x in parse_one_page(html):write_to_file(x)
完整代码:
import requests
import re
import json
import time
from requests.exceptions import RequestExceptiondef get_one_page(url):try:headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0','Cookie':'__mta=244153658.1609735789043.1609814345631.1609903887876.9; uuid_n_v=v1; uuid=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _lxsdk_cuid=176cbbad8c4c8-0687fad5143e0b-3e604000-144000-176cbbad8c4c8; _lxsdk=44FD87D04E4811EBB586F7EF3F3BEBB881E6A67E34BF46848671B5C44D132AF8; _csrf=e80757462cd1516a77cd1805be934c54f7d4e90601451188280cb41fd6c4871a; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1609735788,1609764730,1609812449,1609903888; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1609903888; _lxsdk_s=176d5bfd5c7-e23-d69-9d%7C%7C2'}result = requests.get(url, headers=headers)if result.status_code==200:return result.textreturn Noneexcept RequestException:return Nonedef parse_one_page(html):pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name"><.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>', re.S)items = re.findall(pattern,html)for item in items:yield {'index': item[0],'image': item[1],'title': item[2].strip(),'actor': item[3].strip()[3:],'time': item[4].strip()[5:],'score': item[5].strip() +item[6].strip()}def write_to_file(content):with open('result.txt', 'a', encoding='utf-8') as f_obj:f_obj.write(json.dumps(content, ensure_ascii=False)+'\n')def main(offset):url = 'http://maoyan.com/board/4?offset=' + str(offset)html = get_one_page(url)for x in parse_one_page(html):write_to_file(x)if __name__=='__main__':for i in range(10):main(offset=i*10)time.sleep(1)
现在猫眼多了反爬虫,如果速度过快,则会无响应。所以后面加了一个延时等待。
输出结果:
python3网络爬虫开发实战-抓取猫眼电影排行(正则表达式版)相关推荐
- [Python3网络爬虫开发实战] -爬取电影排行数据
爬取猫眼电影排行 利用requests库和正则表达式来抓取猫眼电影TOP100的相关内容,选用正则表达式来作为解析工具. 主要目标 提取出猫眼电影TOP100的电影名称.时间.评分.图片等信息,提取的 ...
- 《崔庆才Python3网络爬虫开发实战教程》学习笔记(3):抓取猫眼电影榜单TOP100电影,并存入Excel表格
本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,如果你也要这套视频教程的话,关注我公众号[小众技术],关注后回复[PYTHON],无套路免费送你一个学习大 ...
- 【Python3网络爬虫开发实战】3-基本库的使用-4抓取猫眼电影排行
本节中,我们利用requests库和正则表达式来抓取猫眼电影TOP100的相关内容.requests比urllib使用更加方便,而且目前我们还没有系统学习HTML解析库,所以这里就选用正则表达式来作为 ...
- 【崔庆才教材】《Python3网络爬虫开发实战》3.4爬取猫眼电影排行代码更正(绕过美团验证码)
前情提要 最近有七八个小伙伴私信问我说崔大神的<Python3网络爬虫开发实战>教材中 "3.4爬取猫眼电影排行" 一节的代码目前不能用. 首先附上崔大神的github ...
- 《崔庆才Python3网络爬虫开发实战教程》学习笔记(5):将爬虫爬取到的数据存储到TXT,Word,Excel,Json等文件中
本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,此套教程共5章,加起来共有34节课,内容非常详细丰富!如果你也要这套视频教程的话,关注我公众号[小众技术] ...
- [Python3网络爬虫开发实战] 7-动态渲染页面爬取-4-使用Selenium爬取淘宝商品
在前一章中,我们已经成功尝试分析Ajax来抓取相关数据,但是并不是所有页面都可以通过分析Ajax来完成抓取.比如,淘宝,它的整个页面数据确实也是通过Ajax获取的,但是这些Ajax接口参数比较复杂,可 ...
- 【Python3网络爬虫开发实战】 1.7-App爬取相关库的安装
[摘要] 除了Web网页,爬虫也可以抓取App的数据.App中的页面要加载出来,首先需要获取数据,而这些数据一般是通过请求服务器的接口来获取的.由于App没有浏览器这种可以比较直观地看到后台请求的工具 ...
- python3网络爬虫开发实战学习笔记(二)------python3 XPATH爬 猫眼电影排名
我最近在看崔庆才老师的<python3 网络爬虫开发实战>觉得挺不错的,上面还有一个 用正则表达式爬取猫眼电影的电影排行榜 我练了一下,感觉不会很难,后来学到了xpath,就想用xpath ...
- [Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图
[Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图 学习笔记--爬取今日头条街拍美图 准备工作 抓取分析 实战演练 学习笔记–爬取今日头条街拍美图 尝试通过分析Ajax请求来抓取 ...
最新文章
- 收藏 | 深度学习中神经网络的可视化解释!
- Atlas Of Cardiovascular Emergencies 心血管急症图集
- idea2020shezhi代码检查级别_ICT技术:阿里巴巴代码缺陷检测探索与实践
- 揭秘阿里秒级百万TPS平台架构实现
- Linux 等待进程结束 wait() 和 waitpid()
- hibernate Restrictions 用法 查询
- Centos Openssl升级
- 在 UIWebView 中如何准确获得页面加载完成的事件
- 分享Android开发的一些工具
- cartographer 3D点云建图教程
- 关于Windows下使用CuteFTP向Ubuntu传文件时提示“请求被拒绝”
- 工业相机录像丢帧的解决方案
- 3D打印技术让实现更多天马行空的创意
- jpress连接数据库mysql_通过Tomcat jpress连接不到数据库
- 【企业微信实现免密登录以及发送消息(企业内部应用)】
- uniapp使用高德地图微信小程序SDK生成地图轨迹
- 前端学习-VUE框架
- 华为交换机和锐捷交换机端口隔离
- django-blog-zinnia添加文本编辑器ckeditor
- 用JAVA编写简单呼叫器餐厅,使用Java编写Palm OS程序的解决方案1