批量抓取某电影网站的下载链接

news2024/12/22 23:28:05

思路:

  1. 进入电影天堂首页,提取到主页面中的每一个电影的背后的那个urL地址
    a. 拿到“2024必看热片”那一块的HTML代码
    b. 从刚才拿到的HTML代码中提取到href的值
  2. 访问子页面,提取到电影的名称以及下载地址
    a. 拿到子页面的页面源代码
    b. 数据提取

代码实现:

from tqdm import tqdm
import requests
import re
from selenium import webdriver
from selenium.webdriver.edge.options import Options

class MovieScraper:
    """
    MovieScraper类用于从网站抓取电影信息。

    属性
    ----------
    edge_options : Options
        用于配置webdriver的selenium Options对象
    web_driver : webdriver
        用于与网站交互的selenium webdriver
    request_headers : dict
        包含请求头的字典

    方法
    -------
    get_response(url)
        向指定的URL发送GET请求并返回响应。
    get_movie_list_html(response)
        从响应中提取电影列表的HTML。
    get_sub_url_list(movie_list_html)
        从电影列表HTML中提取子URL。
    get_movie_info(child_response)
        从子URL的响应中提取电影信息。
    scrape(target_url)
        从指定的URL抓取电影信息并写入文件。
    """

    def __init__(self):
        """初始化MovieScraper,配置webdriver和请求头。"""
        self.edge_options = Options()
        self.edge_options.add_argument("headless")
        self.web_driver = webdriver.Edge(options=self.edge_options)
        self.request_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
        }

    def get_response(self, url):
        """
        向指定的URL发送GET请求并返回响应。

        参数
        ----------
        url : str
            要发送请求的URL。

        返回
        -------
        response : Response
            GET请求的响应。
        """
        response = requests.get(url, headers=self.request_headers)
        response.encoding = "gbk"
        return response

    def get_movie_list_html(self, response):
        """
        从响应中提取电影列表的HTML。

        参数
        ----------
        response : Response
            要提取HTML的响应。

        返回
        -------
        movie_list_html : str
            电影列表的HTML。
        """
        movie_list_pattern = re.compile(r'2024必看热片.*?<ul>(?P<html>.*?)</ul>', re.S)
        movie_list_result = movie_list_pattern.search(response.text)
        return movie_list_result.group("html")

    def get_sub_url_list(self, movie_list_html):
        """
        从电影列表HTML中提取子URL。

        参数
        ----------
        movie_list_html : str
            电影列表的HTML。

        返回
        -------
        sub_url_list : iterator
            子URL的迭代器。
        """
        sub_url_pattern = re.compile(r"<li><a href='(?P<sub_url>.*?)'", re.S)
        return sub_url_pattern.finditer(movie_list_html)

    def get_movie_info(self, child_response):
        """
        从子URL的响应中提取电影信息。

        参数
        ----------
        child_response : Response
            要提取电影信息的响应。

        返回
        -------
        movie_info_result : Match
            包含电影信息的匹配对象。
        """
        movie_info_pattern = re.compile(r'◎片  名 (?P<movie>.*?)<br.*?<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<download>.*?)"', re.S)
        return movie_info_pattern.search(child_response.text)

    def scrape(self, target_url):
        """
        从指定的URL抓取电影信息并写入文件。

        参数
        ----------
        target_url : str
            要抓取电影信息的URL。
        """
        self.web_driver.get(target_url)
        response = self.get_response(target_url)
        movie_list_html = self.get_movie_list_html(response)
        sub_url_list = self.get_sub_url_list(movie_list_html)

        with open("电影天堂.txt", "w", encoding="utf-8") as file:
            for sub_url in tqdm(sub_url_list, desc="处理URL中", unit="URL"):
                child_url = target_url + sub_url.group("sub_url")
                child_response = self.get_response(child_url)
                movie_info_result = self.get_movie_info(child_response)
                download_link = movie_info_result.group("download")
                file.write(download_link + "\n")

        self.web_driver.quit()
        print("爬取完毕")

