Python多进程爬取电影信息

news2024/11/25 13:40:28

观察翻页时详情页面url地址变化规律
在这里插入图片描述

import json
from os import makedirs
from os.path import exists
import requests
import logging
import re
from urllib.parse import urljoin
import multiprocessing

# 定义了下日志输出级别和输出格式
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s: %(message)s')

BASE_URL = 'https://ssr1.scrape.center'
TOTAL_PAGE = 10

RESULTS_DIR = 'results'
exists(RESULTS_DIR) or makedirs(RESULTS_DIR)

# 爬取列表页
def scrape_page(url):
    """
    scrape page by url and return its html
    :param url: page url
    :return: html of page
    """
    logging.info('scraping %s...', url)
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        logging.error('get invalid status code %s while scraping %s',
                      response.status_code, url)
    except requests.RequestException:
        logging.error('error occurred while scraping %s', url, exc_info=True)

# 爬取详情列表页
def scrape_index(page):
    """
    scrape index page and return its html
    :param page: page of index page
    :return: html of index page
    """
    index_url = f'{BASE_URL}/page/{page}'
    return scrape_page(index_url)

# 解析详情列表页
def parse_index(html):
    """
    parse index page and return detail url
    :param html: html of index page
    """
    pattern = re.compile('<a.*?href="(.*?)".*?class="name">')
    items = re.findall(pattern, html)
    if not items:
        return []
    for item in items:
        detail_url = urljoin(BASE_URL, item)
        logging.info('get detail url %s', detail_url)
        yield detail_url

# 爬取详情页
def scrape_detail(url):
    """
    scrape detail page and return its html
    :param page: page of detail page
    :return: html of detail page
    """
    return scrape_page(url)

# 解析详情页正则匹配方法
def parse_detail(html):
    """
    parse detail page
    :param html: html of detail page
    :return: data
    """

    cover_pattern = re.compile(
        'class="item.*?<img.*?src="(.*?)".*?class="cover">', re.S)
    name_pattern = re.compile('<h2.*?>(.*?)</h2>')
    categories_pattern = re.compile(
        '<button.*?category.*?<span>(.*?)</span>.*?</button>', re.S)
    published_at_pattern = re.compile('(\d{4}-\d{2}-\d{2})\s?上映')
    drama_pattern = re.compile('<div.*?drama.*?>.*?<p.*?>(.*?)</p>', re.S)
    score_pattern = re.compile('<p.*?score.*?>(.*?)</p>', re.S)
    
    # 结果只有一个,用 search 方法提取即可
    # 结果有多个,使用 findall 方法提取,结果是一个列表
    cover = re.search(cover_pattern, html).group(
        1).strip() if re.search(cover_pattern, html) else None
    name = re.search(name_pattern, html).group(
        1).strip() if re.search(name_pattern, html) else None
    categories = re.findall(categories_pattern, html) if re.findall(
        categories_pattern, html) else []
    published_at = re.search(published_at_pattern, html).group(
        1) if re.search(published_at_pattern, html) else None
    drama = re.search(drama_pattern, html).group(
        1).strip() if re.search(drama_pattern, html) else None
    score = float(re.search(score_pattern, html).group(1).strip()
                  ) if re.search(score_pattern, html) else None

    return {
        'cover': cover,
        'name': name,
        'categories': categories,
        'published_at': published_at,
        'drama': drama,
        'score': score
    }


# 解析详情页pq方法
from pyquery import PyQuery as pq
def parse_detail(html):
    """
    parse detail page
    :param html: html of detail page
    :return: data
    """
    doc = pq(html)
    cover = doc('img.cover').attr('src')
    name = doc('a > h2').text()
    categories = [item.text() for item in doc('.categories button span').items()]
    published_at = doc('.info:contains(上映)').text()
    published_at = re.search('(\d{4}-\d{2}-\d{2})', published_at).group(1) \
        if published_at and re.search('\d{4}-\d{2}-\d{2}', published_at) else None
    drama = doc('.drama p').text()
    score = doc('p.score').text()
    score = float(score) if score else None
    return {
        'cover': cover,
        'name': name,
        'categories': categories,
        'published_at': published_at,
        'drama': drama,
        'score': score
    }


