Python爬虫实战—探索某网站电影排名

文章目录

  • Python爬虫实战—探索某网站电影排名
    • 准备工作
    • 编写爬虫代码
    • 代码解析
    • 运行情况截图
    • 进一步优化和说明
    • 完整代码
    • 总结

说明:本案例以XXX网站为例,已隐去具体网站名称与地址。

Python爬虫实战—探索某网站电影排名

网络爬虫是一种自动化程序,用于获取互联网上的信息。它们被广泛用于数据收集、搜索引擎和各种其他应用中。Python语言具有强大的网络爬虫库和工具,使得编写爬虫变得相对简单。在本文中,我们将介绍如何使用Python编写一个简单的网络爬虫,并以某网电影网站为例进行说明。

准备工作

首先,我们需要安装Python以及以下几个库:

  • requests:用于发送HTTP请求和获取响应。
  • lxml:用于解析HTML文档。
  • csv:用于将数据保存到CSV文件中。

你可以使用pip命令来安装这些库:

pip install requests lxml

编写爬虫代码

以下是一个简单的某网电影网站爬虫示例代码:

import requests
from lxml import etree
import csv
import time


class DoubanSpider(object):
    def __init__(self):
        self.header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36'
        }

    # 发请求 获响应
    def get_source(self, com_url):
        res = requests.get(com_url, headers=self.header)
        html = res.content.decode('utf-8')
        return html

    # 解析数据
    def parsed_source(self, html):
        tree = etree.HTML(html)
        divs = tree.xpath('//div[@class="info"]')
        lis_data = []
        for div in divs:
            d = {}
            title = div.xpath('./div[@class="hd"]/a/span/text()')[0].strip()
            score = div.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0].strip()
            evaluate = div.xpath('./div[@class="bd"]/div[@class="star"]/span[last()]/text()')[0].strip()
            quote = div.xpath('./div[@class="bd"]/p[@class="quote"]/span/text()')
            quote = quote[0] if quote else ''
            link_url = div.xpath('./div[@class="hd"]/a/@href')[0].strip()
            d['title'] = title
            d['score'] = score
            d['evaluate'] = evaluate
            d['quote'] = quote
            d['link_url'] = link_url
            lis_data.append(d)
        return lis_data

    # 保存数据
    def save_source(self, move_data, header):
        with open('movie_data.csv', 'a', encoding='utf-8-sig', newline='') as f:
            w = csv.DictWriter(f, header)
            w.writerows(move_data)

    # 主函数
    def main(self):
        start = int(input('输入要爬取的起始页:'))
        end = int(input('输入要爬取的末尾页:'))
        for i in range(start, end+1):
            time.sleep(2)
            page = (i-1) * 25
            com_url = 'https://xxx/top250?start=' + str(page)
            h = self.get_source(com_url)
            print('爬虫机器人正在爬取第%d页' % i)
            move_data = self.parsed_source(h)
            header = ['title', 'score', 'evaluate', 'quote', 'link_url']
            self.save_source(move_data, header)


if __name__ == '__main__':
    Spider = DoubanSpider()
    Spider.main()

代码解析

  1. DoubanSpider

这是一个名为 DoubanSpider 的类,用于执行某网电影网站的爬取任务。

  1. 初始化方法 __init__()

在初始化方法中,我们设置了请求头,模拟了浏览器发送请求的行为。

  1. get_source() 方法

这个方法发送HTTP请求并获取响应内容。

  1. parsed_source() 方法

这个方法用于解析HTML内容,提取电影的相关信息,如标题、评分、评价人数、引用和链接URL。

  1. save_source() 方法

该方法用于将解析后的数据保存到CSV文件中。

  1. main() 方法

这是爬虫的主要逻辑。它接受用户输入的起始页和结束页,然后遍历每一页,调用其他方法执行爬取和保存数据的操作。

运行情况截图

image-20240320132159688

image-20240320132330959

进一步优化和说明

虽然以上代码可以完成基本的爬取任务,但还有一些优化和说明可以帮助提高代码的质量和可读性。

  1. 异常处理

在网络请求中,经常会出现各种异常情况,比如连接超时、请求失败等。为了增加代码的健壮性,可以添加异常处理机制。

try:
    res = requests.get(com_url, headers=self.header)
    res.raise_for_status()  # 检查请求是否成功
except requests.RequestException as e:
    print("请求异常:", e)
    return None
  1. 数据去重

在爬取数据时,可能会出现重复的电影信息。为了避免重复,可以在保存数据之前进行去重操作。

def save_source(self, move_data, header):
    # 去重
    move_data = self.remove_duplicates(move_data)
    with open('movie_data.csv', 'a', encoding='utf-8-sig', newline='') as f:
        w = csv.DictWriter(f, header)
        w.writerows(move_data)

