首页 > 解决方案 > 使用 selenium 一次抓取多个网页

问题描述

我正在使用seleniumPython 做一个大项目。我必须一个一个地浏览 320.000 个网页(320K)并抓取详细信息,然后睡一秒钟并继续前进。

像下面这样:

links = ["https://www.thissite.com/page=1","https://www.thissite.com/page=2", "https://www.thissite.com/page=3"]

for link in links:
    browser.get(link )
    scrapedinfo = browser.find_elements_by_xpath("*//div/productprice").text
    open("file.csv","a+").write(scrapedinfo)
    time.sleep(1)

最大的问题:太慢了!

使用这个脚本,我需要几天甚至几周的时间。

我花了几个小时在 google 和 Stackoverflow 上寻找答案,但只找到了multiprocessing.

但是,我无法在我的脚本中应用它。

标签: pythonpython-3.xseleniumselenium-webdriverselenium-chromedriver

解决方案


线程方法

  • 您应该从它开始,threading.Thread它会给您带来相当大的性能提升在此处解释)。线程也比进程轻。您可以使用futures.ThreadPoolExecutor每个线程使用它自己的 webdriver。还可以考虑为您的 webdriver 添加headless选项。下面使用 chrome-webdriver 的示例:
from concurrent import futures

def selenium_work(url):
    chromeOptions = webdriver.ChromeOptions()
    chromeOptions.add_argument("--headless") 
    driver = webdriver.Chrome(options=chromeOptions)  
    #<actual work that needs to be done be selenium>

# default number of threads is optimized for cpu cores 
# but you can set with `max_workers` like `futures.ThreadPoolExecutor(max_workers=...)`
with futures.ThreadPoolExecutor() as executor:     
    # store the url for each thread as a dict, so we can know which thread fails
    future_results = { url : executor.submit(selenium_work, links) for url in links }
    for url, future in future_results.items(): 
        try:        
           future.result() # can use `timeout` to wait max seconds for each thread  
      except Exception as exc: # can give a exception in some thread
           print('url {:0} generated an exception: {:1}'.format(url, exc))

  • 还考虑使用 . 存储chrome-driver在每个线程上初始化的实例threading.local()从这里他们报告了合理的性能改进。

  • 考虑BeautifulSoup直接在 selenium 的页面上使用是否可以提供其他一些加速。这是一个非常快速且稳定的软件包。示例类似 driver.get(url) ... soup = BeautifulSoup(driver.page_source,"lxml") ... result = soup.find('a')

其他方法

  • 虽然我个人没有看到使用concurrent.futures.ProcessPoolExecutor()你的太多好处,但可以尝试一下。事实上,它比我在 Windows 上的实验中的线程慢。同样在 Windows 上,您对 python 有很多限制Process

  • 考虑是否可以通过使用构建在 asyncio 上的异步 webdriver 客户端满足的用这听起来确实很有希望,尽管有很多限制。

  • 考虑Requests-Html是否可以解决您的 javascript 加载问题。因为它声称完全支持 JavaScript!在这种情况下,您可以将它与BeautifulSoup标准数据抓取方法一起使用。


推荐阅读