100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Python爬虫(三):爬取猫眼电影网经典电影TOP100信息并存入本地Markdown文件(上)

Python爬虫(三):爬取猫眼电影网经典电影TOP100信息并存入本地Markdown文件(上)

时间:2024-03-19 23:14:06

相关推荐

Python爬虫(三):爬取猫眼电影网经典电影TOP100信息并存入本地Markdown文件(上)

运行环境:Python3.6.2Pycharm.2

附此爬虫代码GitHub地址:/IMWoolei/MaoYanMovies

==>【效果链接】

正文

分析

需要获取的信息

进入到猫眼网经典电影TOP100页面【链接】

需要抓取的数据有名次,海报,影片名、主演、上映时间以及评分。

网页信息分析

从中可以看到,每一步影片的信息都分别存在于<dd></dd>标签中。

所以只需要使用正则匹配出<dd></dd>标签中我们需要的数据即可。

正则表达式可以写成如下表达式

import repattern = pile('<dd>.*?<i class="board-index.*?>(\d+)</i>.*?<img data-src="(.*?)".*?<p class="name">''<a.*?>(.*?)</a>.*?<p class="star">(.*?)</p>.*?''<p class="releasetime">(.*?)</p>.*?<i class="integer">(.*?)</i><i class="fraction">(.*?)</i>.*?</dd>',re.S)# ① (\d+):匹配一个或多个数字# ② 第一个(.*?):匹配电影海报图片地址# ③ 第二个(.*?):匹配电影名# ④ 第三个(.*?):匹配电影主演# ⑤ 第四个和第五个(.*?):匹配电影评分

代码

(一)将获取到的电影信息写入文本文档中

需要注意的是我们获取到的影片信息JSON数据格式是无法直接写入文本的,所以我们需要先编码成str类型才能够进行写入。

Python3中可以使用json模块来对JSON数据进行编解码,它包含了两个函数:

-json.dumps(): 对数据进行编码。

-json.loads(): 对数据进行解码。

#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : /11/25 15:08 # @File : MaoYan_TOP100.py # @Software: PyCharmimport requestsimport reimport jsonheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36','Referer': '/board/4?offset=0'}# 获取请求页面def getPage(url):try:response = requests.get(url, headers=headers)# print(response.status_code)if response.status_code == 200:return response.textelse:return Noneexcept Exception:return None# 获取电影信息def getInfo(html):# 正则匹配出电影的索引、海报、电影名、主演、评分pattern = pile('<dd>.*?<i class="board-index.*?>(\d+)</i>.*?<img data-src="(.*?)".*?<p class="name">''<a.*?>(.*?)</a>.*?<p class="star">(.*?)</p>.*?''<p class="releasetime">(.*?)</p>.*?<i class="integer">(.*?)</i><i class="fraction">(.*?)</i>.*?</dd>',re.S)items_list = re.findall(pattern, html)for item in items_list:yield {'index': item[0], # 索引'image': item[1], # 海报'name': item[2], # 电影名'actor': item[3].strip()[3:], # 主演'time': item[4].strip()[5:], # 上映时间'score': item[5] + item[6] # 评分}# 采用这种方法写入数据耦合性高# def writeData(content):#fout = open('Movies_Info.txt', mode='a', encoding='utf-8')#for item in content:# fout.write(json.dumps(item, ensure_ascii=False) + '\n')# fout.write('---------------------------\n')#fout.close()# 写入文件中def writeData(field):with open('Movies_Info.txt', 'a', encoding='utf-8') as f:f.write(json.dumps(field, ensure_ascii=False) + '\n') # json.dumps 用于将 Python 对象编码成 JSON 字符串,若对象为字符串是无法写入文本的f.close()if __name__ == '__main__':for num in [i * 10 for i in range(11)]:url = '/board/4?offset=' + str(num)html = getPage(url)for item in getInfo(html):print(item)writeData(item)

运行结果

(二)多进程爬取数据

Python3标准库中的multiprocessing模块提供了Pool类,用于提供指定数量的进程给用户使用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。

import requestsimport reimport jsonfrom multiprocessing import Poolheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}def getPage(url):response = requests.get(url, headers=headers)print(response.status_code)if response.status_code == 200:return response.textelse:return Nonedef getInfo(html):pattern = pile('<dd>.*?<i class="board-index.*?>(\d+)</i>.*?<img data-src="(.*?)".*?<p class="name">''<a.*?>(.*?)</a>.*?<p class="star">(.*?)</p>.*?''<p class="releasetime">(.*?)</p>.*?<i class="integer">(.*?)</i><i class="fraction">(.*?)</i>.*?</dd>',re.S)items_list = re.findall(pattern, html)for item in items_list:yield {'index': item[0],'image': item[1],'name': item[2],'actor': item[3].strip()[3:],'time': item[4].strip()[5:],'score': item[5] + item[6]}def writeData(field):with open('Movies_Info_MP.txt', 'a', encoding='utf-8') as f:f.write(json.dumps(field, ensure_ascii=False) + '\n')f.close()def main(num):url = '/board/4?offset=' + str(num)html = getPage(url)for item in getInfo(html):print(item)writeData(item)if __name__ == '__main__':pool = Pool()pool.map(main, [i * 10 for i in range(10)]) # 与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。pool.close() # 关闭进程池(pool),使其不在接受新的任务pool.join() # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束

运行结果

多进程爬取数据可以提高效率,但是因为多进程的原因,多进程的写入会使写入顺序不一致,虽然字典的索引不会影响数据的取用,但是如果想要对字典进行排序的话,可以参考如下代码:

# 示例字典列表stus = [{"name":"zhangsan", "age":18}, {"name":"lisi", "age":19},{"name":"wangwu", "age":17} ]# 按name排序:>>> stus.sort(key = lambda x:x['name'])>>> stus[{'age': 19, 'name': 'lisi'}, {'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}]# 按age排序:>>> stus.sort(key = lambda x:x['age'])>>> stus[{'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}, {'age': 19, 'name': 'lisi'}]

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。