def remove_duplicates(self, move_data):
    unique_data = []
    titles = set()
    for item in move_data:
        if item['title'] not in titles:
            unique_data.append(item)
            titles.add(item['title'])
    return unique_data
  1. 使用生成器优化内存占用

在爬取大量数据时,可能会占用大量内存。可以使用生成器来优化内存占用。

def parsed_source(self, html):
    tree = etree.HTML(html)
    divs = tree.xpath('//div[@class="info"]')
    for div in divs:
        d = {}
        title = div.xpath('./div[@class="hd"]/a/span/text()')[0].strip()
        score = div.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0].strip()
        evaluate = div.xpath('./div[@class="bd"]/div[@class="star"]/span[last()]/text()')[0].strip()
        quote = div.xpath('./div[@class="bd"]/p[@class="quote"]/span/text()')
        quote = quote[0] if quote else ''
        link_url = div.xpath('./div[@class="hd"]/a/@href')[0].strip()
        d['title'] = title
        d['score'] = score
        d['evaluate'] = evaluate
        d['quote'] = quote
        d['link_url'] = link_url
        yield d
  1. 添加用户代理池

为了避免被网站识别为爬虫程序而被封禁IP,可以使用代理池来切换IP地址。

  1. 日志记录

添加日志记录功能可以方便调试和追踪爬取过程中的问题。

  1. 数据存储方式

除了CSV文件,还可以考虑使用数据库(如SQLite、MySQL等)来存储爬取的数据,以支持更复杂的数据操作和查询。

  1. 用户交互改进

在用户与爬虫交互方面,可以考虑添加输入参数的方式来控制爬虫的行为,而不是每次都手动输入起始页和结束页。

import argparse

def parse_arguments():
    parser = argparse.ArgumentParser(description="某网电影Top250爬虫")
    parser.add_argument("--start", type=int, default=1, help="起始页码")
    parser.add_argument("--end", type=int, default=10, help="结束页码")
    return parser.parse_args()

def main(self):
    args = parse_arguments()
    start = args.start
    end = args.end
    for i in range(start, end+1):
        # 爬取逻辑不变

通过这种方式,用户可以在命令行中指定起始页和结束页,而不需要手动输入。

  1. 添加定时任务

如果需要定时执行爬虫任务,可以使用Python中的定时任务库(如APScheduler)来实现。

from apscheduler.schedulers.blocking import BlockingScheduler

def scheduled_task():
    Spider = DoubanSpider()
    Spider.main()

if __name__ == "__main__":
    scheduler = BlockingScheduler()
    scheduler.add_job(scheduled_task, "interval", minutes=60)  # 每隔60分钟执行一次
    scheduler.start()
  1. 添加单元测试

为了保证爬虫代码的稳定性和正确性,可以添加单元测试,验证爬虫函数的各个部分是否按照预期工作。

import unittest

class TestDoubanSpider(unittest.TestCase):
    def test_get_source(self):
        # 编写测试用例
    def test_parsed_source(self):
        # 编写测试用例
    def test_save_source(self):
        # 编写测试用例

if __name__ == '__main__':
    unittest.main()

完整代码

import requests  # 导入requests库,用于发送HTTP请求
from lxml import etree  # 导入etree模块,用于解析HTML文档
import csv  # 导入csv模块,用于读写CSV文件
import time  # 导入time模块,用于添加延时


class DoubanSpider(object):
    def __init__(self):
        # 初始化函数,设置请求头,模拟浏览器发送请求
        self.header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36'
        }

    # 发请求 获响应
    def get_source(self, com_url):
        # 发送HTTP请求并获取响应内容
        res = requests.get(com_url, headers=self.header)
        html = res.content.decode('utf-8')
        return html

    # 解析数据
    def parsed_source(self, html):
        # 解析HTML内容,提取电影相关信息
        tree = etree.HTML(html)
        divs = tree.xpath('//div[@class="info"]')
        lis_data = []
        for div in divs:
            d = {}
            # 提取标题
            title = div.xpath('./div[@class="hd"]/a/span/text()')[0].strip()
            # 提取评分
            score = div.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0].strip()
            # 提取评价人数
            evaluate = div.xpath('./div[@class="bd"]/div[@class="star"]/span[last()]/text()')[0].strip()
            # 提取引用
            quote = div.xpath('./div[@class="bd"]/p[@class="quote"]/span/text()')
            quote = quote[0] if quote else ''
            # 提取电影链接url
            link_url = div.xpath('./div[@class="hd"]/a/@href')[0].strip()
            # 根据key值提取数据
            d['title'] = title
            d['score'] = score
            d['evaluate'] = evaluate
            d['quote'] = quote
            d['link_url'] = link_url
            lis_data.append(d)
        return lis_data

    # 保存数据
    def save_source(self, move_data, header):
        # 保存解析后的数据到CSV文件中
        with open('movie_data.csv', 'a', encoding='utf-8-sig', newline='') as f:
            w = csv.DictWriter(f, header)
            # 写入表头
            w.writeheader()
            # 一次性写入多行数据
            w.writerows(move_data)

    # 主函数
    def main(self):
        start = int(input('输入要爬取的起始页:'))  # 输入起始页码
        end = int(input('输入要爬取的末尾页:'))  # 输入结束页码
        for i in range(start, end+1):
            time.sleep(2)  # 延时2秒,避免对目标服务器造成过大压力
            page = (i-1) * 25
            com_url = 'https://xxx/top250?start=' + str(page)
            h = self.get_source(com_url)
            print('爬虫机器人正在爬取第%d页' % i)  # 打印爬取页面信息
            move_data = self.parsed_source(h)
            # 设置表头
            header = ['title', 'score', 'evaluate', 'quote', 'link_url']
            self.save_source(move_data, header)  # 保存数据到CSV文件


