Python selenium 多处理

2025-03-25 08:47:00
admin
原创
18
摘要:问题描述:我用 python 编写了一个脚本,结合 selenium 从其登录页面抓取不同帖子的链接,最后通过跟踪指向其内页的 url 来获取每篇帖子的标题。虽然我在这里解析的内容是静态的,但我使用了 selenium 来查看它在多处理中的工作原理。但是,我的目的是使用多处理进行抓取。到目前为止,我知道 se...

问题描述:

我用 python 编写了一个脚本,结合 selenium 从其登录页面抓取不同帖子的链接,最后通过跟踪指向其内页的 url 来获取每篇帖子的标题。虽然我在这里解析的内容是静态的,但我使用了 selenium 来查看它在多处理中的工作原理。

但是,我的目的是使用多处理进行抓取。到目前为止,我知道 selenium 不支持多处理,但看来我错了。

我的问题是:当使用多处理运行时,如何使用 selenium 减少执行时间?

This is my try (it's a working one)

import requests
from urllib.parse import urljoin
from multiprocessing.pool import ThreadPool
from bs4 import BeautifulSoup
from selenium import webdriver

def get_links(link):
  res = requests.get(link)
  soup = BeautifulSoup(res.text,"lxml")
  titles = [urljoin(url,items.get("href")) for items in soup.select(".summary .question-hyperlink")]
  return titles

def get_title(url):
  chromeOptions = webdriver.ChromeOptions()
  chromeOptions.add_argument("--headless")
  driver = webdriver.Chrome(chrome_options=chromeOptions)
  driver.get(url)
  sauce = BeautifulSoup(driver.page_source,"lxml")
  item = sauce.select_one("h1 a").text
  print(item)

if __name__ == '__main__':
  url = "https://stackoverflow.com/questions/tagged/web-scraping"
  ThreadPool(5).map(get_title,get_links(url))

解决方案 1:

当使用多处理运行时,如何使用 selenium 减少执行时间

您的解决方案中,很多时间都花在为每个 URL 启动 Web 驱动程序上。您可以通过每个线程仅启动一次驱动程序来减少此时间:

(... skipped for brevity ...)

threadLocal = threading.local()

def get_driver():
  driver = getattr(threadLocal, 'driver', None)
  if driver is None:
    chromeOptions = webdriver.ChromeOptions()
    chromeOptions.add_argument("--headless")
    driver = webdriver.Chrome(chrome_options=chromeOptions)
    setattr(threadLocal, 'driver', driver)
  return driver


def get_title(url):
  driver = get_driver()
  driver.get(url)
  (...)

(...)

在我的系统上,这将时间从 1 分 7 秒缩短至 24.895 秒,提升了约 35%。若要自行测试,请下载完整脚本。

注意:ThreadPool使用受 Python GIL 约束的线程。如果大部分任务受 I/O 限制,那么这样做没问题。根据您对抓取结果进行的后处理,您可能希望改用multiprocessing.Pool。这将启动并行进程,这些进程作为一个组不受 GIL 约束。其余代码保持不变。

解决方案 2:

我认为巧妙的“每个线程一个驱动程序”解决方案的一个潜在问题是,它忽略了“退出”驱动程序的任何机制,因此留下了进程挂起的可能性。我会做以下更改:

  1. 而是使用类Driver来创建驱动程序实例并将其存储在线程本地存储中,但也有一个析构函数,quit当线程本地存储被删除时,该驱动程序将析构:

class Driver:
    def __init__(self):
        options = webdriver.ChromeOptions()
        options.add_argument("--headless")
        self.driver = webdriver.Chrome(options=options)

    def __del__(self):
        self.driver.quit() # clean up driver when we are cleaned up
        #print('The driver has been "quitted".')
  1. create_driver现在变成:

threadLocal = threading.local()

def create_driver():
    the_driver = getattr(threadLocal, 'the_driver', None)
    if the_driver is None:
        the_driver = Driver()
        setattr(threadLocal, 'the_driver', the_driver)
    return the_driver.driver
  1. 最后,在您不再使用ThreadPool实例之后但在终止之前,添加以下几行以删除线程本地存储并强制Driver调用实例的析构函数(希望如此):

del threadLocal
import gc
gc.collect() # a little extra insurance

解决方案 3:

我的问题:如何减少执行时间?

Selenium 似乎不适合进行网页抓取 - 尽管我很欣赏 YMMV,特别是当你需要模拟用户与网站的交互或者存在某些 JavaScript 限制/要求时。

对于不需要太多交互的抓取任务,我使用开源Scrapy Python 包进行大规模抓取任务取得了良好的效果。它具有开箱即用的多处理功能,可以轻松编写新脚本并将数据存储在文件或数据库中 - 而且速度非常

当作为完全并行的 Scrapy 蜘蛛实现时,你的脚本看起来会像这样(注意,我没有测试过这个,请参阅选择器的文档)。

import scrapy
class BlogSpider(scrapy.Spider):
    name = 'blogspider'
    start_urls = ['https://stackoverflow.com/questions/tagged/web-scraping']

    def parse(self, response):
        for title in response.css('.summary .question-hyperlink'):
            yield title.get('href')

要运行,请将其放入blogspider.py并运行

$ scrapy runspider blogspider.py

请参阅Scrapy 网站以获取完整教程。

请注意,得益于 @SIM 的提示,Scrapy 还通过scrapy-splash支持 JavaScript 。到目前为止,我还没有接触过它,所以除了它看起来与 Scrapy 的工作方式很好地集成在一起之外,我无法谈论它。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1989  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1446  
  在当今快速发展的IT行业中,项目管理工具的选择对于项目的成功至关重要。随着技术的不断进步,项目经理们需要更加高效、灵活的工具来应对复杂的项目需求。本文将介绍2025年IT项目经理力推的10款管理工具,帮助您在项目管理中取得更好的成果。信创国产项目管理软件 - 禅道禅道是一款国产开源的项目管理软件,禅道开源版不限人数,功...
项目管理工具   0  
  在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目成功的关键工具。随着技术的不断进步,市场上涌现出众多功能各异的项目管理工具,每一款都有其独特的优势和适用场景。本文将深入评测2025年最受欢迎的10款项目管理软件,帮助您根据自身需求做出明智的选择。信创国产项目管理软件 - 禅道禅道是一款...
项目管理平台   2  
  产品开发效率对于企业的竞争力至关重要。在当今复杂多变的商业环境中,如何有效提升产品开发效率成为众多企业关注的焦点。产品生命周期管理(PLM)作为一种整合产品全生命周期信息的管理理念和技术,为提升产品开发效率提供了有力的支持。通过合理运用PLM,企业能够优化流程、加强协作、提高数据管理水平,从而实现产品开发的高效运作。接...
plm开发流程软件   3  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用