【Python网络爬虫案例】python爬虫之爬取豆瓣电影信息

news2025/1/20 18:24:58

🔗 运行环境:PYTHON

🚩 撰写作者:左手の明天

🥇 精选专栏:《python》

🔥  推荐专栏:《算法研究》

#### 防伪水印——左手の明天 ####

💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗

💗今天更新系列【python网络爬虫案例】—— 爬取豆瓣电影信息💗

📆  最近更新:2024 年 08 月 04 日,左手の明天的第 344 篇原创博客

📚 更新于专栏:python网络爬虫

#### 防伪水印——左手の明天 ####


在互联网时代,信息获取变得越来越便捷。如果对电影信息感兴趣,那么可以通过Python编程语言来爬取豆瓣电影的相关信息。下面将介绍如何使用Python爬取豆瓣电影信息的步骤。

一、前言

豆瓣是一个电影资讯网站,用户可以在网站上查找电影信息、评论电影等。我们希望通过爬虫程序获取豆瓣电影的名称、评分和简介等信息,以便进行数据分析或制作推荐系统。

在Python中爬取豆瓣电影信息,我们可以使用多种库,比如requests来发送HTTP请求,以及BeautifulSouplxml来解析HTML内容。但是,需要注意的是,豆瓣网站有反爬虫机制,频繁请求可能会被封IP。因此,在编写爬虫时应当注意请求频率,适当添加请求头,以及考虑使用代理。 

二、基本开发环境

Python 3.9

Pycharm

三、相关模块的使用

  1. from bs4 import BeautifulSoup # 网页解析,获取数据

  2. import re # 正则表达式,进行文字匹配

  3. import Ch  # 自定义模块,提供网络请求和缓存目录获取功能

  4. import requests # 网络

  5. import csv # 数据交换模式,它使用逗号作为字段之间的分隔符,并以纯文本形式存储表格数据。

二、爬取豆瓣电影信息方法

2.1 明确需求

爬取豆瓣Top250排行电影信息,涉及信息包含如下:

1、电影详情;2、电影图片;3、电影名字;4、导演、主演;5、年份、国家、类型;6、评分、评价人数;7、电影简介

下面是展示几种方法展示如何使用爬取豆瓣电影Top 250的信息:

2.2 使用requests和BeautifulSoup库进行爬取

(1)爬取步骤

•使用Python的Requests库发送HTTP请求获取豆瓣电影网页的HTML源码。

•使用BeautifulSoup库解析HTML源码,提取电影名称、评分和简介等信息。

•使用数据库或文件存储提取的电影信息,以便后续使用或分析。

(2) 安装所需库

在Python中,可以使用requests库来发送HTTP请求,使用BeautifulSoup库来解析HTML页面。因此,需要先安装这两个库:

pip install requests beautifulsoup4

(3)爬取代码

# 导入必要的模块
import csv
from bs4 import BeautifulSoup
import Ch  # 自定义模块,提供网络请求和缓存目录获取功能
 
# 主函数
def main(url):
    # 使用Ch模块的get_web_request方法获取网页的HTML内容
    html = Ch.get_web_request(url)
    # 创建BeautifulSoup对象,用于解析HTML
    soup = BeautifulSoup(html, 'html.parser')
    # 获取页面上的每个.item元素(代表每部电影)
    for element in soup.select('.item'):
        # 获取排行榜的序号
        num = element.select_one('em').text
        # 获取电影名称
        zw_name = element.select_one('span.title').text
        # 获取电影详情链接
        urls = element.select_one('div.hd a')['href']
        # 获取评分
        star_rating = element.select('div.star span')[1].text
        # 获取评价人数,去除“人评价”文本
        star_num = element.select('div.star span')[3].text.replace('人评价', '')
        # 获取剧情评语,如果不存在则为空字符串
        content = element.select_one('p span.inq').text if element.select_one('p span.inq') is not None else ''
        # 将抓取的数据打包成元组
        tuples = (num, zw_name, urls, star_rating, star_num, content)
        # 将元组写入CSV文件
        csv_writer.writerow(tuples)
        # 打印当前处理的元组信息
        print(tuples)
 