if __name__ == '__main__':
    # 实例化对象
    Spider = DoubanSpider()
    # 调用主函数
    Spider.main()

总结

在本文中,我们介绍了如何使用Python编写一个简单的网络爬虫,并以某网电影网站为例进行了详细说明。通过对某网电影Top250页面的爬取,我们学习了发送HTTP请求、解析HTML文档、提取所需信息以及保存数据到CSV文件的基本操作。我们还对代码进行了进一步的优化,包括异常处理、数据去重、使用生成器优化内存占用、添加用户代理池等,以提高爬虫的稳定性、效率和可维护性。

除此之外,我们还讨论了一些提高爬虫功能和可用性的方法,如改进用户交互、添加定时任务、编写单元测试等。这些方法可以使得爬虫更加灵活和智能,满足不同场景下的需求,并提供了更多的扩展可能性。

在实际应用中,网络爬虫是一种强大的工具,可用于数据收集、信息监控、搜索引擎优化等各种领域。但是在使用爬虫时,我们必须遵守网站的使用条款和法律法规,尊重网站的隐私权和数据安全,避免对网站造成不必要的干扰和损害。

综上所述,本文介绍了从网络爬虫的基础知识到实际应用的全过程,希望能够帮助读者更好地理解和应用网络爬虫技术。在未来的工作中,我们可以进一步探索和应用更多的爬虫技巧,以满足不断变化的需求,并为数据获取和应用提供更多可能性。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQLiteC/C++接口详细介绍sqlite3_stmt类(十三)

返回:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍sqlite3_stmt类(十二) 下一篇: 待续 51、sqlite3_stmt_scanstatus_reset sqlite3_stmt_scanstatus_reset 函数用于重置指定语句对象最近一次执行的 WHER…

Vue3 Vite3 状态管理 pinia 基本使用、持久化、在路由守卫中的使用

参考https://juejin.cn/post/7152774411571953677,自己简洁化了一部分 1.安装pinia依赖 yarn add pinia 创建pini实例 根目录创建store文件夹,然后创建index.js import { createPinia } from piniaconst pinia createPinia()export default pinia …

2024年全国职业院校技能大赛中职组大数据应用与服务赛项题库参考答案陆续更新中,敬请期待…

2024年全国职业院校技能大赛中职组大数据应用与服务赛项题库参考答案陆续更新中,敬请期待… 武汉唯众智创科技有限公司 2024 年 3 月 联系人:辜渝傧13037102709 题号:试题04 ZZ052-大数据应用与服务赛选赛题04 模块一:平台搭建…

一文带你看懂 前后端之间图片的上传与回显

一文带你看懂 前后端之间图片的上传与回显 前言 看了很多类似的文章,发现很多文章,要不就是不对,要不就是代码写的不通俗易懂,所以有了这篇文章,我将会从原理到实战,带你了解 实战包含前端 原生 vue3 rea…

阿里云OCR文字识别-Python3接口

1.注册/登录阿里云账号 官网链接注册登录 2.选择阿里云OCR产品 选择产品 3.开通阿里云OCR产品 开通服务(每个月赠送200次,不用超就不额外收费) 4.进入调试页面,下载SDK示例 下载SDK模板 5.创建 AccessKey密钥 RAM传送门 创建…

外腔激光器(ECL)市场发展空间大 外腔半导体激光器(ECDL)是主要产品类型

外腔激光器(ECL)市场发展空间大 外腔半导体激光器(ECDL)是主要产品类型 外腔激光器(ECL),是一种利用外腔进行光反馈的激光器。根据新思界产业研究中心发布的《》2024-2029年中国外腔激光器&…

立体式学习灯最推荐哪款?书客、孩视宝、雷士等热销大路灯强势PK!

