python - 让 Selenium Webdriver 跨 Celery 任务

标签 python selenium selenium-chromedriver celery

我开发了一个使用 Celery 处理任务的 Flask 网络应用程序。其中一项任务包括使用从 selenium chrome 驱动程序派生的自定义类抓取一堆页面(大约 200 个)。

@celery_app.task
def scrape_async():
   driver = MyDriver(exec_path=os.environ.get('CHROMEDRIVER_PATH'), options=some_chrome_options)
   
   # Update 'urls_to_scrape' attribute by finding the urls to scrape from a main url
   driver.find_urls_to_scrape_from_main_url()
   
   # Loop over each page and store the data in database
   for url in driver.urls_to_scrape:
      driver.scrape_page(url)

  # Exit driver
  driver.quit()

在要抓取的页面数量增加之前,这在本地和生产环境中都运行良好。我在 Heroku 上收到内存使用错误,并意识到该任务的内存占用量有多大。

经过一些研究,我发现在我的循环中使用子任务会更容易(即为每个页面运行这个子任务),如下所述。

@celery_app.task
def subtask(url):
  driver.scrape_page(url)

@celery_app.task
def scrape_async():
   driver = MyDriver(exec_path=os.environ.get('CHROMEDRIVER_PATH'), options=some_chrome_options)
   
   # Update 'urls_to_scrape' attribute by finding the urls to scrape from a main url
   driver.find_urls_to_scrape_from_main_url()
   
   # Loop over each page and store the data in database
   for url in driver.urls_to_scrape:
      subtask.delay(url)

  # Exit driver
  driver.quit()

我关心的是如何在主任务和子任务之间保持驱动对象。 我找到了这个 link ,关于如何实例化任务,但我无法跨多个任务创建一个驱动程序。

关于如何实现我的目标有什么想法吗?

谢谢

最佳答案

如果您使用分布式爬网,一种方法是使用 selenium 网格,这样做可以减少加载、渲染 html、执行 js 脚本到其他服务器的资源使用量。

这样做的话,如果你正在使用任务后端,如果你正在爬取嵌套链接,那么你不需要为工作人员挑选的东西而烦恼,多个嵌套页面可以由多个工作人员独立爬取,并且所需的 mata 数据可以是通过使用带有 celery 中的组链和和弦功能的结果后端。

关于python - 让 Selenium Webdriver 跨 Celery 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65656175/

相关文章:

java - 如何通过selenium webdriver关闭chrome浏览器上的代理设置?

python - ctypes python 中的浮点指针并传递结构指针

python - 使用py2exe将python脚本编译为exe,出现错误

java - 无法从 加载扩展。 list 文件丢失或不可读 - 没有扩展名

python - 由于某种原因无法从 p 标签获取文本 - Selenium (Python)

java - 在 centos/linux 上运行带缓存的 selenium

javascript - 如何使通过 webkit 的 JS 与通过 chromedriver 的 JS 一样工作?

python - 如何将用户输入存储为多个条目,然后允许用户搜索他们创建的项目?

java - 游戏引擎重制 - 选择语言/API(Java 或 Python)时遇到问题

python - 如何使用 Bottle 返回 JSON 数组?