如何下载.cfm页面显示的已生成PDF,避免获取空模板
问题
我尝试从某cfm地址下载PDF文件,编写了一段Selenium代码:先在指定页面填写机场代码,点击按钮后新标签页会打开生成的PDF文件。但直接访问该cfm地址下载得到的是空PDF模板,请问如何下载当前页面显示的PDF,而非直接访问上述cfm URL?
以下是我的代码:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver import ActionChains from selenium.webdriver.common.print_page_options import PrintOptions from urllib import request from bs4 import BeautifulSoup import re import os import urllib import time import requests from urllib.parse import urljoin aerodromos = "SBNT,SBJP,SBFZ,SBRF" #TEST driver = webdriver.Chrome('C:\Windows\chromedriver.exe') options = webdriver.ChromeOptions() driver = webdriver.Chrome(options=options) driver.get("https://aisweb.decea.mil.br/?i=notam") driver.maximize_window() caixaTexto = driver.find_element(By.XPATH,'//*[@id="icaocode"]') caixaTexto.send_keys(aerodromos) botao = driver.find_element(By.XPATH, '//*[@id="a"]/form/div/div[3]/div/input[2]') botao.click() botao = driver.find_element(By.XPATH, '//*[@id="select-all"]') botao.click() botao = driver.find_element(By.XPATH, '/html/body/div/div/div/div/div[2]/div/div/form/input[3]') botao.click() response = urllib.request.urlretrieve('https://aisweb.decea.mil.br/inc/notam/gerar-boletim/reports/report-notam.cfm', filename='relatorio1.pdf')
解决方案
直接用urllib请求cfm地址会得到空模板,核心原因是该请求未携带之前操作生成的会话Cookie,网站需要验证会话才能返回正确的PDF内容。可以通过以下步骤解决:
- 点击生成PDF按钮后,切换到新打开的标签页,等待页面加载完成
- 从Selenium的driver中提取当前会话的Cookie,传递给
requests库 - 使用
requests发送GET请求获取PDF内容并保存
修改后的代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By import time import requests aerodromos = "SBNT,SBJP,SBFZ,SBRF" #TEST # 初始化Chrome浏览器,修复原代码重复初始化driver的问题 options = webdriver.ChromeOptions() driver = webdriver.Chrome(options=options) driver.get("https://aisweb.decea.mil.br/?i=notam") driver.maximize_window() # 填写机场代码 caixaTexto = driver.find_element(By.XPATH,'//*[@id="icaocode"]') caixaTexto.send_keys(aerodromos) # 点击查询按钮 botao = driver.find_element(By.XPATH, '//*[@id="a"]/form/div/div[3]/div/input[2]') botao.click() time.sleep(2) # 等待查询结果加载完成 # 全选NOTAM条目 botao = driver.find_element(By.XPATH, '//*[@id="select-all"]') botao.click() # 点击生成PDF按钮,触发新标签页打开 botao = driver.find_element(By.XPATH, '/html/body/div/div/div/div/div[2]/div/div/form/input[3]') botao.click() time.sleep(3) # 等待新标签页及PDF加载完成 # 切换到新打开的PDF标签页 driver.switch_to.window(driver.window_handles[-1]) # 提取会话Cookie,转换成requests可识别的格式 cookies = {cookie['name']: cookie['value'] for cookie in driver.get_cookies()} pdf_url = driver.current_url # 获取当前PDF页面的有效URL # 携带Cookie请求PDF并保存到本地 response = requests.get(pdf_url, cookies=cookies) with open('relatorio1.pdf', 'wb') as f: f.write(response.content) # 关闭浏览器释放资源 driver.quit()
关键说明
- 修复了原代码中重复初始化
driver的错误,确保浏览器配置正常生效 - 添加了适当的等待时间,避免因页面未加载完成导致的元素定位或URL获取失败
- 通过
driver.get_cookies()获取会话验证信息,让requests请求能通过网站的会话校验,返回正确的PDF内容 - 切换到新标签页后获取当前URL,确保请求的是经过会话验证的有效PDF地址
内容的提问来源于stack exchange,提问作者Alexandre Viegas
相关产品推荐
相关产品推荐

