【Python爬虫实战】多进程结合 BeautifulSoup 与 Scrapy 构建爬虫项目

#1024程序员节|征文#

  🌈个人主页:易辰君-CSDN博客
🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html

前言

在大数据时代,爬虫技术是获取和处理网络数据的利器。面对需要处理大量网页的爬取任务,如何提升效率成为了一个重要的问题。Python 的多进程技术结合 BeautifulSoupScrapy,可以在保证解析能力的同时,大大提高并发抓取的效率。这篇文章将详细介绍如何利用多进程模块进行爬虫、结合 JoinableQueue 管理任务,以及在更复杂的场景中使用 BeautifulSoupScrapy,打造功能强大的爬虫项目。


一、多进程爬虫

多进程爬虫是利用Python的多进程模块(如multiprocessing)来并发地抓取网页数据的一种方法。这种方法能够显著提高爬虫的效率,特别是在面对需要处理大量网页时。以下是一些关键点和实现步骤:

(一)多进程的基本概念

  • 多进程:通过创建多个进程来并行执行任务。每个进程都有自己的内存空间和解释器,可以独立工作,适合 CPU 密集型任务。

  • 进程池:使用multiprocessing.Pool可以方便地管理多个进程,自动调度任务。

(二)使用多进程爬虫的好处

  • 提高速度:可以同时请求多个网页,缩短抓取时间。

  • 避免 GIL 限制:Python 的全局解释器锁(GIL)会限制单线程执行,但多进程可以绕过这一限制。

(三)示例

import requests
from multiprocessing import Pool

def fetch_url(url):
    try:
        response = requests.get(url)
        print(f"Fetched {url}: {response.status_code}")
        return response.text
    except Exception as e:
        print(f"Failed to fetch {url}: {e}")

def main(urls):
    with Pool(processes=4) as pool:  # 创建4个进程
        results = pool.map(fetch_url, urls)  # 并发抓取
    return results

if __name__ == '__main__':
    urls = [
        'https://www.example.com',
        'https://www.example.org',
        'https://www.example.net',
        # 添加更多网址
    ]
    main(urls)

(四)注意事项

  • 请求频率:要合理控制请求频率,避免被目标网站封禁。

  • 异常处理:确保处理网络请求中的异常情况,防止程序崩溃。

  • 资源管理:爬取大量数据时,要合理管理内存和 CPU 资源。


二、多进程结合JoinableQueue队列

(一)介绍

使用多进程结合 JoinableQueue 来实现爬虫,可以有效管理任务的执行和跟踪任务完成情况。JoinableQueue 允许你在所有任务完成后进行一些后续操作,这对于处理大量网页的爬虫项目非常有用。

以下是一个使用 multiprocessing.JoinableQueue 的爬虫示例,结合 requestsBeautifulSoup 进行网页抓取和解析。

示例:

import requests
from bs4 import BeautifulSoup
from multiprocessing import Process, JoinableQueue
import time

# 定义爬虫工作函数
def worker(queue):
    while True:
        url = queue.get()  # 从队列中获取 URL
        if url is None:  # 用于退出条件
            queue.task_done()
            break
        print(f"Fetching: {url}")
        try:
            response = requests.get(url, timeout=5)
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')
                # 假设提取文章标题
                titles = soup.find_all('h2')
                for title in titles:
                    print(f"Title: {title.get_text()}")
            else:
                print(f"Failed to fetch {url}: {response.status_code}")
        except Exception as e:
            print(f"Error fetching {url}: {e}")
        finally:
            queue.task_done()  # 标记任务完成

# 主函数
def main(urls):
    queue = JoinableQueue()
    processes = []

    # 启动多个工作进程
    for _ in range(4):  # 根据需要启动的进程数
        p = Process(target=worker, args=(queue,))
        p.start()
        processes.append(p)

    # 向队列中添加 URL
    for url in urls:
        queue.put(url)

    # 等待队列中所有任务完成
    queue.join()  # 阻塞直到所有任务调用 task_done()

    # 发送退出信号给每个进程
    for _ in processes:
        queue.put(None)

    # 等待所有进程完成
    for p in processes:
        p.join()

if __name__ == '__main__':
    urls = [
        'https://www.example.com/page1',
        'https://www.example.com/page2',
        'https://www.example.com/page3',
        # 添加更多网址
    ]
    start_time = time.time()
    main(urls)
    print(f"All tasks completed in {time.time() - start_time:.2f} seconds.")

