在AWS EC2服务中使用Python Selenium和Firefox驱动下载PDF文件

0 投票
1 回答
40 浏览
提问于 2025-04-14 18:10

我正在做一个Python项目,其中一部分功能是使用Selenium和Firefox自动从网站下载PDF文件,然后将这些文件上传到一个特定的存储桶。这个过程是Selenium先把PDF临时保存到/tmp目录,然后再进行后续处理。我的开发环境是在一个Docker容器里,这个设置运行得非常顺利——我可以顺利下载PDF,并在/tmp目录里找到它们,使用的Selenium版本是3.141.0、3.8.0或4.18.1,浏览器是Firefox及其对应的驱动。

但是,当我把这个应用部署到AWS的EC2实例上时,情况就变了。应用在与网站的互动上运行正常,Selenium和应用本身也没有报错。但是,应该下载的PDF文件在/tmp目录里却找不到。

我原本期待PDF文件能像在Docker容器里那样下载到EC2实例的/tmp目录,这样我的脚本就可以把它上传到指定的存储桶。然而,文件根本没有出现在目录里,尽管应用显示下载按钮点击成功,也没有记录与文件写入或Selenium与Firefox互动相关的错误。

这是我目前的逻辑:

login_url = 'https://my-web.com/login/'
            dashboard_url = f'https://my-web.com/pdf-button-download-view'
            unique_dir = os.path.join("/tmp/pdfs", str(uuid.uuid4()))
            os.makedirs(unique_dir, exist_ok=True)

            os.chmod(unique_dir, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)

            options = Options()
            options.headless = True
            log_path = "/tmp/geckodriver.log"

            # Firefox Profile for specifying download behavior
            profile = webdriver.FirefoxProfile()
            profile.set_preference("browser.download.folderList", 2)
            profile.set_preference("browser.download.manager.showWhenStarting", False)
            profile.set_preference("browser.download.dir", unique_dir)
            profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")

            driver = webdriver.Firefox(options=options, firefox_profile=profile, service_log_path=log_path)

            driver.get(login_url)
            time.sleep(10)

            # Login
            driver.find_element(By.ID, "username").send_keys("admin")
            driver.find_element(By.ID, "password").send_keys("admin")
            driver.find_element(By.CSS_SELECTOR, "form").submit()
            time.sleep(10)

            # Navigate to the Dashboard
            driver.get(dashboard_url)
            time.sleep(10)

            logging.info(f"Dashboard URL loaded: {driver.current_url}")

            dropdown_trigger = driver.find_element(By.XPATH, "//button[@aria-label='Menu actions trigger']")
            dropdown_trigger.click()

            logging.info("Dropdown trigger clicked.")

            action = ActionChains(driver)

            logging.info("Attempting to find the dropdown item for download.")

            dropdown_item = driver.find_element(By.XPATH, "//div[@title='Download']")
            action.move_to_element(dropdown_item).perform()

            logging.info("The dropdown item was founded.")

            logging.info("Attempting to click the 'Export to PDF' button.")

            export_to_pdf_button = WebDriverWait(driver, 3).until(
                EC.element_to_be_clickable((By.XPATH, "//div[@role='button'][contains(text(), 'Export to PDF')]"))
            )

            export_to_pdf_button.click()

            logging.info("Export to PDF button clicked, waiting for file to download.")

            start_time = time.time()
            while True:
                pdf_files = [f for f in os.listdir(unique_dir) if f.endswith(".pdf")]
                if pdf_files:
                    break
                elif time.time() - start_time > 60:  # Wait up to 60 seconds for the file
                    raise Exception("File download timed out.")
                time.sleep(1)

            driver.quit()

            logging.info("Driver quit.")

在EC2服务中,PDF文件没有在unique_dir目录生成。机器上有21GB的可用空间。/tmp/pdfs目录成功生成,但始终是空的。

1 个回答

0

在下面添加这个设置,让它使用指定的下载目录:

profile.set_preference("browser.download.useDownloadDir", True)

撰写回答