Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Python爬虫实战】多进程结合 BeautifulSoup 与 Scrapy 构建爬虫项目

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

作者头像
易辰君
发布于 2024-11-07 14:25:07
发布于 2024-11-07 14:25:07
18000
代码可运行
举报
文章被收录于专栏:CSDNCSDN
运行总次数:0
代码可运行

前言

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

一、多进程爬虫

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

(一)多进程的基本概念

  • 多进程:通过创建多个进程来并行执行任务。每个进程都有自己的内存空间和解释器,可以独立工作,适合 CPU 密集型任务。
  • 进程池:使用multiprocessing.Pool可以方便地管理多个进程,自动调度任务。

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

  • 提高速度:可以同时请求多个网页,缩短抓取时间。
  • 避免 GIL 限制:Python 的全局解释器锁(GIL)会限制单线程执行,但多进程可以绕过这一限制。

(三)示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 进行网页抓取和解析。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 实现轻量级爬虫

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

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 爬虫。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 爬虫实例。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 的异步能力与多进程结合则更为适用。在实际应用中,合理设计爬虫结构和任务管理机制,能够显著提升数据抓取效率。这不仅可以帮助开发者应对数据采集的挑战,更为大数据分析和挖掘奠定了基础。希望本文的介绍能够为你的爬虫项目提供有价值的参考和帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
爬虫入门指南(5): 分布式爬虫与并发控制 【提高爬取效率与请求合理性控制的实现方法】
在Python中,可以使用标准库中的threading模块实现多线程编程。具体步骤如下:
全栈若城
2024/02/29
9240
爬虫入门指南(5): 分布式爬虫与并发控制 【提高爬取效率与请求合理性控制的实现方法】
Python多进程:如何在不依赖Queue的情况下传递结果
随着数据的爆炸式增长,网络爬虫成为获取信息的强大工具。在爬取大量数据时,多进程技术可以显著提高效率。然而,如何在多进程中传递结果,而不依赖Queue,成为了一个值得探讨的问题。本文将以采集抖音短视频为案例,详尽讲解如何在Python中实现这一目标。
jackcode
2024/07/31
1510
Python多进程:如何在不依赖Queue的情况下传递结果
Python多线程与多进程详解:性能提升技巧与实战案例
文章链接:https://cloud.tencent.com/developer/article/2464989
一键难忘
2024/11/12
5640
Python多线程与多进程详解:性能提升技巧与实战案例
小白爬虫之爬虫快跑,多进程和多线程
使用多线程时好像在目录切换的问题上存在问题,可以给线程加个锁试试 Hello 大家好!我又来了。 你是不是发现下载图片速度特别慢、难以忍受啊!对于这种问题 一般解决办法就是多进程了!一个进程速度慢!我就用十个进程,相当于十个人一起干。速度就会快很多啦!(为什么不说多线程?懂点Python的小伙伴都知道、GIL的存在 导致Python的多线程有点坑啊!)今天就教大家来做一个多进程的爬虫(其实吧、可以用来做一个超简化版的分布式爬虫) 其实吧!还有一种加速的方法叫做“异步”!不过这玩意儿我没怎么整明白就不出来误人
企鹅号小编
2018/01/30
7460
Python爬虫性能优化:多进程协程提速实践指南
各位大佬们我又回来了,今天我们来聊聊如何通过多进程和协程来优化Python爬虫的性能,让我们的爬虫程序6到飞起!我将会提供一些实用的解决方案,让你的爬虫速度提升到新的高度!
华科云商小徐
2023/08/17
5500
Scrapy vs BeautifulSoup
在本教程中,我们将会讨论Scrapy和BeautifulSoup,比较它们有何不同,从而帮助你们来做出选择,哪一个对于你们的实际项目中是最合适的.
别打名名
2019/12/23
2.3K0
Scrapy vs BeautifulSoup
Python3多进程+协程异步爬取小说
之前写了一篇关于用多线程爬小说的博客,但是发现爬取16M的小说需要十几分钟,所以今天更新了一篇用多进程外加使用单线程异步的协程同样爬取之前用多线程爬取的同一篇小说,并进行两者效率的对比
HcodeBlogger
2020/07/14
9350
Python3多进程+协程异步爬取小说
006:开启Scrapy爬虫项目之旅
上一篇文章介绍了Scrapy框架的安装及其目录结构和常用工具命令,相信大家也有了初步的认识。 本章将从实战编写来补充scrapy的基础知识
李玺
2021/11/22
8830
006:开启Scrapy爬虫项目之旅
百度贴吧 | 通用抓图脚本搞专业爬虫的话,先保证网速够好,再考虑多进程还是多线程~
多进程优势:单个进程的崩溃,不会影响其它进程 随之而来的问题是,进程之间,资源不共享,信息不共享,所以进程通讯的问题,是实现多进程协作,必须解决的问题 为解决进程间的通讯,人们常用的方法是 -
zhaoolee
2018/04/19
8450
百度贴吧 | 通用抓图脚本搞专业爬虫的话,先保证网速够好,再考虑多进程还是多线程~
精通Python爬虫框架Scrapy_php爬虫框架哪个好用
讲解Scrapy框架之前,为了让读者更明白Scrapy,我会贴一些网站的图片和代码。 但是,【注意!!!】 【以下网站图片和代码仅供展示!!如果大家需要练习,请自己再找别的网站练习。】 【尤其是政府网站,千万不能碰哦!】
全栈程序员站长
2022/11/01
1.2K0
Python爬虫-- Scrapy入门
转行做python程序员已经有三个月了,这三个月用Scrapy爬虫框架写了两百多个爬虫,不能说精通了Scrapy,但是已经对Scrapy有了一定的熟悉。准备写一个系列的Scrapy爬虫教程,一方面通过输出巩固和梳理自己这段时间学到的知识,另一方面当初受惠于别人的博客教程,我也想通过这个系列教程帮助一些想要学习Scrapy的人。
IT派
2018/07/30
7020
Python爬虫-- Scrapy入门
爬虫框架的选择与对比:Python爬虫框架的比较与评估
Hey大家好!作为一名专业的隧道代理供应商,我今天要和大家分享一些关于爬虫框架的知识。在开发爬虫项目时,选择一个合适的框架非常重要,它可以提高开发效率、简化操作并提供丰富的功能。Python作为一门流行的编程语言,拥有许多优秀的爬虫框架可供选择。在本文中,我将对比和评估几个常用的Python爬虫框架,帮助大家做出更明智的选择。废话不多说,让我们开始吧!
华科云商小彭
2023/08/10
7400
爬虫框架的选择与对比:Python爬虫框架的比较与评估
高级网页爬虫开发:Scrapy和BeautifulSoup的深度整合
引言 在互联网时代,数据的价值日益凸显。网页爬虫作为一种自动化获取网页内容的工具,广泛应用于数据挖掘、市场分析、内容聚合等领域。Scrapy是一个强大的网页爬虫框架,而BeautifulSoup则是一个灵活的HTML和XML文档解析库。本文将探讨如何将这两个工具深度整合,开发出高级的网页爬虫。
小白学大数据
2024/07/26
1790
Python多任务:多线程和多进程
python的多任务其实用了很久了,因为刚开始写代码的时候总是看网上说高并发、异步之类的,就觉得很高大上,所以刻意地去学过,后来在实际开发工作有过为了使用而使用,也有过真正因为性能问题而必须要使用。今天想把目前掌握的一些内容记录下来。
panzhixiang
2024/10/30
1090
[Python 爬虫]煎蛋网 OOXX 妹子图爬虫(2)——多线程+多进程下载图片
上一篇文章全面解析了煎蛋网的妹子图的图片链接解密的方式,已经可以通过 Python 爬虫代码批量获取每个页面中的图片地址。但是上一篇文章中并没有写图片下载的函数,这一篇文章就来使用 Python 的多线程和多进程来批量下载图片。
Hopetree
2022/09/26
7630
[Python 爬虫]煎蛋网 OOXX 妹子图爬虫(2)——多线程+多进程下载图片
6个强大且流行的Python爬虫库,强烈推荐!
Python中有非常多用于网络数据采集的库,功能非常强大,有的用于抓取网页,有的用于解析网页,这里介绍6个最常用的库。
派大星的数据屋
2024/07/17
1.6K0
6个强大且流行的Python爬虫库,强烈推荐!
Scrapy入门
Scrapy是一个强大的Python开源网络爬虫框架,用于抓取和提取网页数据。它提供了简单且灵活的API和强大的数据提取功能,使得开发者能够快速地构建和部署爬虫程序。本篇文章将介绍Scrapy的入门教程,帮助你快速上手。
大盘鸡拌面
2023/11/01
3010
Python 学习笔记 | 多进程爬虫
前段时间学习了多线程,但在实际的情况中对于多线程的速度实在不满意,所以今天就来学学多进程分布式爬虫,在这里感谢莫烦的Python教程。
TeamsSix
2019/12/30
7450
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
在Python的网页抓取领域,BeautifulSoup和Scrapy是两款备受推崇的工具。它们各自有着独特的优势和适用场景。本文将深入探讨这两者的特点,帮助您根据项目需求做出明智的选择。
jackcode
2025/02/25
1320
BeautifulSoup VS Scrapy:如何选择适合的HTML解析工具?
【Python爬虫实战】深入解析 Scrapy 爬虫框架:高效抓取与实战搭建全指南
在大数据时代,网络爬虫已经成为数据收集的重要工具。而 Scrapy 作为一个功能强大且高效的 Python 爬虫框架,以其模块化、异步处理和高度可扩展性,广泛应用于数据挖掘、监控和分析等领域。本指南将从 Scrapy 的基础概念到项目实践,带你全面了解如何搭建和优化一个 Scrapy 爬虫项目,不论是新手还是经验丰富的开发者,都能从中获益。
易辰君
2024/11/26
1.4K0
推荐阅读
相关推荐
爬虫入门指南(5): 分布式爬虫与并发控制 【提高爬取效率与请求合理性控制的实现方法】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验