休闲时光:最近上映的电影与爬虫世界,带您彻底放松!

news2024/9/20 18:32:26

ed754de4e63dbfc5d6692962d017b8c9.jpeg

大家好,我是安果!

周末是与亲朋好友相聚的好时机,可以选择一部大家都喜欢的电影,彻底放松,共同度过一个愉快而难忘的周末

本篇文章将介绍如何使用 Scrapy 爬取最新上映的电影

目标对象:

aHR0cHM6Ly93d3cubWFveWFuLmNvbS8=

1、创建爬虫项目

# 创建一个爬虫项目
scrapy startproject film

cd film

# 创建一个爬虫
scrapy genspider maoyan_film https://www.*.com/

2、创建数据表及定义 Item

在数据库中创建一张表用于保存爬取下来的数据

以 Mysql 为例

create table xag.film
(
    id          int auto_increment
        primary key,
    film_name   varchar(100) null,
    show_time   varchar(100) null,
    file_type   varchar(100) null,
    actors      varchar(100) null,
    url         varchar(100) null,
    insert_time date         null
);

然后,定义 Item 存储数据对象

# items.py

import scrapy

class FilmItem(scrapy.Item):
    film_name = scrapy.Field()  # 电影名称
    show_time = scrapy.Field()  # 上映时间
    file_type = scrapy.Field()  # 电影类型
    actors = scrapy.Field()  # 电影演员
    url = scrapy.Field()  # 电影URL
    insert_time = scrapy.Field()  # 插入时间(年、月、日)

3、编写爬虫解析主页面

这里以 Selenium 为例,首先创建一个浏览器对象

PS:为了在服务器上运行,这里对 CentOS 做了兼容处理

import scrapy
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
import platform

...
 def parse(self, response):
        chrome_options = Options()

        if platform.system().lower() == 'windows':
            # win
            s = Service(r"C:\work\chromedriver.exe")
            self.browser = webdriver.Chrome(service=s, options=chrome_options)
        else:
            # Centos
            DRIVER_PATH = '/home/drivers/chromedriver'
            s = Service(DRIVER_PATH)
            chrome_options.add_argument('--no-sandbox')
            chrome_options.add_argument('--headless')  # 无头参数
            chrome_options.add_argument('--disable-gpu')
            self.browser = webdriver.Chrome(service=s, options=chrome_options)

        self.browser.implicitly_wait(5)
...

然后,分析网页结构,使用 Xpath 解析最近上映的电影数据

886b8fc4c422e0aec54ccaca2198c2ca.jpeg

这里提取出电影的名称及上映时间(包含电影详情页面 URL)

...
        url = response.url
        # selenium打开网页
        self.browser.get(url)
        self.browser.maximize_window()

        WebDriverWait(self.browser, 20).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="movie-grid"]/div[2]//dl'))
        )

        time.sleep(10)

        video_elements = self.browser.find_elements(By.XPATH, '//div[@class="movie-grid"]/div[2]//dl/dd')

        for video_element in video_elements:
            # 电影名称
            film_name = video_element.find_element(By.XPATH, './/div[contains(@class,"movie-title")]').text

            # 上映时间
            show_time = video_element.find_element(By.XPATH, './/div[contains(@class,"movie-rt")]').text.replace(
                "上映",
                "")

            # 详情页面URL
            file_detail_a_element = video_element.find_element(By.XPATH, './/div[@class="movie-item"]/a')
            file_detail_url = file_detail_a_element.get_attribute("href")

            print('film_name:', film_name, ',show_time:', show_time, ",url:", file_detail_url)

            yield Request(file_detail_url, callback=self.parse_detail, headers=self.headers,
                          meta={"film_name": film_name, "show_time": show_time}, dont_filter=True)
...

4、电影详情页面解析

通过上面的步骤,我们可以拿到某一部电影的详情页面 URL

0299d750e121fc0b044a7aba3396fcac.jpeg