if __name__ == '__main__':
    # 打开CSV文件,写模式,UTF-8编码,去除空行
    with open(Ch.get_dir_cache_to('test.csv'), mode='w', encoding='utf-8', newline='') as f:
        # 创建CSV写入器
        csv_writer = csv.writer(f)
        # 写入表头
        csv_writer.writerow(['序号', '电影名称', '电影详情链接', '评分', '评价人数', '剧情概况'])
        # 循环抓取前10页的数据
        for i in range(10):
            # 调用main函数,传入当前页的URL
            main(f'https://movie.douban.com/top250?start={i * 25}&filter=')
            # 打印完成提示
            print(f'第{i + 1}页爬取完毕.')

2.3 使用XPath进行爬取

使用XPath来爬取豆瓣电影排行榜是一个常见且有效的方法,因为XPath提供了一种强大的方式来在XML和HTML文档中查找信息。

在Python中,可以结合使用requests库来发送HTTP请求获取网页内容,以及lxmlBeautifulSoup库(尽管BeautifulSoup本身不直接支持XPath,但可以与lxml解析器一起使用以支持XPath)来解析HTML并应用XPath表达式提取所需的数据。

以下是一个使用requestslxml(通过etree模块)来爬取豆瓣电影Top 250排行榜的简单示例:

import requests
from lxml import etree
 
def get_douban_top_movies(url, page=1):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
    }
 
    try:
        response = requests.get(url.format(page), headers=headers)
        response.raise_for_status()  # 如果响应状态码不是200,则引发HTTPError异常
 
        # 使用lxml的etree解析HTML
        html = etree.HTML(response.text)
 
        # XPath表达式用于查找电影列表中的每个电影项
        movie_items = html.xpath('//div[@class="item"]')
 
        movie_list = []
        for item in movie_items:
            title = item.xpath('.//span[@class="title"]/text()')[0].strip()
            info = item.xpath('.//div[@class="bd"]/p/text()')[0].strip()
            rating, num_ratings = map(lambda x: x.strip(), info.split('/', 1))
            try:
                quote = item.xpath('.//span[@class="inq"]/text()')[0].strip()
            except IndexError:
                quote = ''
 
            movie_list.append({
                'title': title,
                'rating': rating,
                'num_ratings': num_ratings,
                'quote': quote
            })
 
        return movie_list
    except requests.RequestException as e:
        print(e)
        return []
 
if __name__ == '__main__':
    url = 'https://movie.douban.com/top250?start={}&filter='
    for page in range(0, 250, 25):  # 豆瓣Top 250是分页的,每页25部电影
        movies = get_douban_top_movies(url, page)
        for movie in movies:
            print(movie)
        # 根据需要,可以在这里添加将数据保存到文件或数据库的逻辑

注意

  1. 上述代码中的XPath表达式//div[@class="item"]是用来查找每部电影的容器元素。这个XPath假设豆瓣的HTML结构是这样的,但实际上这个结构可能会随着时间的推移而改变。

  2. 豆瓣网站有反爬虫措施,频繁请求可能会被封IP。因此,在实际应用中,你应该考虑添加请求间隔(例如使用time.sleep()),使用代理等策略。

  3. 示例中的url.format(page)用于构建分页的URL。豆瓣Top 250每页显示25部电影,所以你可以通过改变start参数的值来遍历所有页面。

  4. 根据豆瓣的当前布局,我使用了XPath .//span[@class="title"]/text() 来提取电影标题,.//div[@class="bd"]/p/text() 来提取评分和评分人数,以及 .//span[@class="inq"]/text()(如果存在)来提取电影简介。然而,随着网站布局的更新,这些XPath表达式可能需要调整。

2.4 使用正则表达式进行爬取

虽然正则表达式(Regular Expressions)在文本处理中非常强大,但它们通常不是解析HTML或XML文档的最佳工具,因为这些文档的结构化特性(如标签和属性)更适合使用如XPath或CSS选择器这样的解析技术。然而,如果你只是需要从一个非常简单的HTML结构或者特定模式的文本中提取数据,或者作为学习的目的,使用正则表达式也是可行的。

对于豆瓣电影排行榜,由于HTML结构相对复杂,直接使用正则表达式可能会变得非常繁琐且易出错。但是,如果我们假设某个特定部分的数据可以通过正则表达式来提取(例如,从某个JavaScript变量中直接提取JSON数据,这在某些情况下可能会发生),我们可以编写一个简化的例子。

然而,在大多数情况下,我们不会直接从HTML标签中提取信息,而是会提取一些更简单的文本模式,比如页面上的某个特定段落或链接的文本。但请注意,对于豆瓣电影排行榜这样的动态内容,数据往往是通过JavaScript动态加载的,因此直接从HTML源代码中可能找不到所有数据。