立体式学习灯是一款能够帮助长时间伏案工作以及学习人群的照明家电,正因为其优越的表现也受到了不少消费者的喜爱。作为一名电器博主,我也购入过不少立体式学习灯但时有买到一些光线不足、品质差的大路灯,呈现出来的光线不能提升照明条件,反而还会引起越…

LeetCode每日一题【19. 删除链表的倒数第 N 个结点】

思路:快慢指针 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x)…

瑞_Redis_商户查询缓存_什么是缓存

文章目录 项目介绍1 短信登录2 商户查询缓存2.1 什么是缓存2.1.1 缓存的应用场景2.1.2 为什么要使用缓存2.1.3 Web应用中缓存的作用2.1.4 Web应用中缓存的成本 附:缓存封装工具类 🙊 前言:本文章为瑞_系列专栏之《Redis》的实战篇的商户查询缓…

【数据库系统】数据库完整性和安全性

第六章 数据库完整性和安全性 基本内容 安全性;完整性;数据库恢复技术;SQL Server的数据恢复机制; 完整性 实体完整性、参照完整性、用户自定义完整性 安全性 身份验证权限控制事务日志,审计数据加密 数据库恢复 冗余…

Vue3 v-for绑定的dom获取ref为undefined

这是代码结构 <div class"playerInfo" v-for"(item, index) in data.playersInfo" :key"index" :ref"el > {if(el)playersRef[index] el}":style"left:${item.position[0]};top:${item.position[1]}"click"pla…

【ZooKeeper】2、安装

本文基于 Apache ZooKeeper Release 3.7.0 版本书写 作于 2022年3月6日 14:22:11 转载请声明 下载zookeeper安装包 wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz解压 tar -zxvf apache-zookeeper-3.7.0-b…

Transformer的前世今生 day06(Self-Attention和RNN、LSTM的区别

Self-Attention和RNN、LSTM的区别 RNN的缺点&#xff1a;无法做长序列&#xff0c;当输入很长时&#xff0c;最后面的输出很难参考前面的输入&#xff0c;即长序列会缺失上文信息&#xff0c;如下&#xff1a; 可能一段话超过50个字&#xff0c;输出效果就会很差了 LSTM通过忘…

什么是行业垂直类媒体?有哪些?怎么邀约

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体胡老师。 行业垂直类媒体是聚焦于特定行业或领域的媒体平台。 行业垂直类媒体不同于主流媒体&#xff0c;它们专注于提供与某个特定领域相关的深入内容和服务&#xff0c;例如商业新闻、旅游、数字…

什么快递可以寄摩托车?看你要啥样的了

一辆49cc的二冲程摩托车仅需561元。 购买125的组装车不会超过1元&#xff0c;购买250品牌发动机的组装车不会超过4000元。 购买一辆名牌摩托车大约需要4000到10000元。 花一万到两百万多就能买到一辆像样、动力强劲、能玩的炫酷摩托车。 哈哈&#xff0c;就看你想要什么了&…

力扣---随机链表的复制

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

关于5.x版本的Neo4j与py2neo的访问技巧

先说结果。 Neo4j是可以使用py2neo来操作的。而且网上搜到的教程和方法里&#xff0c;首推的http连接方法可能并不是最好的&#xff0c;应该用 bolt 方法可能更好。 对于大多数使用 py2neo 与 Neo4j 数据库进行交互的应用程序来说&#xff0c;建议使用 Bolt 协议&#xff08;即…

操作系统实践之路——五、初始化(2.Linux初始化)

文章目录 一、全局流程二、从BIOS到GRUB三、GRUB是如何启动的四、详解vmlinuz文件结构五、流程梳理-1六、内核初始化从_start开始七、流程梳理-2参考资料 前言 ​ 本章节将讨论一下Linux如何去做初始化。 一、全局流程 ​ 在机器加电后&#xff0c;BIOS 会进行自检&#xff…

Wi-Fi 7:下一代无线网络的革命性技术与特点解析

更多精彩内容在 随着无线通信的不断发展&#xff0c;Wi-Fi技术作为无线网络连接的重要组成部分&#xff0c;也在不断演进。Wi-Fi 7作为下一代无线网络标准&#xff0c;被认为将带来革命性的变化&#xff0c;提供更快速、更可靠的网络连接。本文将深入解析Wi-Fi 7的技术和特点&a…

广交会参展,一起来看看展会二维如何制作吧

展会&#xff0c;一直都是企业开发客户、寻找合作伙伴、拓展渠道、展示产品和技术、提升品牌知名度、行业交流的重要宣传活动。 据相关资料显示&#xff0c;2024年新能源行业和电子电力行业依旧是展会青睐的重点行业&#xff0c;分别占到统计数据的35%和38%。从举办展会的国家…