代码解释:

  • 引入库:引入 requests 进行 HTTP 请求,BeautifulSoup 进行 HTML 解析,multiprocessing 模块进行多进程管理。

  • 工作函数 worker

    • JoinableQueue 中获取 URL。

    • 请求页面并解析 HTML 内容。

    • 提取标题,并在控制台打印。

    • 每处理完一个 URL,调用 queue.task_done() 标记任务完成。

  • 主函数 main

    • 创建 JoinableQueue 实例。

    • 启动多个工作进程。

    • 向队列中添加待爬取的 URL。

    • 调用 queue.join(),阻塞主线程,直到所有任务都标记为完成。

    • 发送退出信号(None)给每个进程,确保所有进程能够正常退出。

  • 执行

    • if __name__ == '__main__' 下执行爬虫逻辑,开始爬取指定的 URL。

(二)使用场景

  • 适用于需要高并发、并且需要确保所有任务都能被处理的爬虫项目。

  • 适合处理大量网页抓取任务时,能够有效地管理工作流程和任务状态。


三、构建复杂的多进程项目

结合多进程与 BeautifulSoupScrapy 可以构建更高效、复杂的爬虫项目。根据项目规模和需求,可以选择不同的组合方式。下面介绍两种结合方式:使用 BeautifulSoup 与多进程实现一个轻量级爬虫,以及通过多进程管理多个 Scrapy 爬虫实例的方案。

(一)多进程 + BeautifulSoup 实现轻量级爬虫

这种方案适合中小型爬虫项目,手动管理请求和数据解析,同时使用多进程加速请求处理。适用于需要快速获取网页数据并做简单解析的场景。

示例:

import requests
from bs4 import BeautifulSoup
from multiprocessing import Process, JoinableQueue
import time

# 定义爬虫工作函数
def worker(queue):
    while True:
        url = queue.get()
        if url is None:  # 退出条件
            queue.task_done()
            break

        try:
            response = requests.get(url, timeout=5)
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')
                # 假设需要提取所有标题和链接
                titles = soup.find_all('h2')  # 根据实际结构调整
                for title in titles:
                    print(f"Title: {title.get_text()} - URL: {url}")
            else:
                print(f"Failed to fetch {url}: {response.status_code}")
        except Exception as e:
            print(f"Error fetching {url}: {e}")
        finally:
            queue.task_done()

# 主函数
def main(urls):
    queue = JoinableQueue()
    processes = []

    # 启动多个进程
    for _ in range(4):  # 启动4个工作进程
        p = Process(target=worker, args=(queue,))
        p.start()
        processes.append(p)

    # 添加 URL 到队列
    for url in urls:
        queue.put(url)

    # 等待队列中所有任务完成
    queue.join()

    # 发送退出信号给每个进程
    for _ in processes:
        queue.put(None)

    # 等待所有进程完成
    for p in processes:
        p.join()

if __name__ == '__main__':
    urls = [
        'https://www.example.com/page1',
        'https://www.example.com/page2',
        'https://www.example.com/page3',
        # 添加更多网址
    ]
    start_time = time.time()
    main(urls)
    print(f"All tasks completed in {time.time() - start_time:.2f} seconds.")

代码解释:

  • 使用 requests 库抓取网页,BeautifulSoup 解析 HTML。

  • 利用 multiprocessing.JoinableQueue 管理 URL 队列,每个进程独立处理一个 URL。

  • JoinableQueuetask_donejoin 方法确保主进程在所有任务完成后继续执行。

(二)多进程 + Scrapy 管理大型爬虫项目

Scrapy 是一个功能强大的爬虫框架,自带异步处理和数据管道,但在某些场景下,可以通过多进程来管理多个独立的爬虫任务,尤其是当需要同时爬取多个不同网站时。

(1)编写 Scrapy 爬虫

spiders/my_spider.py 中创建一个简单的 Scrapy 爬虫。

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['https://www.example.com']

    def parse(self, response):
        titles = response.css('h2::text').getall()  # 假设要提取的内容为 <h2> 标签的文本
        for title in titles:
            yield {'title': title}

(2)多进程管理多个 Scrapy 实例

创建一个 Python 脚本 run_spiders.py,在其中使用 multiprocessing 启动多个 Scrapy 爬虫实例。

示例:

from multiprocessing import Process
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from myproject.spiders.my_spider import MySpider

def run_spider():
    process = CrawlerProcess(get_project_settings())
    process.crawl(MySpider)
    process.start()

if __name__ == '__main__':
    processes = []

    # 启动多个爬虫进程
    for _ in range(3):  # 根据需求启动多个爬虫实例
        p = Process(target=run_spider)
        p.start()
        processes.append(p)

    # 等待所有爬虫进程完成
    for p in processes:
        p.join()

