【python】抓取猫眼电影排行

系统 133 0

抓取猫眼电影上面Top100榜单,抓取的内容有电影名称,主演,上映时间,图片,得分等信息。抓取的内容以文件形式保存,地址为https://maoyan.com/board/4
1.分析
该榜单页面如下
【python】抓取猫眼电影排行_第1张图片
拉到底部点击下一页,发现此时的URL变化了。
【python】抓取猫眼电影排行_第2张图片
此时的URL变为https://maoyan.com/board/4?offset=10,比之前的URL多了参数offset=10,再点击下一页的URL为https://maoyan.com/board/4?offset=20,由此我们发现了规律,Top100,每页展示10部电影,这样100部电影需要请求10次
2.抓取首页
首先来抓取第一页的内容,我们编写一个get_one_page()的方法

            
              import requests

def get_one_page(url):
    response = requests.get(url)
    if response.status_code == 200:
        return response.text
    return None

def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)

main()

            
          

3.正则提取
网页在开发者模式下,network,查看源码
【python】抓取猫眼电影排行_第3张图片
排名第一的霸王别姬的源码如下:

            
              
1 霸王别姬

霸王别姬

主演:张国荣,张丰毅,巩俐

上映时间:1993-01-01

9. 5

可以看到一部电影对应一个 dd 节点,排名信息在 class board-index i 节点内,利用非贪婪匹配来提取 i 节点内的信息,正则表达式为

            
              
.*?board-index.*?>(.*?)

然后提取图片信息,接下来的 a 节点,里面有两个 img 节点,经过检查后发现,第二个 img 节点的 data-src 属性是图片的链接。于是提取第二个 img 节点的 data-src 属性,正则表达式改写如下:

                  
                    
.*?board-index.*?>(.*?).*?data-src="(.*?)"

之后,提取电影名称,在后面的 p 节点内, class name ,之后的 a 节点里

                        
                          
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?)

主演信息在 p 节点下 class star ,上映时间在 p 节点下 class releasetime ,评分在‘p’节点下的’class’为 score ,其中整数部分对应 integer ,小数部分对应为 fraction 。完整的表达式为

                              
                                
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?

