python爬取豆瓣电影数据

news2024/9/23 17:18:44

目录

一、背景

二、分析网站

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'] = key
                    yield item

4、解析数据

定义parse_data来解析我们的数据,解析电影标题,评分,电影排名,电影类型,发行国家,发行日期,演员人数,评价人数,演员名字,电影图片,电影详情页地址这些字段。

    @staticmethod
    def 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 requests


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()

    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'] = key
                    yield item

    @staticmethod
    def 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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

136 只出现一次的数字

解题思路: \qquad 这道题目明确要求了时间复杂度为O(N),空间复杂度为O(1),不然借助哈希表很容易能够在O(N)的空间复杂度下解决。特殊的要求只能特殊处理,解这道题只能记住异或这种较特殊的运算方式。 \qquad 异或是对二进制数进…

《深入探究 @SpringBootApplication 注解的内部原理》

《深入探究 SpringBootApplication 注解的内部原理》 SpringBootApplication注解涵盖了 Spring Boot 的包扫描原理、自动装配原理等众多重要原理。接下来,我们将对该注解展开深入且详尽的研究。而研究上述原理的关键,在于剖析SpringBootApplication内部…

网上商品订单转手系统bootpf

TOC springboot408网上商品订单转手系统bootpf 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本的…

【SpringBoot】SpringBoot框架的整体环境搭建和使用(整合Mybatis,Druid,Junit4,PageHelper,logback等)

目录 1.介绍 1.1 配置文件 1.2 目录结构 2.基于SpringBoot的SpringMVC 4.整合Mybatis 5.整合Druid连接池 6.整合Junit4 7.整合Logback 8.整合PageHelper 9.SpringBoot整合Thymeleaf ​编辑 【附录】springboot的pom.xml 1.介绍 Spring框架的优点是方便解耦、简化开…

openEuler系统安装Visual Studio Code

openEuler系统安装Visual Studio Code 背景安装密钥和存储库更新包缓存并使用dnf安装包Fedora 22及以上版本旧版本使用yum 安装过程截图安装成功看桌面效果 背景 openEuler(openEuler-24.03-LTS)安装了麒麟UKUI桌面但是没有麒麟软件商店想安装Visual Studio Code 安装密钥和…

计算机毕业设计选什么题目好? springboot 大学志愿填报系统

✍✍计算机毕业编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java、…

东晟时尚服饰文化传承与发展研发中心成立

近期,东晟时尚创新科技(北京)有限公司宣布成立东晟时尚服饰文化传承与发展研发中心,此举标志着公司在促进中国传统文化与现代时尚产业结合方面迈出了关键步伐。 作为一家在时尚科技推广和设计研发应用服务领域具有战略眼光的企业&…

微信云开发云存储 下载全部文件

一、安装 首先按照这个按照好依赖,打开cmd 安装 | 云开发 CloudBase - 一站式后端云服务 npm i -g cloudbase/cli 安装可能遇到的问题 ‘tcb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。-CSDN博客 二、登录 在cmd输入 tcb login 三、…

导出运营数据Excel报表

文章目录 概要整体架构流程技术细节小结 概要 产品原型 在数据统计页面,有一个数据导出的按钮,点击该按钮时,其实就会下载一个文件。这个文件实际上是一个Excel形式的文件,文件中主要包含最近30日运营相关的数据。表格的形式已经…

C语言(16)——初识单链表

1.链表的概念及结构 概念:链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 结构图: 补充说明: 1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续 2、…

【网络】自定义(应用层)协议——序列化和反序列化

我们接着上一篇:http://t.csdnimg.cn/Xt18d 我们之前写的代码都是在应用层的,而TCP是在应用层下面一层的传输层 1.自定义协议(应用层) 1.1.应用层和传输层的关系 应用层和传输层的概述 应用层:位于网络协议的最高层…

Apollo9.0 PNC源码学习之Planning模块—— Lattice规划(四):纵向运动轨迹规划

参考文章: (1)Apollo6.0代码Lattice算法详解——Part5: 生成横纵向轨迹 (2)自动驾驶规划理论与实践Lattice算法详解 0 前言 纵向运动规划主要是车辆的速度规划,对应于车辆油门和刹车的控制 reference_line和reference_line_info的区别及联系:ReferenceLineInfo 结构中…

全网最最最详细Keepalive的详解

1 Keepalived简介 Keepalived是一款开源的、免费的高可用软件,广泛应用于互联网IT企业中,以其轻量级、配置简单、管理方便等特点受到青睐。以下是Keepalived的详细简介: 1.1 基本概念 定义:Keepalived是一个类似于Layer 3、4 &…

Nginx系列-负载均衡

文章目录 Nginx系列-负载均衡1. 负载均衡基础1.1 负载均衡定义1.2 Nginx负载均衡原理 2. 负载均衡策略2.1 轮询(Round Robin)2.2 加权轮询(Weighted Round Robin)2.3 IP哈希(IP Hash)2.4 最少连接&#xff…

JavaEE----Servlet过滤器

前言 在现代Web开发中,Servlet技术是Java EE(Jakarta EE)的核心部分。随着Web应用复杂性的增加,Servlet过滤器(Filter)提供了一种灵活的方法来对请求和响应进行处理 Servlet过滤器是一种特殊的Java对象&a…

C语言钥匙迷宫2.0

目录 开头程序程序的流程图程序游玩的效果结尾 开头 大家好&#xff0c;我叫这是我58。废话不多说&#xff0c;咱们直接开始。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <Windows.h> enum color {Y,B,R …

Linux 开机自动挂载共享文件设置

选择一个要共享的文件 点击确定 -> 确定 启动虚拟机 执行下面的命令 /YumSource 是我选择的共享文件夹&#xff0c;自行替换自已选择的文件夹 mkdir -p /mnt/hgfs cat >> /etc/fstab << EOF .host:/YumSource /mnt/hgfs fuse.vmhgfs-fuse allow_other defaul…

探索生成式AI在文档处理中的应用:llm Whisperer

在现代科技的快速发展中&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;正逐渐改变我们处理文档的方式。虽然许多生成式AI模型在处理文档时表现出色&#xff0c;但面对复杂文档时&#xff0c;大多数开源模型仍显得力不从心。甚至连GPT-4在某些情况下也会遇到…

性能测试-性能监控分析与调优(三)《实战-CPU瓶颈分析、内存问题分析、gc、tomcat性能调优,数据库监控-redis\mysql》

性能监控 使用命令监控 cpu瓶颈分析 top命令 在进行性能测试时使用top命令&#xff0c;界面如下 上图可以看出 - CPU 概况区&#xff1a; %Cpu(s): - us&#xff08;用户进程占用CPU的百分比&#xff09;, 和 sy&#xff08;系统进程占用CPU的百分比&#xff09; 的数…

【16】暴力递归改dp(上)

目录 一.机器人问题 二.最少硬币问题 一.机器人问题 题目&#xff1a;N表示位置1-N&#xff0c;S表示机器人开始位置&#xff0c;e表示结尾位置&#xff0c;k表示机器人必须走k步&#xff0c;问一共有多少种方法&#xff1f; 情况&#xff1a; 如果第1个位置&#xff0c;下次…