You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Selenium WebDriver在Firefox下载PDF后进程卡住的问题排查

问题:Selenium访问PMC PDF链接后程序卡住无法退出

我尝试用Python的Selenium WebDriver从PubMed Central下载PDF,代码能成功下载PDF,但程序卡在browser.get(href)这一行,无法自动退出,请问可能的原因是什么?

原代码

import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
ncbi_url = "https://www.ncbi.nlm.nih.gov/"

download_dir = "pdf_downloaded"

if not os.path.exists(download_dir):
    os.mkdir(download_dir)
    
options = Options()
options.set_preference('permissions.default.stylesheet', 2)
options.set_preference('permissions.default.image', 2)
options.set_preference('browser.download.folderList', 2)
options.set_preference('browser.download.dir', os.path.abspath(download_dir))
options.set_preference('browser.download.manager.showWhenStarting', False)
options.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/pdf')
options.set_preference('pdfjs.disabled', True)

browser = webdriver.Firefox(options=options)

###############################################################################
def download_pmc_pdf(pmcid_key):
    pmc_url = ncbi_url + "pmc/articles/" + pmcid_key + "/"
    browser.get(pmc_url)
    try:
        wait = WebDriverWait(browser, 10)
        pdf_links = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.pmc-sidebar__formats li a')))
        
        # Iterate over all links and navigate to the link containing '.pdf' in the href attribute
        for link in pdf_links:
            href = link.get_attribute('href')
            if '.pdf' in href:
                browser.get(href)
                break  # exit the loop as we have found the PDF link
        print("line beofre browser.quit()")
        browser.quit()  # quit the browser outside the loop
    except Exception as e:
        print(e)


    
###############################################################################
pmcid = "2788555"            
download_pmc_pdf(pmcid)
browser.quit()

可能的原因

  1. 页面加载等待逻辑冲突
    调用browser.get(href)访问PDF链接时,Selenium默认会等待页面完全加载完成才执行后续代码。但你设置了pdfjs.disabled=True,浏览器不会在页面内渲染PDF,而是直接触发下载操作——这个操作没有“完成页面加载”的状态,导致Selenium一直卡在等待页面加载的环节,无法继续执行退出代码。

  2. 重复调用browser.quit()
    代码在download_pmc_pdf函数内部已经调用了browser.quit(),函数执行完毕后外部又调用了一次。这虽不是卡住的直接原因,但会导致程序正常退出时报错,属于冗余代码。


解决办法

方法1:设置页面加载超时

给浏览器设置页面加载超时时间,超时后程序会抛出异常但可继续执行退出逻辑:

# 初始化浏览器后添加这行代码
browser.set_page_load_timeout(10)  # 10秒超时,可根据情况调整

方法2:改用JavaScript触发下载(推荐)

避免使用browser.get(),用JS打开新窗口触发下载,跳过Selenium的页面加载等待逻辑:

# 替换原代码中的browser.get(href)部分
if '.pdf' in href:
    # 用JS打开新窗口触发下载
    browser.execute_script("window.open(arguments[0]);", href)
    # 切换到新窗口并关闭
    handles = browser.window_handles
    browser.switch_to.window(handles[-1])
    browser.close()
    browser.switch_to.window(handles[0])
    break

方法3:清理冗余的退出代码

只保留一处browser.quit(),比如放在函数的finally块中,确保无论是否报错都能退出浏览器:

def download_pmc_pdf(pmcid_key):
    pmc_url = ncbi_url + "pmc/articles/" + pmcid_key + "/"
    try:
        browser.get(pmc_url)
        # ... 中间逻辑不变 ...
    except Exception as e:
        print(f"出错:{e}")
    finally:
        browser.quit()  # 统一在这里退出

修改后的完整代码

import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

ncbi_url = "https://www.ncbi.nlm.nih.gov/"
download_dir = "pdf_downloaded"

if not os.path.exists(download_dir):
    os.mkdir(download_dir)
    
options = Options()
options.set_preference('permissions.default.stylesheet', 2)
options.set_preference('permissions.default.image', 2)
options.set_preference('browser.download.folderList', 2)
options.set_preference('browser.download.dir', os.path.abspath(download_dir))
options.set_preference('browser.download.manager.showWhenStarting', False)
options.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/pdf')
options.set_preference('pdfjs.disabled', True)

browser = webdriver.Firefox(options=options)
browser.set_page_load_timeout(10)  # 添加页面加载超时

def download_pmc_pdf(pmcid_key):
    pmc_url = ncbi_url + "pmc/articles/" + pmcid_key + "/"
    try:
        browser.get(pmc_url)
        wait = WebDriverWait(browser, 10)
        pdf_links = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.pmc-sidebar__formats li a')))
        
        for link in pdf_links:
            href = link.get_attribute('href')
            if '.pdf' in href:
                # 用JS触发下载,避免等待页面加载
                browser.execute_script("window.open(arguments[0]);", href)
                handles = browser.window_handles
                browser.switch_to.window(handles[-1])
                browser.close()
                browser.switch_to.window(handles[0])
                break
        print("准备退出浏览器")
    except Exception as e:
        print(f"错误信息:{e}")
    finally:
        browser.quit()

pmcid = "2788555"            
download_pmc_pdf(pmcid)

内容的提问来源于stack exchange,提问作者Wasim Aftab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:32:48