如何在Selenium中处理在线PDF并提取文本?
解决PDF爬取连接错误及Selenium处理方案
一、直接获取PDF二进制内容到变量(无需本地保存)
利用Selenium的Chrome DevTools Protocol(CDP)拦截PDF的网络请求,直接获取响应的二进制数据,无需保存到本地即可传入文本提取库处理,步骤如下:
- 初始化ChromeDriver并启用网络监控
- 导航到PDF URL,等待请求完成
- 提取PDF的二进制响应内容
- 用tika或pypdf直接处理内存中的二进制数据
代码示例:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait import base64 from tika import parser # 配置Chrome选项 chrome_options = Options() chrome_options.add_argument("--headless=new") # 无头模式,可选 chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=chrome_options) # 启用网络监控 driver.execute_cdp_cmd("Network.enable", {}) pdf_url = 'http://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes/jose-sarney/discursos/1985/02.pdf' driver.get(pdf_url) # 等待PDF请求完成并获取响应 def wait_for_pdf_response(driver, target_url): responses = [] def handle_response(response): if response['response']['url'] == target_url and response['response']['status'] == 200: responses.append(response) driver.execute_cdp_cmd("Network.responseReceived", {}, handle_response) # 等待响应获取完成 WebDriverWait(driver, 10).until(lambda d: len(responses) > 0) # 获取二进制内容 body = driver.execute_cdp_cmd("Network.getResponseBody", {"requestId": responses[0]['requestId']}) return body['body'] if not body['base64Encoded'] else base64.b64decode(body['body']) # 获取PDF二进制数据 pdf_content = wait_for_pdf_response(driver, pdf_url) driver.quit() # 用tika处理内存中的PDF raw = parser.from_buffer(pdf_content) print(raw['content'])
二、配置Selenium自动下载PDF到本地
如果需要留存原始PDF文件,可配置Chrome自动下载PDF而非在浏览器中预览,之后读取本地文件处理:
代码示例:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait import os from tika import parser # 配置下载路径和PDF自动下载设置 download_dir = '/tmp' chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") # 设置Chrome偏好,自动下载PDF prefs = { "download.default_directory": download_dir, "download.prompt_for_download": False, "download.directory_upgrade": True, "plugins.always_open_pdf_externally": True # 禁止浏览器预览PDF,直接下载 } chrome_options.add_experimental_option("prefs", prefs) driver = webdriver.Chrome(options=chrome_options) pdf_url = 'http://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes/jose-sarney/discursos/1985/02.pdf' driver.get(pdf_url) # 等待文件下载完成(根据文件名判断) def wait_for_download(download_dir, filename): file_path = os.path.join(download_dir, filename) WebDriverWait(driver, 20).until(lambda d: os.path.exists(file_path)) return file_path # 这里假设PDF文件名是'02.pdf',实际可根据URL或网络请求调整 pdf_path = wait_for_download(download_dir, '02.pdf') driver.quit() # 提取文本 raw = parser.from_file(pdf_path) print(raw['content'])
补充说明
你遇到的ConnectionResetError大概率是网站反爬机制导致——requests模拟的请求缺少浏览器环境的会话信息、Cookie或完整请求头,Selenium模拟真实浏览器行为,能绕过这类限制。
两种方案各有优势:
- 直接获取二进制内容适合不需要保存PDF的场景,节省磁盘IO;
- 自动下载适合需要留存原始PDF文件的需求。
内容的提问来源于stack exchange,提问作者Marcelo Soares
相关产品推荐
相关产品推荐