需要注意的是,如果使用 Selenium 直接打开该页面会触发反爬,这里我们需要修改浏览器特征值

...
 def parse_detail(self, response):
        """
        解析子页面
        :param response:
        :return:
        """
        # 应对反爬
        self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
            "source": """
                            Object.defineProperty(navigator, 'webdriver', {
                              get: () => undefined
                            })
                            """
        })
...

接着,打开目标页面,爬取电影的类型及演员列表

最后,将数据将存储到 Item 中

...
 self.browser.get(response.url)
        self.browser.maximize_window()

        # 等待加载完成
        WebDriverWait(self.browser, 20).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="movie-brief-container"]//a[@class="text-link"]'))
        )

        # 获取电影类型
        film_type_elements = self.browser.find_elements(By.XPATH,
                                                        '//div[@class="movie-brief-container"]//a[@class="text-link"]')
        file_type = ''
        for index, film_type_element in enumerate(film_type_elements):
            if len(film_type_elements) >= 2:
                if index != len(film_type_elements) - 1:
                    file_type += film_type_element.text + "|"
                else:
                    file_type += film_type_element.text
            else:
                file_type += film_type_element.text

        # 演员
        celebritys = self.browser.find_elements(By.XPATH,
                                                '//div[@class="celebrity-group"][2]//div[@class="info"]//a[@class="name"]')[
                     :3]
        actors = ''
        for index, celebrity in enumerate(celebritys):
            if len(celebritys) >= 2:
                if index != len(celebritys) - 1:
                    actors += celebrity.text + "|"
                else:
                    actors += celebrity.text
            else:
                actors += celebrity.text

        item = FilmItem()

        item['film_name'] = response.meta.get("film_name", "")
        item['show_time'] = response.meta.get("show_time", "")
        item["file_type"] = file_type
        item["actors"] = actors
        item['url'] = response.url
        item['insert_time'] = date.today().strftime("%Y-%m-%d")

        yield item
...

5、编写数据库管道,将上面的数据存储到数据库表中

from scrapy.exporters import CsvItemExporter
from film.items import FilmItem
import MySQLdb

class MysqlPipeline(object):
    def __init__(self):
        # 链接mysql数据库
        self.conn = MySQLdb.connect("host", "root", "pwd", "xag", charset="utf8", use_unicode=True)
        self.cursor = self.conn.cursor()

    # 数据同步插入到mysql数据库
    def process_item(self, item, spider):
        table_name = ''
        if isinstance(item, FilmItem):
            table_name = 'film'

        # sql语句
        insert_sql = """
            insert into  {}(film_name,show_time,file_type,actors,url,insert_time) values(%s,%s,%s,%s,%s,%s)  
        """.format(table_name)
        params = list()
        params.append(item.get("film_name", ""))
        params.append(item.get("show_time", ""))
        params.append(item.get("file_type", ""))
        params.append(item.get("actors", ""))
        params.append(item.get("url", ""))
        params.append(item.get("insert_time", ""))

        # 执行插入数据到数据库操作
        self.cursor.execute(insert_sql, tuple(params))

        # 提交,保存到数据库
        self.conn.commit()

        return item

    def close_spider(self, spider):
        """释放数据库资源"""
        self.cursor.close()
        self.conn.close()

6、配置爬虫项目 settings.py

在 settings.py 文件中,对下载延迟、默认请求头、下载管道 Pipline等进行配置

# settings.py

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

DOWNLOAD_DELAY = 3

DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Accept-Language': 'en',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
    'Host':'www.host.com'
}

ITEM_PIPELINES = {
   'film.pipelines.MysqlPipeline': 300,
}

7、运行入口

在项目根目录下创建一个文件,用于定义爬虫的运行入口

from scrapy.cmdline import execute
import sys, os

def start_scrapy():
    sys.path.append(os.path.dirname(__file__))
    # 运行单个爬虫
    execute(["scrapy", "crawl", "maoyan_film"])

