1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python爬虫 抓取豆瓣电影 电影分类排行榜的所有数据

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

时间:2022-07-20 13:22:24

相关推荐

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

准备流程

确认网页是否为动态数据

右键查看网页源代码中搜你要的数据中的关键词,若搜不出来,就说明是动态数据只要是动态数据,直接去抓包

控制台Network ->xhr -> 点击左下角各个数据包 ->preview,找到你想要的数据所在的那些数据包后 -> Headers -> general ->request-URL:找到后端返给前端的api

电影总数的request-URL为:/j/chart/top_list_count?type=13&interval_id=100%3A90分析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节点中抓取出来在地址栏中请求我们抓到的后端传给前端的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包的apiself.url = '/j/chart/top_list?type={}&interval_id=100%3A90&action=&start={}&limit=20' #各分类排行电影的电影总数Json包apiself.url_1 = '/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 = '/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 = pile('<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#启动函数:需要给出请求的urldef 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包的urlurl = self.url.format(type,start)self.parse_html(url)time.sleep(random.uniform(0,1))if __name__ == '__main__':spider = DoubanSpider()spider.run()

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