# 保存数据
def save_data(data):
    """
    save to json file
    :param data:
    :return:
    """
    name = data.get('name')
    data_path = f'{RESULTS_DIR}/{name}.json'
    json.dump(data, open(data_path, 'w', encoding='utf-8'),
              ensure_ascii=False, indent=2)

# main 方法
def main(page):
    """
    main process
    :return:
    """
    index_html = scrape_index(page)
    detail_urls = parse_index(index_html)
    for detail_url in detail_urls:
        detail_html = scrape_detail(detail_url)
        data = parse_detail(detail_html)
        logging.info('get detail data %s', data)
        logging.info('saving data to json file')
        save_data(data)
        logging.info('data saved successfully')

# 多进程加速
if __name__ == '__main__':
    pool = multiprocessing.Pool()
    pages = range(1, TOTAL_PAGE + 1)
    pool.map(main, pages)
    pool.close()



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

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

相关文章

Java——》synchronized编译

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

python+selenium自动化测试项目实战

说明&#xff1a;本项目采用流程控制思想&#xff0c;未引用unittest&pytest等单元测试框架 一.项目介绍 目的 测试某官方网站登录功能模块可以正常使用 用例 1.输入格式正确的用户名和正确的密码&#xff0c;验证是否登录成功&#xff1b; 2.输入格式正确的用户名和不…

想做交传翻译,如何成为一名专业的交传译员?

据了解&#xff0c;交传翻译指的是在会议进行过程中&#xff0c;译员快速地记录演讲者发言内容&#xff0c;在主讲者发言间隙&#xff0c;将上一段演讲内容翻译成目标语言并演讲个观众听。那么&#xff0c;如何成为一名专业的交传译员&#xff1f; 交传译员必须具备的能力有哪…

阿里云ubuntu服务器搭建ftp服务器

阿里云ubuntu服务器搭建ftp服务器 服务器环境安装步骤一.创建用户二.安装 vsftp三 配置vsftp四.配置阿里云安全组 服务器环境 阿里云上的云服务器&#xff0c;操作系统为 ubuntu20.04。 安装步骤 一.创建用户 为什么需要创建用户&#xff1f; 这里的用户&#xff0c;指的是…

Spring MVC入门必读:实现增删改查

目录 引言 一、前期准备 1.1.搭建Maven环境 1.2.导入pom.xml依赖 1.3.导入配置文件 ①jdbc.properties ②generatorConfig.xml ③log4j2.xml ④spring-mybatis.xml ⑤spring-context.xml ⑥spring-mvc.xml ⑦修改web.xml文件 二、逆向生成增删改查 2.1.导入相关u…

Visual Studio 2022 同步代码报错:Authentication failed...

1.使用其他git GUI工具&#xff0c;例如&#xff1a;TortoiseGit 能够正常拉取和推送项目&#xff0c; 但如果使用Visual Studio 2022 里面的git 代码管理工具拉取项目时&#xff0c;报错弹窗如下。 打开输出窗口,查看报错详细&#xff1a;点击Visual Studio 2022顶部菜单栏里…

win11和虚拟机上的ubuntu系统共享文件夹

出发点&#xff1a;有时候需要在虚拟机内和win11系统之间进行文件拷贝操作&#xff0c;但是虚拟机内的Vmware Tools不好用 解决方式 开启虚拟机共享文件夹 在虚拟机的Ubuntu系统内的终端命令行输入以下命令 sudo /usr/bin/vmhgfs-fuse .host:/SVMware /mnt/win -o subtype…

selenium 自动化测试:如何搭建自动化测试环境,搭建环境过程应该注意的问题

最近也有很多人私下问我&#xff0c;selenium学习难吗&#xff0c;基础入门的学习内容很多是3以前的版本资料&#xff0c;对于有基础的人来说&#xff0c;3到4的差别虽然有&#xff0c;但是不足以影响自己&#xff0c;但是对于没有学过的人来说&#xff0c;通过资料再到自己写的…

2024年天津农学院专升本增加水文与水资源专业更名报考范围的通知

天津农学院2024年关于增加高职升本科“水文与水资源工程” 报考专业范围的通知 各位考生&#xff1a; 根据教育部《职业教育专业目录&#xff08;2021年&#xff09;》&#xff08;教职成〔2021〕2号&#xff09;相关内容要求&#xff0c;天津农学院专升本“水文与水资源工程”…