不过,为了演示如何使用正则表达式来提取一些简单信息(假设这些信息是静态的或者已经以某种方式提取到了文本中),我们可以编写一个简化的Python脚本。但请注意,这个脚本不会直接爬取豆瓣电影排行榜,因为它不会处理JavaScript加载的数据。

import re
 
# 假设这是从某处获取的HTML页面内容(实际上你需要使用requests库来获取它)
# 这里我们使用一个简化的字符串来模拟HTML内容
html_content = '''
<div>
    <h2>电影名称1</h2>
    <p>评分: 9.2</p>
    <p>评价人数: 123,456</p>
</div>
<div>
    <h2>电影名称2</h2>
    <p>评分: 8.5</p>
    <p>评价人数: 65,432</p>
</div>
'''
 
# 使用正则表达式提取电影名称、评分和评价人数
pattern = r'<h2>(.*?)</h2>.*?<p>评分: (\d+\.\d+)</p>.*?<p>评价人数: (\d+,\d+)</p>'
matches = re.findall(pattern, html_content, re.DOTALL)
 
for match in matches:
    title, rating, num_ratings = match
    print(f"电影名称: {title.strip()}, 评分: {rating}, 评价人数: {num_ratings}")
 
# 注意:这里的正则表达式和代码只是为了演示目的
# 实际上,对于复杂的HTML文档,你应该使用像BeautifulSoup或lxml这样的库

但请记住,上面的代码示例并不是用来爬取豆瓣电影排行榜的,因为它不会处理JavaScript动态加载的内容,也不会处理豆瓣网站的反爬虫机制。

对于豆瓣电影排行榜的爬取,你通常需要使用像Selenium这样的工具来模拟浏览器行为,或者分析网络请求来找到实际包含电影数据的API接口,并使用requests库来调用这些API。同时,你还需要处理Cookie、User-Agent等HTTP头部信息,以及可能的反爬虫措施。

 爬取的完整代码如下:

# 导入必要的模块
import csv
import re
from bs4 import BeautifulSoup
import Ch  # 假设Ch模块提供了一些自定义功能,如网络请求和文件路径获取
 
# 定义主函数,负责爬取指定URL的网页数据
def main(url):
    # 使用Ch模块的get_web_request方法发送网络请求并获取响应内容
    html = Ch.get_web_request(url)
    # 使用BeautifulSoup解析HTML内容
    soup = BeautifulSoup(html, 'html.parser')
    # 查找所有class为'item'的div标签,即每一部电影的条目
    for item in soup.find_all('div', class_='item'):
        # 使用正则表达式提取电影详情链接
        info_01 = re.findall(re.compile(r'<a href="(.*?)">'), str(item))[0]
        # 提取电影封面图片链接
        info_02 = re.findall(re.compile(r'<img.*src="(.*?)"', re.S), str(item))[0]
        # 提取电影标题(中文名和英文名),可能有两个标题
        title = re.findall(re.compile(r'<span class="title">(.*)</span>'), str(item))
        # 根据标题数量,设置中文名和外文名
        if len(title) == 2:
            info_03 = title[0]  # 中文名
            info_04 = title[1].replace('/', '')  # 英文名,去除斜杠
        else:
            info_03 = title[0]  # 中文名
            info_04 = ' '  # 如果只有一个标题,英文名留空
        # 提取评分
        info_05 = re.findall(re.compile(r'<span class="rating_num" property="v:average">(.*)</span>'), str(item))[0]
        # 提取评价人数
        info_06 = re.findall(re.compile(r'<span>(\d*)人评价</span>'), str(item))[0]
        # 提取剧情概况,可能不存在
        inq = re.findall(re.compile(r'<span class="inq">(.*)</span>'), str(item))
        if len(inq) == 0:
            info_07 = ' '  # 如果没有概况,留空
        else:
            info_07 = inq[0].replace('。', '')  # 去除句点
        # 提取更多信息,如导演、演员等,可能存在换行和斜杠
        bd = re.findall(re.compile(r'<p class="">(.*?)</p>', re.S), str(item))[0]
        # 清理换行符和多余空格
        bd = re.sub('<br(\s+)?/>(\s+)?', '', bd)
        bd = re.sub('/', '', bd)
        info_08 = bd.strip()  # 去除首尾空格
        # 将提取的信息打包成元组
        tuples = (info_01, info_02, info_03, info_04, info_05, info_06, info_07, info_08)
        # 将元组写入CSV文件
        csv_writer.writerow(tuples)
        # 打印当前处理的元组信息
        print(tuples)
 