if __name__ == '__main__':
    start_scrapy()

最后,我们将爬虫部署到服务器,设置定时任务及消息通知

这样我们可以及时获取最近上映的电影,通过电影类型及演员阵容,挑选自己喜欢的电影

d269828e95074b44c3ab76914fdc84de.jpeg

文中所有的源码我已经上传到公众号后台,回复关键字 230708 获取完整源码

如果大家有任何疑惑,欢迎在评论区留言!

推荐阅读

如何利用 Selenium 对已打开的浏览器进行爬虫!

如何利用 Playwright 对已打开的浏览器进行爬虫!

最全总结 | 聊聊 Selenium 隐藏浏览器指纹特征的几种方式!

END

好文和朋友一起看~

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

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

相关文章

深入浅出讲解Python中的可变类型与不可变类型,以及赋值,浅拷贝与深拷贝的区别

文章目录 1、不可变数据类型2、可变数据类型3、赋值,浅拷贝与深拷贝3.1 赋值操作符 3.2 浅拷贝copy()3.3 深拷贝copy() 小结 在Python中,数据类型主要分为可变数据类型和不可变数据类型。主要的区别在于可变数据类型的值可以改变,而不可变数据…

【网络系统集成】路由器实验

1.实验名称:路由器RIP协议配置 2.实验目的 在PacketTracer中进行模拟实验,配置RIP协议,验证RIP协议更新时间及路由状态变化,加深对路由器RIP协议相关知识的理解与掌握。 3.实验内容 (1)拓扑结构图 (2)ip地址分配与端口分配

Mybatis基础总结1

Mybatis快速入门 一.Mybatis快速入门1.1 框架介绍1.2 ORM介绍1.3 原始jdbc操作(查询数据)1.4原始jdbc操作(插入数据)1.5 原始jdbc操作的分析1.6 什么是Mybatis1.7 Mybatis的快速入门1.7.1 环境搭建1.7.2编写测试代码 1.8 知识小结…

Linux进程调度

转自:深入理解Linux进程调度(0.4)_进程调度 城_城中之城的博客-CSDN博客 一、进程调度概览 进程调度是操作系统最重要的内容之一,也是学习操作系统的重点和难点。关于进程本身的实现和管理请参看《深入理解Linux进程管理》。关于进程调度,我…

阿里云ECS服务器架构X86计算_ARM_GPU/FPGA_裸金属_超级计算集群

阿里云服务器架构有什么区别?X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、超级计算集群有什么区别?阿里云服务器网分享云服务器ECS架构详细说明: 目录 阿里云服务器ECS架构说明 X86计算 ARM计算 GPU/FPGA/ASIC 弹性裸金属服务…

mysql单表查询,排序,分组查询,运算符,select,order by,group by