代码随想录算法训练营第45天 | ● 70. 爬楼梯 (进阶)● 322. 零钱兑换 ● 279.完全平方数11

文章目录 前言一、70. 爬楼梯 &#xff08;进阶&#xff09;二、322. 零钱兑换三、279.完全平方数总结 前言 完全背包&#xff1b; 一、70. 爬楼梯 &#xff08;进阶&#xff09; 第44天的blog里面有提到这个题目&#xff0c;本质上还是完全背包&#xff1b;另外&#xff0c;例…

spring-secrity的Filter顺序+自定义过滤器

Filter顺序 Spring Security的官方文档向我们提供了filter的顺序&#xff0c;实际应用中无论用到了哪些&#xff0c;整体的顺序是保持不变的: ChannelProcessingFilter&#xff0c;重定向到其他协议的过滤器。也就是说如果你访问的channel错了&#xff0c;那首先就会在channel…

【LeetCode-中等题】79. 单词搜索

文章目录 题目方法一&#xff1a;递归 回溯 题目 方法一&#xff1a;递归 回溯 需要一个标记数组 来标志格子字符是否被使用过了先找到word 的第一个字符在表格中的位置&#xff0c;再开始递归递归的结束条件是如果word递归到了最后一个字符了&#xff0c;说明能在矩阵中找到单…

学历低不能学编程?

最近&#xff0c;有小伙伴向小编提问&#xff1a;自己学历低是否可以学编程呢&#xff1f;围绕这个问题&#xff0c;相信也有不少小伙伴也有这个疑问&#xff0c;那就让我们一起来揭晓这个谜底吧&#xff01; 答案是&#xff1a;当然可以&#xff01;为什么呢&#xff1f; 首…

在线积分求解网站和求解举例

在线积分求解网站和求解举例 在进行复杂计算时&#xff0c;有时会遇到积分求解的问题&#xff0c;基于大学高数、积分变换、复变函数或者矩阵论等理论知识可以通过解析方式求解所遇到的积分问题。在这个求解过程中&#xff0c;能够清晰的理解积分求解基本知识和技巧。有时&…

macbook命令行乱码处理办法

作者&#xff1a;吴业亮 博客&#xff1a;wuyeliang.blog.csdn.net 1、设置编码 2、在终端下输入在这里插入代码片 vi ~/.zshrc在文件内容末端添加&#xff1a; export LC_ALLen_US.UTF-8 export LANGen_US.UTF-8最后再让设置生效 source ~/.zshrc

web请求cookie中expires总结

用意 cookie 有失效日期 "expires"&#xff0c;如果还没有过失效期&#xff0c;即使重新启动电脑&#xff0c;cookie 仍然不会丢失 注意&#xff1a;如果没有指定 expires 值&#xff0c;那么在关闭浏览器时&#xff0c;cookie 即失效。 设置 如果cookie存储时间大…

【GO语言基础】变量常量

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 【GO语言基础】运算符 文章目录 系列文章目录常量和枚举变量声明全局变量声明大小写敏感 总结 常量和枚举 使用const关键字声明常量&#xff0c;并为每个常量提…

游戏平台加盟该怎么做?需要准备什么?

游戏平台加盟是一种合作模式&#xff0c;允许个人或企业以加盟商的身份参与游戏平台&#xff0c;并从中获得一定的权益和收益。以下是一些步骤和需要准备的事项&#xff0c;来考虑如何进行游戏平台加盟&#xff1a; 步骤&#xff1a; 研究市场和平台&#xff1a;了解游戏市场和…

【Python+selenium】自动化生成测试报告

批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。 unittest里面是不能生成html格式报告的&#xff0c;需要导入一个第三方的模块&#xff1a;HTMLTestRunner 一、入HTMLTe…

BMS电池管理系统——BMS的功能模块及基本要素(二)

BMS电池管理系统 文章目录 BMS电池管理系统前言一、BMS电池管理系统各个功能模块的关系二、BMS的边界及基本要素 前言 前面了解了BMS以及他的功能模块&#xff0c;这些功能模块之间的关系是什么呢&#xff1f; 一、BMS电池管理系统各个功能模块的关系 下面我们分析一下这张图…