if __name__ == '__main__':
    # 打开CSV文件,写模式,UTF-8编码,无空行
    with open(Ch.get_dir_cache_to('test.csv'), mode='w', encoding='utf-8', newline='') as f:
        # 创建CSV写入器
        csv_writer = csv.writer(f)
        # 写入表头
        csv_writer.writerow(['电影详情链接', '图片链接', '影片中文名', '影片外国名', '评分', '评价人数', '剧情概况', '相关信息'])
        # 循环爬取10页数据
        for i in range(10):
            # 调用main函数,传入当前页的URL
            main(f'https://movie.douban.com/top250?start={i * 25}&filter=')
            # 打印完成提示
            print(f'第{i + 1}页爬取完毕.')

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

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

相关文章

【C语言】计算四则运算,中缀表达式转换为后缀表达式

C语言编程—中缀表达式转换为后缀表达式 思路&#xff1a; 中缀转后缀保存结果栈&#xff1a;stack&#xff0c;保存数据和-*/ 操作符栈&#xff1a;op_stack&#xff0c;保存-*/() 场景一&#xff1a;遇到数据&#xff0c;直接入栈stack 场景二&#xff1a;遇到"(&qu…

海康笔试题

1. 2. 块设备&#xff1a;磁盘设备驱动、SD设备驱动 字符设备&#xff1a;终端设备驱动 网络设备&#xff1a;网络设备驱动 &#xff08;1&#xff09;linux操作系统驱动程序分为三大类&#xff1a;字符设备驱动、快设备驱动和网络设备驱动 &#xff08;2&#xff09;字符设…

2024 年华数杯全国大学生数学建模竞赛C 题 老外游中国 完整思路 源代码 模型结果(仅供学习)

最近&#xff0c;“city 不 city”这一网络流行语在外国网红的推动下备受关注。随着我国过境免签政策的落实&#xff0c;越来越多外国游客来到中国&#xff0c;通过网络平台展示他们在华旅行的见闻&#xff0c;这不仅推动了中国旅游业的发展&#xff0c;更是在国际舞台上展现了…

基于X86+FPGA助力实现电力系统的智能监测与高效管理

电力监控 信迈提供基于Intel平台、Xilinx平台、Rockchip平台、NXP平台、飞腾平台的Mini-ITX主板、Micro-ATX主板、ATX主板、嵌入式准系统/工业整机等计算机硬件。产品算力强大&#xff0c;支持高速存储&#xff0c;提供丰富串口、USB、LAN、PCIe扩展接口、显示接口等I/O接口&am…

【python】数据类型之列表类型(上)

本篇文章将讲解列表类型。 列表&#xff08;list&#xff09;&#xff0c;是一个有序且可变的容器&#xff0c;在里面可以存放多个不同类型的元素。 列表中的元素之间用逗号&#xff08;英文中的逗号&#xff09;相隔。 1、定义&#xff1a; 例如&#xff1a; user_list[]…

stl容器 vector的基本操作

目录 1.vector构造 1.1默认构造函数 1.2 fill 填充构造函数 ​编辑 1.3 范围构造函数&#xff08;Range Constructor&#xff09; 1.4拷贝构造函数 2.initializer_list初始化vector 3.迭代器 4.常用的几个成员 4.1 size()统计当前有效字符个数 4.2 capacity ve…

青甘环线游记|day(2)|西宁、青海湖

坐动车 早上7:30醒来&#xff0c;在8:00左右起床&#xff0c;下楼吃兰州拉面。面煮的很好吃&#xff0c;就是还是不是很适应。看到8元的牛肉面感觉很震惊&#xff0c;没想到是面8元&#xff0c;牛肉另加&#xff0c;10元。 坐上动车前往西宁&#xff0c;12点左右到了。虽然在…

PXE实现自动安装部署操作系统

PXE&#xff08;Preboot eXecution Environment&#xff09;是一种在计算机启动时使用网络接口从远程服务器获取操作系统安装和启动信息的技术。通过PXE&#xff0c;计算机可以从局域网中的PXE服务器上下载操作系统安装文件&#xff0c;并进行自动化的操作系统部署或故障排除。…

25考研数据结构复习·7.4B树和B+树7.5散列(Hash)表

