自己做网站广告法,驾校官方网站 模板,wordpress投稿者用户权限,全国ip地址查询本例中#xff0c;利用 requests 库和正则表达式来抓取猫眼电影 TOP100 的相关内容。
1.目标
提取出猫眼电影 TOP100 的电影名称、时间、评分、图片等信息#xff0c;提取的站点 URL 为 http://maoyan.com/board/4#xff0c;提取的结果会以文件形式保存下来。
2.抓取分析…本例中利用 requests 库和正则表达式来抓取猫眼电影 TOP100 的相关内容。
1.目标
提取出猫眼电影 TOP100 的电影名称、时间、评分、图片等信息提取的站点 URL 为 http://maoyan.com/board/4提取的结果会以文件形式保存下来。
2.抓取分析
抓取页面如下 页面中显示的有效信息有影片名称、主演、上映时间、上映地区、评分、图片等信息。 将网页滚动到最下方可以发现有分页的列表。直接点击第 2 页观察页面的 URL 和内容发生了怎样的变化。
第一页urlhttps://www.maoyan.com/board/4?offset0
第二页urlhttps://www.maoyan.com/board/4?offset10
可以发现offset从0变成了10而每一页都显示了十部电影由此可以总结出规律offset 代表偏移量值。如果想获取 TOP100 电影只需要分开请求 10 次而 10 次的 offset 参数分别设置为 0、10、20…90 即可这样获取不同的页面之后再用正则表达式提取出相关信息就可以得到 TOP100 的所有电影信息了。
3.抓取首页
首先抓取第一页的内容。实现 get_one_page 方法并给它传入 url 参数。然后将抓取的页面结果返回。初步代码实现如下
import requests
import redef get_one_page(url):headers{User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36}responserequests.get(url,headersheaders)if response.status_code200:return response.textreturn Nonedef main():htmlget_one_page(https://www.maoyan.com/board/4?offset0)print(html)main()4.正则提取
回到网页看一下页面的真实源码。在开发者模式下的 Network 监听组件中查看源代码。、 注意这里不要在 Elements 选项卡中直接查看源码因为那里的源码可能经过 JavaScript 操作而与原始请求不同而是需要从 Network 选项卡部分查看原始请求得到的源码。
其中一个条目的源代码如下 可以看到一部电影信息对应的源代码是一个 dd 节点我们用正则表达式来提取这里面的一些电影信息。首先需要提取它的排名信息。而它的排名信息是在 class 为 board-index 的 i 节点内这里利用非贪婪匹配来提取 i 节点内的信息正则表达式写为
result_rankingre.findall(dd.*?board-index.*?(.*?)/i,html,re.S)随后需要提取电影的图片。
result_imgre.findall(img\sdata-src(.*?),html,re.S)再往后需要提取电影的名称.
result_namere.findall(classname.*?data-val.*?(.*?)/a,html,re.S)再提取主演、发布时间、评分等内容时都是同样的原理。最后正则表达式写为
result_starre.findall(classstar.*?(.*?)/p,html,re.S)
result_star [star.strip() for star in result_star]
result_timere.findall(classreleasetime.*?(.*?)/p,html,re.S)
result_scorere.findall(classscore.*?integer.*?(.*?)/i.*?fraction(.*?)/i,html,re.S)由于这里的主演前后带有空格和换行符使用strip去除。
到这里我们就可以将一部电影的6个数据提取出来但这样还不够数据比较杂乱我们再将匹配结果处理一下生成字典如下
index0
result{ranking:result_ranking[index],img:result_img[index],name:result_name[index],star:result_star[index],time:result_time[index],score:result_score[index]}5.写入文件
随后我们将提取的结果写入文件这里直接写入到一个文本文件中。这里通过 JSON 库的 dumps 方法实现字典的序列化并指定 ensure_ascii 参数为 False这样可以保证输出结果是中文形式而不是 Unicode 编码。代码如下
import json
def write_to_file(content): with open(result.txt, a, encodingutf-8) as f: print(type(json.dumps(content))) f.write(json.dumps(content, ensure_asciiFalse)\n)6.整合代码分页爬取
因为我们需要抓取的是 TOP100 的电影所以还需要遍历一下给这个链接传入 offset 参数实现其他 90 部电影的爬取此时添加如下调用即可
import time
for i in range(10):urlhttps://www.maoyan.com/board/4?offsetstr(i*10)time.sleep(0.5)htmlget_one_page(url)result_rankingre.findall(dd.*?board-index.*?(.*?)/i,html,re.S)result_imgre.findall(img\sdata-src(.*?),html,re.S)result_namere.findall(classname.*?data-val.*?(.*?)/a,html,re.S)result_starre.findall(classstar.*?(.*?)/p,html,re.S)result_star [star.strip() for star in result_star]result_timere.findall(classreleasetime.*?(.*?)/p,html,re.S)result_scorere.findall(classscore.*?integer.*?(.*?)/i.*?fraction(.*?)/i,html,re.S)for index in range(10):result{ranking:result_ranking[index],img:result_img[index],title:result_name[index],star:result_star[index],reaease_time:result_time[index],score:result_score[index]}write_to_file(result)注意每次请求页面后加入暂停时间否则会被反爬机制阻止需要更换新的user-agent和cookie。
爬取结果如下 番外使用正则表达式对象改写
在上面的正则提取中我们为每一条要提取的信息都编写了一个正则表达式进行提取可以利用compile方法编写正则表达式对象一次将六条信息全部提取出来下面进行简化我们将要提取的信息用一条正则表达式描述使用group逐个提取出来。
可以看到一部电影信息对应的源代码是一个 dd 节点我们用正则表达式来提取这里面的一些电影信息。首先需要提取它的排名信息。而它的排名信息是在 class 为 board-index 的 i 节点内这里利用非贪婪匹配来提取 i 节点内的信息正则表达式写为
dd.*?board-index.*?(.*?)/i随后需要提取电影的图片。可以看到后面有 a 节点其内部有两个 img 节点。经过检查后发现第二个 img 节点的 data-src 属性是图片的链接。这里提取第二个 img 节点的 data-src 属性在原有正则表达式基础可以改写如下
dd.*?board-index.*?(.*?)/i.*?data-src(.*?)再往后需要提取电影的名称它在后面的 p 节点内class 为 name。所以可以用 name 做一个标志位然后进一步提取到其内 a 节点的正文内容此时正则表达式改写如下
dd.*?board-index.*?(.*?)/i.*?data-src(.*?).*?name.*?a.*?(.*?)/a再提取主演、发布时间、评分等内容时都是同样的原理。最后正则表达式写为
dd.*?board-index.*?(.*?)/i.*?data-src(.*?).*?name.*?a.*?(.*?)/a.*?star.*?(.*?)/p.*?releasetime.*?(.*?)/p.*?integer.*?(.*?)/i.*?fraction.*?(.*?)/i.*?/dd接下来通过调用 findall 方法提取出所有的内容。
pattern re.compile(dd.*?board-index.*?(.*?)/i.*?data-src(.*?).*?name.*?a.*?(.*?)/a.*?star.*?(.*?)/p.*?releasetime.*?(.*?)/p.*?integer.*?(.*?)/i.*?fraction.*?(.*?)/i.*?/dd,re.S)items re.findall(pattern, html)输出结果如下
[(1, http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg160w_220h_1e_1c, 霸王别姬 , \n 主演张国荣张丰毅巩俐 \n , 上映时间1993-01-01(中国香港), 9., 6), (2, http://p0.meituan.net/movie/__40191813__4767047.jpg160w_220h_1e_1c, 肖申克的救赎 , \n 主演蒂姆・罗宾斯摩根・弗里曼鲍勃・冈顿 \n , 上映时间1994-10-14(美国), 9., 5), (3, http://p0.meituan.net/movie/fc9d78dd2ce84d20e53b6d1ae2eea4fb1515304.jpg160w_220h_1e_1c, 这个杀手不太冷 , \n 主演让・雷诺加里・奥德曼娜塔莉・波特曼 \n , 上映时间1994-09-14(法国), 9., 5), (4, http://p0.meituan.net/movie/23/6009725.jpg160w_220h_1e_1c, 罗马假日 , \n 主演格利高利・派克奥黛丽・赫本埃迪・艾伯特 \n , 上映时间1953-09-02(美国), 9., 1), (5, http://p0.meituan.net/movie/53/1541925.jpg160w_220h_1e_1c, 阿甘正传 , \n 主演汤姆・汉克斯罗宾・怀特加里・西尼斯 \n , 上映时间1994-07-06(美国), 9., 4), (6, http://p0.meituan.net/movie/11/324629.jpg160w_220h_1e_1c, 泰坦尼克号 , \n 主演莱昂纳多・迪卡普里奥凯特・温丝莱特比利・赞恩 \n , 上映时间1998-04-03, 9., 5), (7, http://p0.meituan.net/movie/99/678407.jpg160w_220h_1e_1c, 龙猫 , \n 主演日高法子坂本千夏糸井重里 \n , 上映时间1988-04-16(日本), 9., 2), (8, http://p0.meituan.net/movie/92/8212889.jpg160w_220h_1e_1c, 教父 , \n 主演马龙・白兰度阿尔・帕西诺詹姆斯・凯恩 \n , 上映时间1972-03-24(美国), 9., 3), (9, http://p0.meituan.net/movie/62/109878.jpg160w_220h_1e_1c, 唐伯虎点秋香 , \n 主演周星驰巩俐郑佩佩 \n , 上映时间1993-07-01(中国香港), 9., 2), (10, http://p0.meituan.net/movie/9bf7d7b81001a9cf8adbac5a7cf7d766132425.jpg160w_220h_1e_1c, 千与千寻 , \n 主演柊瑠美入野自由夏木真理 \n , 上映时间2001-07-20(日本), 9., 3)]