CREATE TABLE emp (empno int(4) NOT NULL, --员工编号ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工名字job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工工作mgr int(4) NULL DEFAULT NU…

json 解析chrome浏览器插件json-handle

插件地址 非常好用,平常工作中需要经常查看对象属性,展开的时候往往都是很长的数据,有了这个大大提升效率了

云计算值得学习吗

云计算值得学习吗 云计算作为一项重要的技术和商业模式,未来的发展前景非常广阔。随着企业和个人对云计算需求的增长,以及新兴技术的不断突破和创新,云计算将继续引领科技进步和社会发展,并为用户带来更多的便利和创新&#xff0…

项目配置日志的打印目录,输出日志

最近的项目需要在服务器上跑&#xff0c;配个日志方便查看。简单记录一下&#xff0c; resources下新增日志配置的xml文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10 seco…

从零开始 Spring Boot 67:JPA 中的惰性元素

从零开始 Spring Boot 67&#xff1a;JPA 中的惰性元素 图源&#xff1a;简书 (jianshu.com) 惰性加载带来的问题 在实体类之间建立关系时&#xff0c;可以选择“惰性加载”&#xff0c;比如&#xff1a; Entity public class Student {// ...OneToMany(mappedBy "stu…

基于springboot,vue网上订餐系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术 &#xff1a;VueElementUI 服务端技术&#xff1a;springbootmybatisredis 本系统分用户前台和管理后台两部分&#xff0c;项…

【Kafka】Kafka的Broker概述

【Kafka】Kafka的Broker概述 文章目录 【Kafka】Kafka的Broker概述1. Broker的工作流程1.1 Zookeeper存储的Kafka信息1.2 Broker 总体工作流程1.3 Broker重要参数 2. 节点服役和退役2.1 服役新节点2.2 退役旧节点 3. Kafka副本3.1 副本信息3.2 Leader选举流程3.3 Leader 和 Fol…

【成都】EFDC建模方法、SWAT模型高阶研修

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证应用 为了定量地描述地表水环境质量与污染排放之间的动态关系&#xff0c;EFDC、MIKE、Delft3D、Qual2K等数值模型被广泛应用在环境、水务、海洋等多个领域。Environmental Fluid Dynamics Code&#xff08;EFDC&#…

[NISACTF 2022]checkin

[NISACTF 2022]checkin 直接给了源码&#xff0c;乍一看非常的简单&#xff0c;但是这题有坑。其实看注释颜色不一样&#xff0c;也能发现不对劲了。 贴一个payload&#xff0c;?ahahahahajitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan%E2%80%AE%E2…

ARM异常处理详解

前言&#xff1a; 学习一门处理器最重要的就是掌握该处理器的指令集和异常处理。 异常概念&#xff1a; 处理器在正常执行程序时可能会遇到一些不正常的事件发生&#xff0c;这时处理器就要将当前的程序暂停下来转去处理这个异常的事件&#xff0c;异常处理后再返回到被异常打…

需求分析引言:架构漫谈(五)架构师成长之路

我研发领域也从事了一些年&#xff0c;期间也做过一些架构设计工作&#xff0c;包括C#单体转型为Java微服务、Python单体转型为Java微服务等&#xff0c; 也尝试着从自己的经验角度&#xff0c;来汇总一些知识点&#xff0c;同时描述一下如何成长为一个合格的软件架构师&#x…

权限管理系统后端实现1-SpringSecurity执行原理概述

spring security的简单原理&#xff1a; SpringSecurity有很多很多的拦截器&#xff0c;在执行流程里面主要有两个核心的拦截器 1&#xff0c;登陆验证拦截器AuthenticationProcessingFilter 2&#xff0c;资源管理拦截器AbstractSecurityInterceptor 但拦截器里面的实现需要…

IDEA+Spring Boot + MyBatis + Layui+Mysql垃圾回收管理系统源码

IDEASpring Boot MyBatis LayuiMysql垃圾回收管理系统源码 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.垃圾回收管理3.添加需要回收的垃圾4.垃圾去向管理5.申请需要打包运出的垃圾6.系统公告管理7.个人信息管理8.修改密码 三、部分代码UserMapper.javaUserControlle…

Python的网络爬虫框架-网络爬虫常用框架

Python的网络爬虫框架-网络爬虫常用框架 一、前言二、引言三、Scrapy 爬虫框架四、Crawley 爬虫框架五、PySpider 爬虫框架 一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起来了解Python的网络爬虫框架-网络爬虫常用框架如果文章对你有帮助、欢迎关注、点…

Redis缓存同步1-策略介绍

缓存数据同步策略示意图 在大多数情况下&#xff0c;我们通过浏览器查询到的数据都是缓存数据&#xff0c;如果缓存数据与数据库的数据存在较大差异的话&#xff0c;可能会产生比较严重的后果的。所以&#xff0c;我们应该也必须保证数据库数据、缓存数据的一致性&#xff0c;…