首页 > 解决方案 > Selenium Python 浏览上下文已被丢弃。使用 Firefox 和 GeckoDriver

问题描述

我正在使用带有 Selenium 的 Firefox GeckoDriver 为网站上的客户端下载一些文件。

该设置在带有 Docker 的 Digital Ocean 上运行。

这是流程,所以每当用户调用 API 时,都会创建一个新的浏览器实例并使用用户的登录 ID 和密码登录到网站,然后下载一堆文件创建一个 zip 并发送回。

当只有一个请求意味着服务器上只有一个浏览器实例时,一切似乎都可以正常工作,但是当有多个请求意味着服务器上的多个浏览器实例时,其中一些会中断并给出错误消息“浏览上下文已被丢弃”。

这发生在爬取部分期间或在实例创建之后。

此错误没有特定的模式,它随机发生并破坏浏览器实例。我可能已经浏览了关于这个主题的所有问题和 GitHub 问题,但其中一些是太旧的解决方法,在当前版本中不起作用,而有些根本不起作用。

这是我在 Jenkins 上运行的浏览器版本和配置。

`
{'browserName': 'firefox', 
'marionette': True, 
'acceptInsecureCerts': True, 
'moz:firefoxOptions': {
    'prefs': {
               'browser.download.folderList': 2, 
               'browser.download.dir': '/home/usr/usr/project/static/785fg7', 
               'browser.download.useDownloadDir': True, 
               'pdfjs.disabled': True, 
               'browser.helperApps.neverAsk.saveToDisk':
                                  'application/vnd.openxmlformats- 
                                   officedocument.spreadsheetml.sheet,
                                   application/pdf,
                                   application/csv,application/excel,
                                   application/vnd.msexcel,
                                   application/vnd.ms-excel,text/anytext,
                                   text/comma-separated-values,
                                   text/csv,application/vnd.ms-excel,
                                   application/octet-stream,
                                   image/tiff'}, 
           'args': ['-headless', 
                    '--no-sandbox', 
                    '--disable-setuid-sandbox', 
                    '--disable-dev-shm-usage', 
                    '--window-size=1920,1080', 
                    '--start-maximized']}} `

请注意,无论我创建多少个浏览器实例,在本地一切正常。问题仅在于它部署在服务器上时。在我的本地系统中,任何数量的请求都可以在无头模式下正常工作。

这是启动浏览器的 Python 代码。

def get_firefox_driver_for_linux_server(apply_proxy, uuid_user, download_options=False):

    firefox_options = Options()

    firefox_options.set_headless()

    if download_options:
        if not os.path.exists(constants.DOWNLOADS_PATH):
            os.mkdir(constants.DOWNLOADS_PATH)

        download_path = os.path.join(constants.DOWNLOADS_PATH, uuid_user)
        firefox_options.set_preference("browser.download.folderList", 2)
        firefox_options.set_preference("browser.download.dir", download_path)
        firefox_options.set_preference("browser.download.useDownloadDir", True)
        firefox_options.set_preference("pdfjs.disabled", True)
            firefox_options.set_preference("browser.helperApps.neverAsk.saveToDisk",
                                       "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,"
                                       "application/pdf,"
                                       "application/csv,"
                                       "application/excel,"
                                       "application/vnd.msexcel,"
                                       "application/vnd.ms-excel,"
                                       "text/anytext,"
                                       "text/comma-separated-values,"
                                       "text/csv,"
                                       "application/vnd.ms-excel,"
                                       "application/octet-stream,"
                                       "image/tiff")

    firefox_options.add_argument("--no-sandbox")
    firefox_options.add_argument("--disable-setuid-sandbox")
    firefox_options.add_argument('--disable-dev-shm-usage')
    firefox_options.add_argument("--window-size=1920,1080")
    firefox_options.add_argument("--start-maximized")

    if not os.path.exists(constants.LOG_PATH):
        os.mkdir(constants.LOG_PATH)


    import random as r
    global random_id
    random_id = str(r.randint(1, 99999))
    logging.warning("random id...{}".format(random_id))
    with open(os.path.join(constants.LOG_PATH, random_id + '.log'), 'w+') as lf:
        pass

    gecko_driver_path = "/usr/local/bin/geckodriver"
    if apply_proxy:
        proxy = "proxy:24000"
        firefox_capabilities = webdriver.DesiredCapabilities.FIREFOX
        firefox_capabilities['marionette'] = True
        firefox_capabilities['proxy'] = {
            "proxyType": "MANUAL",
            "httpProxy": proxy,
            "ftpProxy": proxy,
            "sslProxy": proxy
        }

        driver = webdriver.Firefox(executable_path=gecko_driver_path, firefox_options=firefox_options,
                                   capabilities=firefox_capabilities,
                                   log_path=os.path.join(constants.LOG_PATH, random_id + '.log'))
        check_gecko_version(driver, firefox_options)
        return driver
    else:
        logging.info("No proxy applied")
        driver = webdriver.Firefox(executable_path=gecko_driver_path, firefox_options=firefox_options)
        check_gecko_version(driver, firefox_options)
        return driver

标签: python-3.xseleniumgeckodriver

解决方案


推荐阅读