当前位置: 首页 > news >正文

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= '';

如下图,这样就成功解决了

如果帅哥,美女些觉得小耶这篇文章还不错,可以动动大家发财的小手,帮小耶点个赞

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Dynamics 365 如何查看某个自定义实体是谁创建的
  • python之numpy(3 矩阵属性及矩阵运算)
  • 破解 Google 账户注册难题丨0到1学习谷歌广告(1)
  • uniapp实现足球数据分析平台移动端H5
  • js取消焦点事件
  • python中有哪些常用语言成分?
  • 【安全】XSS
  • UniAD_面向规划的自动驾驶
  • OpenCV图像处理——直线拟合并找出拟合直线的起点与端点
  • multimodel ocr dataset
  • 密码学基础---椭圆曲线一文打尽
  • 鸿蒙开发入门day10-组件导航
  • Python办公自动化:使用openpyxl 创建与保存 Excel 工作簿
  • MATLAB 手动实现投影密度法分割建筑物立面 (73)
  • Chart.js:内容、优点及使用方法
  • [PHP内核探索]PHP中的哈希表
  • 时间复杂度分析经典问题——最大子序列和
  • Java IO学习笔记一
  • PHP CLI应用的调试原理
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 前端之React实战:创建跨平台的项目架构
  • 浅谈Golang中select的用法
  • 使用 @font-face
  • 小程序测试方案初探
  • 用Visual Studio开发以太坊智能合约
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • #APPINVENTOR学习记录
  • #include<初见C语言之指针(5)>
  • #NOIP 2014#Day.2 T3 解方程
  • (4)STL算法之比较
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (C语言)字符分类函数
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转载)Google Chrome调试JS
  • *算法训练(leetcode)第四十天 | 647. 回文子串、516. 最长回文子序列
  • .Net Core 中间件与过滤器
  • .Net 知识杂记
  • .NET正则基础之——正则委托
  • @Conditional注解详解
  • @ModelAttribute 注解
  • []Telit UC864E 拨号上网
  • [20161101]rman备份与数据文件变化7.txt
  • [C#]使用C#部署yolov8-seg的实例分割的tensorrt模型
  • [c++] 单例模式 + cyberrt TimingWheel 单例分析
  • [C++初阶]list的模拟实现
  • [ChromeApp]指南!让你的谷歌浏览器好用十倍!
  • [CODE:-5504]没有[SYS.SYSOBJECTS]对象的查询权限
  • [CSS]中子元素在父元素中居中
  • [Datawhale AI夏令营 2024 第四期] 从零入门大模型微调之旅的总结
  • [Electron] 将应用打包成供Ubuntu、Debian平台下安装的deb包
  • [FBCTF2019]RCEService (PCRE回溯绕过和%a0换行绕过)
  • [javaee基础] 常见的javaweb笔试选择题含答案
  • [Mysql-DML数据操作语句]