解释:

  • Scrapy 爬虫:在 my_spider.py 中定义爬虫规则,解析 h2 标签内容。

  • 多进程管理:通过 multiprocessing.Process 启动多个 Scrapy 爬虫实例,每个实例可以处理不同的任务。

  • 适用场景:当需要同时抓取多个不同的网站或执行多个独立爬虫任务时,这种方式可以提高抓取效率。

(三)设计复杂爬虫项目的建议

  • 合理选择并发模式:对于中小型项目,requests + BeautifulSoup + 多进程已经能达到较高的性能;对于大规模项目,Scrapy 是更好的选择。

  • 任务调度和监控:在多进程环境下,确保每个任务有清晰的调度和监控机制,防止资源浪费和任务卡死。

  • 错误处理:无论使用哪种组合方式,都要做好异常处理,避免因为某些 URL 或请求失败而导致整个爬虫崩溃。

  • 延迟和限速:为了避免被目标网站封禁,建议在多进程或异步请求中加入请求延迟和限速机制。

(四)多进行项目总结

  • 多进程 + BeautifulSoup:适合需要手动处理请求和解析的场景,通过 JoinableQueue 管理任务,简单易用。

  • 多进程 + Scrapy:适用于需要处理大规模数据抓取的场景,能够利用 Scrapy 的异步特性,同时通过多进程管理多个任务,适合大规模爬虫项目。


四、总结

通过结合 Python 的多进程能力与数据解析库,如 BeautifulSoupScrapy,我们可以打造高效且灵活的爬虫系统。对于中小型项目,使用多进程加速抓取和解析是一个便捷的选择,而在处理大规模任务时,Scrapy 的异步能力与多进程结合则更为适用。在实际应用中,合理设计爬虫结构和任务管理机制,能够显著提升数据抓取效率。这不仅可以帮助开发者应对数据采集的挑战,更为大数据分析和挖掘奠定了基础。希望本文的介绍能够为你的爬虫项目提供有价值的参考和帮助。

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

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

相关文章

ChatGPT实现旅游推荐微信小程序

随着旅游行业的快速发展&#xff0c;个性化推荐已成为提升用户体验的重要手段。通过AI技术&#xff0c;提供一个智能旅游推荐小程序&#xff0c;使用户能够轻松获取定制化的旅行建议。 项目概述 项目目标 开发一个AI旅游推荐小程序&#xff0c;基于用户输入的旅行偏好&#…

Visual Studio安装图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 教程说明 本教程旨在详细介绍 Visual Studio 社区版的安装过程及其注意事项。 Visual Studio简介 Visual Studio 社区版功能完备且可扩展的免费 IDE&#xff0c;可用于创…

【WPF】中Dispatcher的DispatcherPriority参数使用

在 WPF 中&#xff0c;DispatcherPriority 参数用于指定通过 Dispatcher 调度的操作的执行优先级。加入 DispatcherPriority 参数的情况通常取决于你希望操作何时以及如何被执行。 1.Dispatcher的DispatcherPriority参数使用 以下是几种情况和示例说明&#xff1a; 1.1 需要…

【STM32 Blue Pill编程实例】-控制步进电机(ULN2003+28BYJ-48)

控制步进电机(ULN2003+28BYJ-48) 文章目录 控制步进电机(ULN2003+28BYJ-48)1、步进电机介绍2、ULN2003步进电机驱动模块3、硬件准备及接线4、模块配置3.1 定时器配置3.2 ULN2003输入引脚配置4、代码实现在本文中,我们将介使用 STM32Cube IDE 使用 ULN2003 电机驱动器来控制28B…

自由学习记录(14)

unity操作问题 位置&#xff1a;子物体的位置是相对于父物体的。如果你移动父物体&#xff0c;子物体会保持相对于父物体的相对位置&#xff0c;跟着一起移动。 旋转&#xff1a;子物体的旋转也是相对于父物体的。旋转父物体会导致子物体围绕父物体的原点旋转。 缩放&#xf…

【HarmonyOS NEXT】鸿蒙开发环境准备

0. 引言 看了发布会以后&#xff0c;热血澎湃啊&#xff0c;是时候学学把自己做的一些小工具搞成鸿蒙版了&#xff01;&#xff01;&#xff01; 1. 开发工具下载 下载地址&#xff1a;https://pan.quark.cn/s/08ddebdb7a20 工具版本会不定时更新&#xff0c;下载最新版即可…

【网络原理】——HTTP协议、fiddler抓包

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识HTTP 1&#xff1a;超文本传输 2&#xff1a;发展历史 3&#xff1a;HTML 4&am…

