python爬虫 抓取豆瓣电影 电影分类排行榜的所有数据

准备流程

  1. 确认网页是否为动态数据
    右键查看网页源代码中搜你要的数据中的关键词,若搜不出来,就说明是动态数据
  2. 只要是动态数据,直接去抓包
    控制台Network ->xhr -> 点击左下角各个数据包 ->preview,找到你想要的数据所在的那些数据包后 -> Headers -> general ->request-URL:找到后端返给前端的api
    电影总数的request-URL为:https://movie.douban.com/j/chart/top_list_count?type=13&interval_id=100%3A90
  3. 分析headers中查询参数query string params的规律
    比对各个数据包的查询字符串的不同点,看哪些参数是变化的:
    type: 13
    interval_id: 100:90
    action:
    start: 0
    limit: 20
    type: 13
    interval_id: 100:90
    发现start和type是变化的,start表示第几页,从0开始以20递增,type表示电影类型(爱情等),与类型的关系可从首页的html节点中抓取出来
  4. 在地址栏中请求我们抓到的后端传给前端的api包,查看json数据的具体格式
    后端返回给前端的api,返回的是json串,发现此处数据格式为:’[{},{},{}]’

思路

要实现抓取所有电影分类的数据,需要知道每个分类下电影部数的总数,发现这个数据在电影类别页面下也有,而且也是动态数据,也需要抓包获取

详细代码

import requests 
import time 
import random 
from fake_useragent import UserAgent 
import json 
import re 

class DoubanSpider: 	
	def __init__(self): 
		#各分类排行的电影数据json包的api
		self.url = 'https://movie.douban.com/j/chart/top_list?type={}&interval_id=100%3A90&action=&start={}&limit=20' 
		#各分类排行电影的电影总数Json包api
		self.url_1 = 'https://movie.douban.com/j/chart/top_list_count?type={}&interval_id=100%3A90' 
	
	#1. 发请求获取响应的方法
	def get_html(self,url): 
		headers = {'User-Agent':UserAgent().random} 
		html = requests.get(url=url,headers=headers).text 
		return html 
		
	#2. 解析提取电影数据(动态)的方法 
	#动态数据的提取不使用re和xpath,而是分析json包(因为前端使用ajax向后端要数据,后端返给前端的数据是json串) 
	def parse_html(self,url): 
		#拿到的响应内容是Json格式的字符串:'[{},{},{}]' html = self.get_html(url) 
		#从Json串中取出你想要的数据:电影名,得分,年代,并存放到字典中 #将json串转换成python的数据类型:[{title:xxx},{score:xxx},{}] 
		html = self.get_html(url)
		#将json格式的字符串转为Python数据类型
		html = json.loads(html) 
		item = {} 
		#对字典进行遍历赋值,每次遍历赋值都会覆盖修改之前的数据打印出来查看
		for film in html: 
			item['name'] = film['title'] 
			item['score'] =film['score'] 
			item['time'] = film['release_date'] 
			print(item) 
	
	
	#为了拼接url,需要电影类型码这个变量,该方法用于获取电影类型码,发现是数据在静态页面中,使用re解析
	def get_types_dict(self): 
		#类型码数据所在网页
		url = 'https://movie.douban.com/chart' 
		#请求改页面获取响应
		html = self.get_html(url) 
		
		#在页面源代码中找type值和电影类型,使用re解析(方便),源码中的标签如下:  
		#<span><a href="/typerank?type_name=剧情&type=11&interval_id=100:90&action=">剧情</a></span>   
		#写正则,返回的数据格式为:[('type_name','type'),('剧情','11'),(),....]   
		#<span><a href="/typerank.*?type_name=(.*?)&type=(.*?)&interval_id=100:90&action=">.*?</span>   
		p = re.compile('<span><a href="/typerank.*?type_name=(.*?)&type=(.*?)&interval_id=100:90&action=">.*?</span>',re.S)   
		r_list = p.findall(html)

		#将拿到的数据格式:[(),(),...]做成字典
		types_dict = {}
		for r in r_list:
			types_dict[r[0]] = r[1]
			
		return types_dict

	#2. 请求并解析提取各分类排行电影总部数的方法
	def get_total(self,type):
		#请求json包并获取响应
		html = self.get_html(self.url_1.format(type))
		#将json串:{key1:value1,....} 转为python数据类型:字典
		html = json.loads(html)
		#提取电影总量数据
		total = html['total']
		return total

	#启动函数:需要给出请求的url
	def run(self):
		
		#获取电影类型对应类型码的数据,数据格式为字典:{类型1:类型码1,类型2:类型2,。。。。}
		types_dict = self.get_types_dict()
		
		#将所有电影类型输出出来供选择
		menu ={}
		for key in types_dict:
			menu = menu + key + ' | '
		print(menu)
		type = input('请输入用户类型:')

		#获取用户输入类型的type码
		type = types_dict[type]

		total = self.get_total(type)
		for start in range(0,total,20): #第二个参数是想要遍历的总电影数
			#拼接电影数据的json包的url
			url = self.url.format(type,start)
			self.parse_html(url)
			time.sleep(random.uniform(0,1))

if __name__ == '__main__':
	spider = DoubanSpider()
	spider.run() 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值