if __name__ == "__main__":
    scraper = MovieScraper()
    scraper.scrape("https://www.dy2018.com/")

效果:

在这里插入图片描述

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

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

相关文章

Linux理解文件操作 文件描述符fd 理解重定向 dup2 缓冲区 C语言实现自己的shell

文章目录 前言一、文件相关概念与操作1.1 open()1.2 close()1.3 write()1.4 read()1.4 写入的时候先清空文件内容再写入1.5 追加&#xff08;a && a&#xff09; 二、文件描述符2.1 文件描述符 fd 0 1 2 的理解2.2 FILE结构体&#xff1a;的源代码 三、深入理解文件描述…

Vue 开发中的一些问题简单记录,Cannot find module ‘webpack/lib/RuleSet‘

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

【C语言】项目实践-贪吃蛇小游戏(Windows环境的控制台下)

一.游戏要实现基本的功能&#xff1a; • 贪吃蛇地图绘制 • 蛇吃食物的功能 &#xff08;上、下、左、右方向键控制蛇的动作&#xff09; • 蛇撞墙死亡 • 蛇撞自身死亡 • 计算得分 • 蛇身加速、减速 • 暂停游戏 二.技术要点 C语言函数、枚举、结构体、动态内存管…

【Java探索之旅】内部类 静态、实例、局部、匿名内部类全面解析

文章目录 &#x1f4d1;前言一、内部类1.1 概念1.2 静态内部类1.3 实例内部类1.4 局部内部类1.5 匿名内部类 &#x1f324;️全篇总结 &#x1f4d1;前言 在Java编程中&#xff0c;内部类是一种强大的特性&#xff0c;允许在一个类的内部定义另一个类&#xff0c;从而实现更好的…

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

网络攻击(Cyber Attacks)

目录 1.概念 2.分类 3.总结 1.概念 网络攻击&#xff08;Cyber Attacks&#xff0c;也称赛博攻击&#xff09;是指针对计算机信息系统、基础设施、计算机网络或个人计算机设备的&#xff0c;任何类型的进攻动作。对于计算机和计算机网络来说&#xff0c;破坏、揭露、修改、使…

【C++】STL — List的接口讲解 +详细模拟实现

前言&#xff1a; 本章我们将学习STL中另一个重要的类模板list… list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是带头双向循环链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xf…

从零到屎山系列-游戏开发(Day2)

简介 这次就来一个比较简单的小游戏贪吃蛇 贪吃蛇 游戏规则就是一串珠子不断的移动&#xff0c;碰到场景里面的食物变长一点&#xff0c;碰到墙壁游戏结束。 开始动手 设计绘制设备 首先我计划从一个控制台游戏开始&#xff0c;需要一个控制台下的绘图机制&#xff0c;希…

基于Sen+MK的多站点不同季节和年尺度的SPEI趋势分析.md

再大的风浪&#xff0c;不过只短暂喧哗。 文章目录 前言1. 概述2.1 问题情景2.2 说明 2. 版本2.1 天津&#xff0c;2024年5月4日&#xff0c;Version1 3. 微信公众号GISRSGeography 一、数据1. 输入数据2. 输出数据 二、程序代码三、参考资料 前言 1. 概述 2.1 问题情景 假…

java-Spring-mvc-(请求和响应)

目录 &#x1f4cc;HTTP协议 超文本传输协议 请求 Request 响应 Response &#x1f3a8;请求方法 GET请求 POST请求 &#x1f4cc;HTTP协议 超文本传输协议 HTTP协议是浏览器与服务器通讯的应用层协议&#xff0c;规定了浏览器与服务器之间的交互规则以及交互数据的格式…

thinkphp6 workerman无法使用框架Db/model等类库方法解决方案