Axure树形菜单展开与折叠

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;Axure树形菜单展开与折叠 主要内容&#xff1a;树形菜单制作——层级关系——隐藏与显示——值的变化——多层交互 应用场景&#xff1a;关系树、菜…

R语言机器学习算法实战系列(十)自适应提升分类算法 (Adaptive Boosting)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理步骤教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性保存模型总…

断点续传技术是什么?大型文件传输的新模式!

随着科技的不断进步&#xff0c;文件传输已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;传输大型文件时常常会遇到网络不稳定、传输中断等问题&#xff0c;导致传输失败或者重新传输。为解决这一问题&#xff0c;断点续传技术应运而生。 一、断点续传技术是什么…

3GPP协议解读_NTN系列(一)_38.811_非地面网络(NTN)的背景、应用场景和信道建模

非地面网络 1. Scope4. 非地面网络背景介绍4.1 5G中的非地面网络4.2 非地面网络在5G中的用例4.3 卫星和空中接入网的架构4.4 卫星和空中接入网终端的特点4.5 空气/星载飞行器特性4.6 NTN的覆盖模式4.7 NTN网络架构选项4.8 频谱 5. 非地面网络应用场景5.1 应用场景概览5.2 属性介…

STM32通信协议-I2C

目录 一&#xff0c;IC2的协议规则 I2C总线是PHILIPS公司开发的两线式串行总线&#xff0c;I2C总线主要解决了单片机一对多通信的问题 两根通信线&#xff1a;SCL,SDA&#xff0c;同步&#xff0c;半双工通信&#xff0c;支持数据应答机制&#xff0c;支持总线挂载多设备。 …

2024ideaUI切换和svn与git的切换,svn的安装和配置,idea集成svn ,2024-10-18日

2024-10-18日 2024的UI实在很不舒服&#xff0c;隐藏了很多按键&#xff1b; 第一步&#xff1a; 视图 -》 外观 -》 工具栏选出来&#xff1b; 结果出来&#xff1a; 运行的按键和设置的按钮 第二步 点击设置的按钮&#xff0c;选择最后一个&#xff0c;重启就行 结果 舒服&…

网站漏扫:守护网络安全的关键防线

网站漏洞扫描&#xff0c;简称漏扫&#xff0c;是一种针对网站进行漏洞检测的安全服务。网站漏洞扫描在网络安全中占据着至关重要的地位。 网站漏扫在及时发现和修复漏洞方面发挥着关键作用 通过对网站和系统的全面扫描&#xff0c;能够快速识别出各种潜在的漏洞&#xff0c;…

网络安全领域推荐证书介绍及备考指南

在网络安全领域&#xff0c;拥有专业认证不仅可以证明个人的专业能力&#xff0c;还能帮助在实际工作中应用先进的技术和知识。以下是几种热门的网络安全证书介绍及备考指南。 1. OSCP (Offensive Security Certified Professional) 证书简介 OSCP是针对渗透测试领域的入门级…

<项目代码>YOLOv8路面垃圾识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

实现简道云与企业微信的自动化数据集成

简道云入职新增企微成员西乡公司 在企业信息化管理中&#xff0c;数据的高效集成和实时同步是提升业务效率的重要环节。本文将分享一个具体的系统对接集成案例&#xff1a;如何通过轻易云数据集成平台&#xff0c;将简道云的数据无缝集成到企业微信&#xff0c;实现西乡公司新…

汽车免拆诊断案例 | 2023款零跑C01纯电车后备厢盖无法电动打开和关闭

故障现象  一辆2023款零跑C01纯电车&#xff0c;累计行驶里程约为2万km&#xff0c;车主进厂反映&#xff0c;后备厢盖无法电动打开和关闭。 故障诊断  接车后试车&#xff0c;操作后备厢盖外侧、驾驶人侧及遥控钥匙上的后备厢盖开启按钮&#xff0c;可以听到后备厢盖解锁的…

Golang | Leetcode Golang题解之第500题键盘行

题目&#xff1a; 题解&#xff1a; func findWords(words []string) (ans []string) {const rowIdx "12210111011122000010020202" next:for _, word : range words {idx : rowIdx[unicode.ToLower(rune(word[0]))-a]for _, ch : range word[1:] {if rowIdx[unico…

精益思维在新能源汽车研发中的应用体现

近年来&#xff0c;新能源汽车作为绿色出行的重要载体&#xff0c;其研发与生产模式正经历着深刻的变革。精益思维&#xff0c;这一源自制造业的管理理念&#xff0c;正逐步渗透并深刻影响着新能源汽车的研发过程&#xff0c;不仅提升了产品质量与生产效率&#xff0c;还促进了…