抓取猫眼电影上面Top100榜单,抓取的内容有电影名称,主演,上映时间,图片,得分等信息。抓取的内容以文件形式保存,地址为https://maoyan.com/board/4
            
             1.分析
            
             该榜单页面如下
            
            
              
            
            
             拉到底部点击下一页,发现此时的URL变化了。
            
            
              
            
            
             此时的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,查看源码
            
            
              
            
            
             排名第一的霸王别姬的源码如下:
          
            
              
                
                  1
                
                
                  
                  
                
                
                  
                    
                    
                      
                        
                          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)
                              
                            
                            
                           
                        
                      
                     
                  
                
               
            
          
        