这样就可以将一页中10部电影的信息提取出来
定义解析页面的方法为 parse_one_page() ,主要通过正则表达式提取想要的内容

                              
                                def parse_one_page(html):
	pattern = re.compile( '
                                
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
', re.S) items = re.findall(pattern,html) print(items)

提取出来的结果如下:

                              
                                [('1', 'https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c', '霸王别姬', '\n                主演:张国荣,张丰毅,巩俐\n        ', '上映时间:1993-01-01', '9.', '5'), ('2', 'https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c', '肖申克的救赎', '\n                主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿\n        ', '上映时间:1994-09-10(加拿大)', '9.', '5'), ('3', 'https://p0.meituan.net/movie/289f98ceaa8a0ae737d3dc01cd05ab052213631.jpg@160w_220h_1e_1c', '罗马假日', '\n                主演:格利高里·派克,奥黛丽·赫本,埃迪·艾伯特\n        ', '上映时间:1953-09-02(美国)', '9.', '1'), ('4', 'https://p1.meituan.net/movie/6bea9af4524dfbd0b668eaa7e187c3df767253.jpg@160w_220h_1e_1c', '这个杀手不太冷', '\n                主演:让·雷诺,加里·奥德曼,娜塔莉·波特曼\n        ', '上映时间:1994-09-14(法国)', '9.', '5'), ('5', 'https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@160w_220h_1e_1c', '泰坦尼克号', '\n                主演:莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩\n        ', '上映时间:1998-04-03', '9.', '5'), ('6', 'https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', '唐伯虎点秋香', '\n                主演:周星驰,巩俐,郑佩佩\n        ', '上映时间:1993-07-01(中国香港)', '9.', '1'), ('7', 'https://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', '魂断蓝桥', '\n                主演:费雯·丽,罗伯特·泰勒,露塞尔·沃特森\n        ', '上映时间:1940-05-17(美国)', '9.', '2'), ('8', 'https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c', '乱世佳人', '\n                主演:费雯·丽,克拉克·盖博,奥利维娅·德哈维兰\n        ', '上映时间:1939-12-15(美国)', '9.', '1'), ('9', 'https://p1.meituan.net/movie/ba1ed511668402605ed369350ab779d6319397.jpg@160w_220h_1e_1c', '天空之城', '\n                主演:寺田农,鹫尾真知子,龟山助清\n        ', '上映时间:1992', '9.', '1'), ('10', 'https://p0.meituan.net/movie/b0d986a8bf89278afbb19f6abaef70f31206570.jpg@160w_220h_1e_1c', '辛德勒的名单', '\n                主演:连姆·尼森,拉尔夫·费因斯,本·金斯利\n        ', '上映时间:1993-12-15(美国)', '9.', '2')]

                              
                            

我们处理一下结果,让它以字典的形式呈现:

                              
                                def parse_one_page(html):
	pattern = re.compile( '
                                
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
', re.S) items = re.findall(pattern,html) for item in items: yield{ '排名':item[0], '图片':item[1], '电影名称':item[2], '演员':item[3].strip()[3:], '上映时间':item[4].strip()[5:], '评分':item[5]+item[6]}

运行结果如下:

                              
                                {'排名': '1', '图片': 'https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c', '电影名称': '霸王别姬', '演员': '张国荣,张丰毅,巩俐', '上映时间': '1993-01-01', '评分': '9.5'}
{'排名': '2', '图片': 'https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c', '电影名称': '肖申克的救赎', '演员': '蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿', '上映时间': '1994-09-10(加拿大)', '评分': '9.5'}
{'排名': '3', '图片': 'https://p0.meituan.net/movie/289f98ceaa8a0ae737d3dc01cd05ab052213631.jpg@160w_220h_1e_1c', '电影名称': '罗马假日', '演员': '格利高里·派克,奥黛丽·赫本,埃迪·艾伯特', '上映时间': '1953-09-02(美国)', '评分': '9.1'}
{'排名': '4', '图片': 'https://p1.meituan.net/movie/6bea9af4524dfbd0b668eaa7e187c3df767253.jpg@160w_220h_1e_1c', '电影名称': '这个杀手不太冷', '演员': '让·雷诺,加里·奥德曼,娜塔莉·波特曼', '上映时间': '1994-09-14(法国)', '评分': '9.5'}
{'排名': '5', '图片': 'https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@160w_220h_1e_1c', '电影名称': '泰坦尼克号', '演员': '莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩', '上映时间': '1998-04-03', '评分': '9.5'}
{'排名': '6', '图片': 'https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', '电影名称': '唐伯虎点秋香', '演员': '周星驰,巩俐,郑佩佩', '上映时间': '1993-07-01(中国香港)', '评分': '9.1'}
{'排名': '7', '图片': 'https://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', '电影名称': '魂断蓝桥', '演员': '费雯·丽,罗伯特·泰勒,露塞尔·沃特森', '上映时间': '1940-05-17(美国)', '评分': '9.2'}
{'排名': '8', '图片': 'https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c', '电影名称': '乱世佳人', '演员': '费雯·丽,克拉克·盖博,奥利维娅·德哈维兰', '上映时间': '1939-12-15(美国)', '评分': '9.1'}
{'排名': '9', '图片': 'https://p1.meituan.net/movie/ba1ed511668402605ed369350ab779d6319397.jpg@160w_220h_1e_1c', '电影名称': '天空之城', '演员': '寺田农,鹫尾真知子,龟山助清', '上映时间': '1992', '评分': '9.1'}
{'排名': '10', '图片': 'https://p0.meituan.net/movie/b0d986a8bf89278afbb19f6abaef70f31206570.jpg@160w_220h_1e_1c', '电影名称': '辛德勒的名单', '演员': '连姆·尼森,拉尔夫·费因斯,本·金斯利', '上映时间': '1993-12-15(美国)', '评分': '9.2'}

                              
                            

4.写入网页
我们将提取的结果写入文件,这里直接写入到一个文本文件中。这里通过 JSON库 dumps() 方法实现字典的序列化,并指定 ensure_ascii 参数为 False ,这样可以保证输出结果是中文形式而不是 Unicode 编码。代码如下:

                              
                                def write_to_json(content):
	with open('result.txt','a') as f:
		print(type(json.dumps(content)))
		f.write(json.dumps(content,ensure_ascii=False)+'\n')

                              
                            

content 为提取下来的一部电影的信息

5.整合代码

                              
                                def main():
	url = 'http://maoyan.com/board/4'
	html = get_one_page(url)
	for item in parse_one_page(html):
		print(item)
		write_to_json(item)

                              
                            

实现了将第一页的十部电影爬取下来,保存到本地文件中。
6.分页爬取
我们想要爬取的是前100部电影,所以还需要遍历一下,给这个链接传入offset参数,实现其他90部电影的爬取

                              
                                if __name__ == '__main__':
    for i in range(10):
        main(offset=i * 10)

                              
                            

那么在定义 main() 时需要给它一个 offset 参数

                              
                                def main(offset):
	url = 'http://maoyan.com/board/4?offset=' + str(offset)
	html = get_one_page(url)
	for item in parse_one_page(html):
		print(item)
		write_to_json(item)

                              
                            

完整代码

                              
                                import requests
import re
import json

def get_one_page(url):
	response = requests.get(url)
	if response.status_code == 200:
		return response.text
	return None	
	
def parse_one_page(html):
	pattern = re.compile( '
                                
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
', re.S) items = re.findall(pattern,html) for item in items: yield{ '排名':item[0], '图片':item[1], '电影名称':item[2], '演员':item[3].strip()[3:], '上映时间':item[4].strip()[5:], '评分':item[5]+item[6]} def write_to_json(content): with open('result.txt','a') as f: print(type(json.dumps(content))) f.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 item in parse_one_page(html): print(item) write_to_json(item) if __name__ == '__main__': for i in range(10): main(offset=i * 10)

效果如下:
【python】抓取猫眼电影排行_第4张图片
文本文件内容如下

完成。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请请扫描上面二维码支持博主1元、2元、5元等您想捐的金额吧,狠狠点击下面给点支持吧

发表我的评论
最新评论 总共0条评论