python爬取豆瓣电影数据
目录
一、背景
二、分析网站
1、ajax请求
三、代码实现
1、导包
2、面向对象实现
3、发送请求
4、解析数据
5、保存数据
6、定义主函数
7、实例化对象运行主函数
8、运行效果
四、以下是全部完整代码
五、报错解决
1、数据库连接报错
2、数据插入报错
一、背景
豆瓣这个网站相信大家并不陌生,大家一定想知道哪些电影类型是比较好看的,哪些电影是评分高的,今天的主题就是教大家爬取豆瓣电影的电影数据。豆瓣网址https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
二、分析网站
1、ajax请求
由于网站是动态的,数据不在页面源代码里,所以我们需要找到数据的接口,首先我们需要进入这个网站,然后键盘按F12打开调试窗口,准备进行抓包,如下图
然后点击浏览器的刷新,就找到了数据的接口,如下图
接下来就是用代码区发送请求拿到数据了。
三、代码实现
1、导包
我们选择用requests库来发送请求,然后用Mysql来保存数据
import pymysql
import requests
2、面向对象实现
我们还是创建一个类,并且定义类的初始化方法,其中url就是我们找到的接口网址,headers就是我们给爬虫加的伪装,里面有cookie和user-agent,可以去响应接口里复制然后写成字典的形式,
movie_type就是我们要爬取的电影类型,值为什么要用一个列表呢?因为这个接口的参数有电影的类型和页数,但是电影类型不是用字符串去请求,而是豆瓣的后端根据电影的类型来划分的某一个数值,也就是列表中的第一个值,那为什么列表中有2个值呢,因为每种电影类型的数量不一样,所以我们需要找到每种类型的电影数量有多少,然后再去请求,这里小伙伴们就不要就写了,小耶已经帮大家写好了,db和cursor就是我们连接的数据库和游标,这里大家一定要加数据库换成自己的用户名和密码,且必须在运行这个文件前创建名叫douban的数据库。
class Douban:def __init__(self):self.url = 'https://movie.douban.com/j/chart/top_list?type={0}&interval_id=100%3A90&action=&start={1}&limit=20'self.headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0','cookie': 'll="108309"; bid=ypF5OtbNlSg; _pk_id.100001.4cf6=76af15049c8cc83a.1723513955.; __yadk_uid=zAARDdLWvW7KZNBKMZVicYIqUHa6uXM6; _vwo_uuid_v2=D3FAC8D3B8E4E71CC8897160A33C91583|6e30c52e71a0b1465cb45852bb98bb8e; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1723597993%2C%22https%3A%2F%2Fcn.bing.com%2F%22%5D; _pk_ses.100001.4cf6=1; ap_v=0,6.0; __utma=30149280.933405728.1723513952.1723513952.1723597993.2; __utmb=30149280.0.10.1723597993; __utmc=30149280; __utmz=30149280.1723597993.2.2.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=223695111.1611865066.1723513955.1723513955.1723597993.2; __utmb=223695111.0.10.1723597993; __utmc=223695111; __utmz=223695111.1723597993.2.2.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/'}self.movie_types = {'剧情': [11, 952], '喜剧': [24, 667], '动作': [5, 412], '爱情': [13, 484],'科幻': [17, 195], '动画': [25, 159],'悬疑': [10, 262], '惊悚': [19, 391], '恐怖': [20, 310], '纪录片': [1, 234],'短片': [23, 336], '情色': [6, 94],'音乐': [14, 78], '歌舞': [7, 60], '家庭': [28, 171], '儿童': [8, 32], '传记': [2, 124],'历史': [4, 132], '战争': [22, 122],'犯罪': [3, 377], '奇幻': [16, 231], '冒险': [15, 255], '灾难': [12, 21], '武侠': [29, 45],'古装': [30, 85], '运动': [18, 53]}self.db = pymysql.connect(host='localhost', user='root', password='123456', database='douban', port=3306,charset='utf8')self.cursor = self.db.cursor()
3、发送请求
定义spyder函数来向接口发送请求
def spyder(self):for key, value in self.movie_types.items():for page in range(0, value[1], 20):print('正在爬取:{0}的第{1}页!'.format(key, page))url = self.url.format(value[0], page)res = requests.get(url=url, headers=self.headers)data = res.json()for item in data:item['type'] = keyyield item
4、解析数据
定义parse_data来解析我们的数据,解析电影标题,评分,电影排名,电影类型,发行国家,发行日期,演员人数,评价人数,演员名字,电影图片,电影详情页地址这些字段。
@staticmethoddef parse_data(data):data_dict = {}for item in data:data_dict['title'] = item['title']data_dict['score'] = float(item['score'])data_dict['rank'] = item['rank']data_dict['types'] = str(item['types'])data_dict['regions'] = item['regions'][0]data_dict['release_date'] = item['release_date']data_dict['actor_count'] = item['actor_count']data_dict['vote_count'] = item['vote_count']data_dict['actors'] = str(item['actors'])data_dict['img'] = item['cover_url']data_dict['url'] = item['url']data_dict['type']=item['type']yield data_dict
5、保存数据
def save(self, data_dict):for item in data_dict:sql = """INSERT INTO movieInfo (title ,score, rank_,movie_type, types, regions, release_date, actor_count, vote_count, actors, img, url)VALUES (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""self.cursor.execute(sql, (item['title'],item['score'],item['rank'],item['type'],item['types'],item['regions'],item['release_date'],item['actor_count'],item['vote_count'],item['actors'],item['img'],item['url'])) # 执行sql语句print(item)self.db.commit() #提交数据到数据库
6、定义主函数
用一个主函数来运行上面我们所定义的功能函数
def run(self):columns = """CREATE TABLE IF NOT EXISTS movieInfo (id INT AUTO_INCREMENT PRIMARY KEY,title varchar(32), score float, rank_ int, movie_type varchar(4) ,types varchar(64), regions char(16),release_date date, actor_count int, vote_count int,actors VARCHAR(128), img VARCHAR(128), url varchar(128)) """self.cursor.execute(columns) # 创建表的字段data = self.spyder() # 运行发送请求函数data_dict = self.parse_data(data) # 运行解析数据函数self.save(data_dict) # 运行保存数据函数self.cursor.close() # 关闭游标self.db.close() # 关闭数据库
7、实例化对象运行主函数
if __name__ == '__main__':douban = Douban()douban.run()
8、运行效果
数据库里的数据,一共有6000多条数据
四、以下是全部完整代码
import pymysql
import requestsclass Douban:def __init__(self):self.url = 'https://movie.douban.com/j/chart/top_list?type={0}&interval_id=100%3A90&action=&start={1}&limit=20'self.headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0','cookie': 'll="108309"; bid=ypF5OtbNlSg; _pk_id.100001.4cf6=76af15049c8cc83a.1723513955.; __yadk_uid=zAARDdLWvW7KZNBKMZVicYIqUHa6uXM6; _vwo_uuid_v2=D3FAC8D3B8E4E71CC8897160A33C91583|6e30c52e71a0b1465cb45852bb98bb8e; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1723597993%2C%22https%3A%2F%2Fcn.bing.com%2F%22%5D; _pk_ses.100001.4cf6=1; ap_v=0,6.0; __utma=30149280.933405728.1723513952.1723513952.1723597993.2; __utmb=30149280.0.10.1723597993; __utmc=30149280; __utmz=30149280.1723597993.2.2.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=223695111.1611865066.1723513955.1723513955.1723597993.2; __utmb=223695111.0.10.1723597993; __utmc=223695111; __utmz=223695111.1723597993.2.2.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/'}self.movie_types = {'剧情': [11, 952], '喜剧': [24, 667], '动作': [5, 412], '爱情': [13, 484],'科幻': [17, 195], '动画': [25, 159],'悬疑': [10, 262], '惊悚': [19, 391], '恐怖': [20, 310], '纪录片': [1, 234],'短片': [23, 336], '情色': [6, 94],'音乐': [14, 78], '歌舞': [7, 60], '家庭': [28, 171], '儿童': [8, 32], '传记': [2, 124],'历史': [4, 132], '战争': [22, 122],'犯罪': [3, 377], '奇幻': [16, 231], '冒险': [15, 255], '灾难': [12, 21], '武侠': [29, 45],'古装': [30, 85], '运动': [18, 53]}self.db = pymysql.connect(host='localhost', user='root', password='123456', database='douban', port=3306,charset='utf8')self.cursor = self.db.cursor()def spyder(self):for key, value in self.movie_types.items():for page in range(0, value[1], 20):print('正在爬取:{0}的第{1}页!'.format(key, page))url = self.url.format(value[0], page)res = requests.get(url=url, headers=self.headers)data = res.json()for item in data:item['type'] = keyyield item@staticmethoddef parse_data(data):data_dict = {}for item in data:data_dict['title'] = item['title']data_dict['score'] = float(item['score'])data_dict['rank'] = item['rank']data_dict['types'] = str(item['types'])data_dict['regions'] = item['regions'][0]data_dict['release_date'] = item['release_date']data_dict['actor_count'] = item['actor_count']data_dict['vote_count'] = item['vote_count']data_dict['actors'] = str(item['actors'])data_dict['img'] = item['cover_url']data_dict['url'] = item['url']data_dict['type']=item['type']yield data_dictdef save(self, data_dict):for item in data_dict:sql = """INSERT INTO movieInfo (title ,score, rank_,movie_type, types, regions, release_date, actor_count, vote_count, actors, img, url)VALUES (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""self.cursor.execute(sql, (item['title'],item['score'],item['rank'],item['type'],item['types'],item['regions'],item['release_date'],item['actor_count'],item['vote_count'],item['actors'],item['img'],item['url']))print(item)self.db.commit()def run(self):columns = """CREATE TABLE IF NOT EXISTS movieInfo (id INT AUTO_INCREMENT PRIMARY KEY,title varchar(32), score float, rank_ int, movie_type varchar(4) ,types varchar(64), regions char(16),release_date date, actor_count int, vote_count int,actors VARCHAR(128), img VARCHAR(128), url varchar(128)) """self.cursor.execute(columns)data = self.spyder()data_dict = self.parse_data(data)self.save(data_dict)self.cursor.close()self.db.close()# SET @@global.sql_mode= '';if __name__ == '__main__':douban = Douban()douban.run()
五、报错解决
1、数据库连接报错
一定在运行这个爬虫文件之前创建叫douban的数据库
create database douban;
连接数据时一定要换成自己的用户名和密码
self.db = pymysql.connect(host='localhost', user='用户名', password='密码', database='douban', port=3306,charset='utf8')
2、数据插入报错
如果出现一下类似报错,在douban的数据库里输入以下命令,然后在运行爬虫文件
报错:pymysql.err.DataError: (1406, "Data too long for column 'actors' at row 1")
SET @@global.sql_mode= '';
如下图,这样就成功解决了
如果帅哥,美女些觉得小耶这篇文章还不错,可以动动大家发财的小手,帮小耶点个赞