Python-入门的第一个爬虫例子
前言: 此文为大家入门爬虫来做一次简单的例子,让大家更直观的来了解爬虫。 本次我们利用 Requests 和正则表达式来抓取豆瓣电影的相关内容。 一、本次目标: 我们要提取出豆瓣电影-正在上映电影名称、评分、图片的信息,提取的站点 URL 为:https://movie.douban.com/cinema/nowplaying/beijing/,提取的结果我们以文件形式保存下来。 二、准备工作 确保已经正确安装 Requests 库,无论是 Windows、Linux 还是 Mac,都可以通过 Pip 这个包管理工具来安装。 安装命令:pip3 install requests 正则表达式相关教程见:正则表达式总结版、正则表达式 三、抓取分析 抓取的目标站点为:https://movie.douban.com/cinema/nowplaying/beijing/,打开之后便可以查看到正在上映的电影信息,如图所示: 20180512142639_result.png 页面中显示的有效信息有影片名称、评分、图片等信息。这样我们获取该页面结果之后再用正则表达式提取出相关信息就可以得到所有正在上映的电影信息了。 四、抓取页面源代码 接下来我们用代码实现抓取页面源代码过程,首先实现一个 get_page() 方法,传入 url 参数,然后将抓取的页面结果返回,然后再实现一个 main() 方法调用一下,初步代码实现如下: def get_page(url): try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: return None def main(): url = "https://movie.douban.com/cinema/nowplaying/beijing/" html = get_page(url) 五、正则提取电影信息 接下来我们回到网页看一下页面的真实源码,在开发者工具中 Network 监听,然后查看一下源代码,如图所示: 20180512142636_result.png 注意这里不要在 Elements 选项卡直接查看源码,此处的源码可能经过 JavaScript 的操作而和原始请求的不同,我们需要从 Network 选项卡部分查看原始请求得到的源码。 查看其中的一个条目的源代码如图所示: 20180512143404_result.png 可以看到一部电影信息对应的源代码是一个 li 节点,我们用正则表达式来提取这里面的一些电影信息,首先我们需要提取它的电影名称信息,而它的电影名称信息是在 class 为 "list-item"的节点后,所以这里利用非贪婪匹配来提取data-title属性的信息,正则表达式写为: <li.*?list-item.*?data-title="(.*?)".*?> 使用相同判断方法来提取data-score属性的信息,正则表达式写为: <li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?> 随后我们需要提取电影的图片,可以看到在a节点内部有img节点,该节点的src属性是图片的链接,所以在这里提取img节点的src属性,所以正则可以改写如下: <li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/> 这样我们一个正则表达式可以匹配一个电影的结果,里面匹配了3个信息,接下来我们通过调用 findall() 方法提取出所有的内容,实现一个 parse_page() 方法如下: def parse_page(html): pattern = re.compile('<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/>', re.S) items = re.findall(pattern, html) for item in items: yield{ 'title': item[0], 'score': item[1], 'image': item[2], } 这样我们就可以成功提取出电影的图片、标题、评分内容了,并把它赋值为一个个的字典,形成结构化数据,运行结果如下: {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2517753454.jpg', 'title': '复仇者联盟3:无限战争', 'score': '8.6'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2517769368.jpg', 'title': '小公主艾薇拉与神秘王国', 'score': '0'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2519994468.jpg', 'title': '后来的我们', 'score': '5.8'} {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2520200484.jpg', 'title': '我是你妈', 'score': '5.1'} {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2520197352.jpg', 'title': '战犬瑞克斯', 'score': '7.0'} 到此为止我们就成功提取了此页的电影信息。 六、写入文件 随后我们将提取的结果写入文件,在这里直接写入到一个文本文件中,通过 json 库的 dumps() 方法实现字典的序列化,并指定 ensure_ascii 参数为 False,这样可以保证输出的结果是中文形式而不是 Unicode 编码,代码实现如下: def write_to_file(content): with open('xiaoxi.txt', 'a', encoding='utf-8')as f: print(type(json.dumps(content))) f.write(json.dumps(content,ensure_ascii=False)) 通过调用 write_to_json() 方法即可实现将字典写入到文本文件的过程,此处的 content 参数就是一部电影的提取结果,是一个字典。 七、整合代码 到此为止,我们 的爬虫就全部完成了,再稍微整理一下,完整的代码如下:源码见git # -*- coding: utf-8 -*- # @Time : 2018/5/12 上午11:37 # @Author : xiaoxi # @File : test.py import json import re import requests from requests import RequestException def get_page(url): try: response = requests.get(url) if response.status_code == 200: return response.text return None except RequestException: return None def parse_page(html): pattern = re.compile('<li.*?list-item.*?data-title="(.*?)".*?data-score="(.*?)".*?>.*?<img.*?src="(.*?)".*?/>', re.S) items = re.findall(pattern, html) for item in items: yield{ 'title': item[0], 'score': item[1], 'image': item[2], } def write_to_file(content): with open('xiaoxi.txt', 'a', encoding='utf-8')as f: # print(type(json.dumps(content))) f.write(json.dumps(content,ensure_ascii=False)) def main(): url = "https://movie.douban.com/cinema/nowplaying/beijing/" html = get_page(url) for item in parse_page(html): print(item) write_to_file(item) if __name__ == '__main__': main() 运行之后,可以看到电影信息也已全部保存到了文本文件中,大功告成! 八、运行结果 最后我们运行一下代码,类似的输出结果如下: {'image': 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2517753454.jpg', 'title': '复仇者联盟3:无限战争', 'score': '8.6'} {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2517769368.jpg', 'title': '小公主艾薇拉与神秘王国', 'score': '0'} ... {'image': 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2519994468.jpg', 'title': '后来的我们', 'score': '5.8'} 中间的部分输出结果已省略,可以看到这样就成功把电影信息爬取下来了。 这时我们再看下文本文件,结果如图所示: 20180512143407_result.png 以上~~你对爬虫有进一步的了解了么? 请继续关注我的爬虫系列~~~