我开发了一个使用 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/