目录 B树和B树 B树 m阶B树的核心特性 B树的插入 B树的删除 非终端结点关键字 终端结点关键字 低于下限 B树 散列&#xff08;Hash&#xff09;表 基本概念 散列函数的构造 &#x1f469;‍&#x1f4bb; 除留余数法 直接定址法 数字分析法 平方取中法 处理冲突…

动手学深度学习V2每日笔记(池化层)

本文主要参考沐神的视频教程 https://www.bilibili.com/video/BV1EV411j7nX/spm_id_from333.999.0.0&vd_sourcec7bfc6ce0ea0cbe43aa288ba2713e56d 文档教程 https://zh-v2.d2l.ai/ 本文的主要内容对沐神提供的代码中个人不太理解的内容进行笔记记录&#xff0c;内容不会特别…

Linux基础环境开发工具(二)

目录 一、前言二、make和makefile工具1.快速认识一下2.依赖关系和依赖方法3.执行原理 三、Git工具1.快速认识一下2.git的使用 四、gdb工具1.快速认识一下2、类比Windows使用 一、前言 在开发工具第一篇中我们介绍了yum&#xff0c;vim&#xff0c;gcc/g编译器这几种工具&#…

C++ 继承 派生类的拷贝构造

继承 派生类的拷贝构造构造顺序拷贝构造 引例1: 当子类,不自实现拷贝构造时,默认调用父类的拷贝构造引例2: 子类自实现拷贝构造,不做特殊处理时,只会调用父类的构造器.引例3: 显示的调用父类的拷贝构造器。案例: 内嵌函数的拷贝构造 引例1 :当内嵌子对象,子类不自实现拷贝构造时…

Netty二

Netty 问题分析 bootstrap serverBootstrap pipeline和channelPipeline EventLoopGroup和实现类NioEventLoopGroup

U2net论文复现-简单解读-以及奇奇怪怪的改进-测试roc以及pr

论文地址&#xff1a;U2net论文地址 显著性目标检测&#xff1a; Salient ObjectDetetion(SOD)显著性目标检测&#xff0c;就是要把图片中最显著的物体分割出来&#xff0c;所以是二分类任务&#xff0c;只需要背景和前景。 1、Introduce 1.1、目前存在的2个挑战&#xff1…

Day-11 员工管理案例 增删改查、配置文件

SpringBootWeb案例 前面我们已经实现了员工信息的条件分页查询以及删除操作。 关于员工管理的功能&#xff0c;还有两个需要实现&#xff1a; 新增员工修改员工 首先我们先完成"新增员工"的功能开发&#xff0c;再完成"修改员工"的功能开发。而在"新…

Midjourney、Sora和硅谷机密-《分析模式》漫谈15

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的Preface&#xff08;前言&#xff09;有这么一句&#xff1a; Kent Beck, Ward Cunningham, and Jim Coplein encouraged me to get involved with the commu…

《Advanced RAG》-02-揭开 PDF 解析的神秘面纱

摘要 PDF 文件是非结构化文档的代表&#xff0c;但从 PDF 文档中提取信息是一个具有挑战性的过程。 PDF 文件由一系列指令组成&#xff0c;这些指令指示 PDF 阅读器或打印机在屏幕或纸张上显示符号的位置和方式。与 HTML 和 docx 等文件格式不同&#xff0c;后者使用标记来组织…

8月2日,贪心-买卖股票的最佳时期

大家好呀&#xff0c;今天我们看两道用贪心算法解的两道题&#xff0c;150道经典面试题中的买卖股票的最佳时期1和2。 1.买卖股票的最佳时期1 . - 力扣&#xff08;LeetCode&#xff09; 思路 对于这题&#xff0c;我们其实很容易想出暴力解&#xff0c;那就是从后往前找值&…

【文件系统】抽象磁盘的存储结构 CHS寻址法 | sector数组 | LAB数组

目录 1.为什么要抽象 2.逻辑抽象_版本1 2.1sector数组 ​2.2index转化CHS 3.逻辑抽象_版本2 3.1LBA数组 3.2LAB下标转化sector下标 文件其实就是在磁盘中占有几个扇区的问题❗文件是很多个sector的数组下标❗文件是有很多块构成的❗❗文件由很多扇区构成------>文件…

C语言刷题小记3

题目1 序列中删除指定数字 分析&#xff1a;本题要求我们来删除一个序列中指定的数字&#xff0c;这里大家要注意我们要删除的数字可能不止出现一次&#xff0c;所以我们需要用两个变量来进行处理&#xff0c;一个变量来遍历数组&#xff0c;一个变量来存储数组的位置&#xff…