赞
踩
版本:
- Chrome 124
- Python 3.12
- Selenium 4.19.0
版本与我有差异不要紧,只要别差异太大比如 Chrome 用 57 之前的版本了,就可以看本文。
如果你从前完全没使用过、没安装过Selenium,可以参考这篇博客《【记录】Python3|Selenium4 极速上手入门(Windows)》快速安装Edge版本的webdriver,再继续看下文。
这个问题我本来以为就是抓个包解决的,不过后来才发现因为现在浏览器的设计原因,返回Content-Type:application/pdf
;的时候就会自动在浏览器中预览文件,报文的响应会解析成以下东西:
<!doctype html><html>
<body style='height: 100%; width: 100%; overflow: hidden; margin:0px; background-color: rgb(51, 51, 51);'>
<embed name='2F7A72AC9A127791D290DA205760BBE4' style='position:absolute; left: 0; top: 0;'width='100%' height='100%' src='about:blank' type='application/pdf' internalid='2F7A72AC9A127791D290DA205760BBE4'>
</body></html>
这会导致网页在遇到这种响应的时候会预览PDF,而不是下载PDF。
网上方法一大堆我看五花八门的其实解决起来就那么回事,有人问我我就汇总一下ok废话不多说。
如果关掉浏览器的PDF阅读模式就不会预览而是会直接下载,例如谷歌浏览器中的设置项,步骤如下:
如果设置了下载路径为“另存为”的话,仍然需要手动选择PDF的下载路径。如下所示。
但是,这个问题是可以解决的。
如果根据下面的步骤设置了默认下载路径,则会自动下载如下。
如下所示:
user-data-dir
。不过我按照这个思路去解决发现并不起效:options.add_argument("user-data-dir=C:/Users/User/AppData/Local/Google/Chrome/User Data/Default")
chrome://version
查看(路径查找参考:chromedriver官方文档),如下所示。根据这篇博客,说其实谷歌浏览器是靠一个自带的叫PDF-Viewer的插件来打开网页的pdf,selenium有个语句能禁用这个插件。
相关代码如下:
from time import sleep
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(chrome_options=chrome_options)
chrome_options.add_experimental_option('prefs', {
"download.prompt_for_download": False,
'plugins.always_open_pdf_externally': True
})
driver = webdriver.Chrome(chrome_options=chrome_options)
sleep(1000) # 有时候会有人还没等到它下载就退出了,然后觉得这个方法没有作用,所以特地加一行sleep
注意一点,网上还流传着另一种代码:'plugins.plugins_disabled': ["Chrome PDF Viewer"]
,这个早就已经没用了(自从 Chrome 57)。具体的讨论帖子可以看 Disabling PDF Viewer plugin in chromedriver-StackOverflow。
这个做法的缺点如此之多,以至于第三个方式存在极大的生存土壤。
参考:没参考,这就是我自己平常的写法。
都已经有url了就别那么麻烦了,赶紧直接请求得到结果吧。。
可用的示例代码如下:
import requests # URL of the PDF file pdf_url = 'https://xx.pdf' # Send an HTTP GET request to the URL response = requests.get(pdf_url) # Check if the request was successful (status code 200) if response.status_code == 200: # Open a file in binary write mode with open('downloaded_pdf.pdf', 'wb') as f: # Write the PDF content to the file f.write(response.content) print("PDF downloaded successfully.") else: print("Failed to download PDF. Status code:", response.status_code)
from selenium import webdriver import requests # Set up Selenium WebDriver (make sure to have appropriate driver installed) driver = webdriver.Chrome() # Navigate to the website containing the PDF driver.get("https://example.com/your_pdf_link") # Extract the URL of the PDF file pdf_url = driver.current_url # Retrieve the headers from the WebDriver headers = driver.execute_script("return Object.fromEntries(new Map(Object.entries(arguments[0].headers)))", driver.execute_script("return window.navigator")) # Use requests to download the PDF file with headers response = requests.get(pdf_url, headers=headers) # Check if the request was successful if response.status_code == 200: # Save the PDF file with open("output.pdf", "wb") as f: f.write(response.content) print("PDF file downloaded successfully.") else: print("Failed to download the PDF file.") # Close the Selenium WebDriver driver.quit()
说实在的啊,这个script是不能用的,但是思路就是继承Selenium的参数。
根据我的精心查找,我发现写出一个继承 Selenium 参数的 script 的方式已经值得再写一篇博客了,这篇博客的链接是【代码】Python3|Requests 库怎么继承 Selenium 的 Headers (2024,Chrome)。
一般情况(指对 headers 要求不高时)加上这一个参数就行,反爬虫厉害的网站得再加点别的:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'}
通过 requests 已经获取了 response 之后,可以通过如下步骤直接使用 pdf 的内容,这样做和下载之后再open是一样的:
import io import PyPDF2 # 使用 io 模块创建一个 BytesIO 对象,以便将 response.content 传递给 PyPDF2 pdf_file = io.BytesIO(response.content) # 创建一个 PdfFileReader 对象来读取 PDF 文件内容 pdf_reader = PyPDF2.PdfFileReader(pdf_file) # 获取 PDF 文件中的页数 num_pages = pdf_reader.numPages print("Number of pages:", num_pages) # 逐页提取文本并打印 for page_num in range(num_pages): # 获取页面对象 page = pdf_reader.getPage(page_num) # 提取文本 text = page.extractText() # 打印文本 print("Page", page_num + 1, ":", text.strip()) # 关闭 BytesIO 对象 pdf_file.close()
注意一定要用BytesIO,不需要再with open什么东西了。
好的就分享到这里。
本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/137883196。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。