thinkphp6 workerman无法使用框架Db/model相关操作解决 执行安装相关扩展 composer require webman/gateway-worker引入成功后编辑服务类文件,直接展示代码 <?phpnamespace app\server\controller;use GatewayWorker\BusinessWorker; use GatewayWorker\Gateway; use Gate…

java异常.day30(Error,Exception)

Error和Exception说明 Error Error类及其子类表示的是Java虚拟机&#xff08;JVM&#xff09;无法或不应该尝试恢复的严重问题。这些问题通常是由JVM本身的问题、系统资源耗尽、或其他不可控的环境因素引起的。由于Error是不可恢复的&#xff0c;因此应用程序不应该尝试捕获和…

Cisco WLC 2504控制器重启后所有AP掉线故障-系统日期时间

1 故障描述 现场1台WLC 2504控制器掉电重启后&#xff0c;所有AP均无线上线&#xff0c; 正常时共有18个AP在线&#xff0c;而当前为0 AP在线数量为0 (Cisco Controller) >show ap sumNumber of APs.................................... 0Global AP User Name..........…

细胞自动机与森林火灾与燃烧模拟

基于 元胞自动机-森林火灾模拟_vonneumann邻域-CSDN博客 进行略微修改&#xff0c;解决固定方向着火问题&#xff0c;用了一个meshv2数组记录下一状态&#xff0c;避免旧状态重叠数据失效。 参数调整 澳洲森林火灾蔓延数学建模&#xff0c;基于元胞自动机模拟多模式下火灾蔓延…

大语言模型从Scaling Laws到MoE

1、摩尔定律和伸缩法则 摩尔定律&#xff08;Moores law&#xff09;是由英特尔&#xff08;Intel&#xff09;创始人之一戈登摩尔提出的。其内容为&#xff1a;集成电路上可容纳的晶体管数目&#xff0c;约每隔两年便会增加一倍&#xff1b;而经常被引用的“18个月”&#xf…

【C++题解】1659. 是否含有数字5

问题&#xff1a;1659. 是否含有数字5 类型&#xff1a;分支结构 题目描述&#xff1a; 请从键盘读入一个五位整数 n&#xff0c;判断其是否含有数字 5&#xff0c;如果含有数字 5 &#xff0c;请输出这个 5 位数各个位的和&#xff1b;如果不含数字 5 &#xff0c;请直接输出…

IoTDB 入门教程 基础篇⑧——数据库管理工具 | IDEA 连接 IoTDB

文章目录 一、前文二、下载iotdb-jdbc三、IDEA驱动四、IDEA连接数据库五、数据库应用六、其他 一、前文 IoTDB入门教程——导读 二、下载iotdb-jdbc 下载地址org/apache/iotdb/iotdb-jdbc&#xff1a;https://maven.proxy.ustclug.org/maven2/org/apache/iotdb/iotdb-jdbc/ 本…

记录vue报错问题 in ./node_modules/axios/lib/platform/index.js

今天这个问题困扰了我许久 报错内容如下&#xff1a; 最初一直以为是我没装axios&#xff0c;又重新装了一次&#xff0c;后面才发现是axios版本原因&#xff0c;真的总是被版本的原因困住真的很烦 解决方法如下&#xff1a; 将axios的版本改为1.5.0 1、打开项目的文件夹“…

探索LLM在广告领域的应用——大语言模型的新商业模式和新个性化广告的潜力

概述 在网络搜索引擎的领域中&#xff0c;广告不仅仅是一个补充元素&#xff0c;而是构成了数字体验的核心部分。随着互联网经济的蓬勃发展&#xff0c;广告市场的规模已经达到了数万亿美元&#xff0c;并且还在持续扩张。广告的经济价值不断上升&#xff0c;它已经成为支撑大…

C++奇迹之旅:STL初步学习

文章目录 &#x1f4dd;什么是STL&#x1f320; STL的版本&#x1f309;STL的六大组件 &#x1f320;STL的重要性&#x1f309;如何学习STL&#x1f320;STL的缺陷&#x1f6a9;总结 &#x1f4dd;什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的…