【记录】Python3|Selenium 下载 PDF 不预览不弹窗(2024年)
版本:
- 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打开方式默认为下载
1.1 具体做法
如果关掉浏览器的PDF阅读模式就不会预览而是会直接下载,例如谷歌浏览器中的设置项,步骤如下:
- 打开设置,搜索pdf,前往网站设置。
- 展开更多内容设置,并点击PDF文档。
- 修改默认行为为下载PDF文件。
如果设置了下载路径为“另存为”的话,仍然需要手动选择PDF的下载路径。如下所示。
但是,这个问题是可以解决的。
如果根据下面的步骤设置了默认下载路径,则会自动下载如下。
如下所示:
1.2 做法评估
- 优点:能让我们的读者朋友们弄清楚不预览不弹窗的可视化逻辑。
- 缺点:
- 这种做法放到selenium里面就没用了,因为这个设置不会继承到 chromedriver 中去。
- 不会继承的问题是有可能解决的,即设置
user-data-dir
。不过我按照这个思路去解决发现并不起效:options.add_argument("user-data-dir=C:/Users/User/AppData/Local/Google/Chrome/User Data/Default")
具体路径可以通过
chrome://version
查看(路径查找参考:chromedriver官方文档),如下所示。
方式二:Selenium设置,禁用PDF Viewer插件
2.1 具体做法
根据这篇博客,说其实谷歌浏览器是靠一个自带的叫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。
2.2 做法评估
- 优点:和Selenium结合得非常好;
- 缺点:有人说这个方法不起效,因为他们没有sleep,在还没开始下载的时候这个程序就退出了。这个并不是编程人员的毛病,而是这个方法本身确实有缺点。① 它具体下载到哪里了不太好获取(因为是Default),还得另外写代码;② 你没办法确定这个 PDF 是否下载好了。(和第一个缺点一样,都是因为这个下载位置都不太好获取,下载状态更难获取)③ 需要等待一定的时间去下载它,但又难以知道要等多久。(这就是 Selenium 的缺点了,它在模拟方面登峰造极,也在线程控制方面和浏览器的线程控制一样随意而混乱……)
这个做法的缺点如此之多,以至于第三个方式存在极大的生存土壤。
方式三:requests库,直接请求url
3.1 具体做法
参考:没参考,这就是我自己平常的写法。
都已经有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)
3.2 方法评估
- 优点:简单直接高效。
- 缺点:requests库有个坏处,就是总是要自己定义header的参数。而这一点Selenium弥补得很好。为了继承Selenium的自动填充的参数,避免反爬虫的问题,GPT添加headers如下所示:
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'}
彩蛋:不下载PDF直接读取内容
通过 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。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
【记录】Python3|Selenium 下载 PDF 不预览不弹窗(2024年)的更多相关文章
- 实战动态PDF在线预览及带签名的PDF文件转换
开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是这个想法,说干就干,实践过程总是艰难的,折腾了3 ...
- 动态PDF在线预览
实战动态PDF在线预览及带签名的PDF文件转换 开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是 ...
- Office在线预览及PDF在线预览的实现方式史上最全大集合
Office在线预览及PDF在线预览的实现方式大集合 一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office2007以上版本的一个PDF插件SaveAsPD ...
- Aspose office (Excel,Word,PPT),PDF 在线预览
前文: 做个备份,拿的是试用版的 Aspose,功能见标题 代码: /// <summary> /// Aspose office (Excel,Word,PPT),PDF 在线预览 // ...
- java原装代码完成pdf在线预览和pdf打印及下载
这是我在工作中,遇到这样需求,完成需求后,总结的成果,就当做是工作笔记,以免日后忘记,当然,能帮助到别人是最好的啦! 下面进入正题: 前提准备: 1. 项目中至少需要引入的jar包,注意版本: a) ...
- PDF文件预览和下载
背景:项目中实现pdf文件的预览以及下载 环境:jdk1.8.SpringBoot2.0.Maven PDF.js下载地址将下载的源码拷入项目中 修改viewer.js: 将default ...
- 记一次关于pdf 下载需求变更到 pdf 在线预览
背景: 之前的需求是根据接口中提供的Blob数据实现PDF下载,已实现代码如下: 1 const url = window.URL.createObjectURL(newBlob([response. ...
- [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你!
引言 之前项目需要,查找了office文档在线预览的解决方案,顺便记录一下,方便以后查询. 方案一 直接在浏览器中打开Office文档在页面上的链接.会弹出如下窗口: 优点:主流浏览器都支持. 缺点: ...
- [Asp.net]常见word,excel,ppt,pdf在线预览方案(转)
引言 之前项目需要,查找了office文档在线预览的解决方案,顺便记录一下,方便以后查询. 方案一 直接在浏览器中打开Office文档在页面上的链接.会弹出如下窗口: 优点:主流浏览器都支持. 缺点: ...
- 前端使用pdf.js预览pdf文件
现在的浏览器基本都支持直接把pdf文件拖到浏览器就可以打开了,不用安装额外的插件.但是不同的浏览器显示的页面不一样.如果我们想在网页上统一预览pdf怎样实现呢? Mozilla开源了一个插件pdf.j ...
随机推荐
- Leetcode 765 情侣牵手 / Hetao-013 翅膀打结 题解 [ 黄 ] [ 并查集 ] [ BFS ] [ 贪心 ]
经典的连通块题,幸好我之前在 leetcode 看过原. 转化 首先观察到一对cp无论是男在前,还是女在前,都视为配对成功,对答案无影响. 因此,我们可以把一对情侣赋同一个编号,直接加一除以二即可. ...
- 烟草行业如何用低代码+ BI 实现数字化转型?
在数字经济的大潮中,烟草行业正迎来重大的发展契机.国家层面的政策引导和战略规划为行业的数字化转型提供了明确的方向.<数字中国>的愿景逐步变为现实,国家信息化发展战略的深入推进,为烟草行业的 ...
- 小程序开发实战案例五 | 小程序如何嵌入H5页面
在接入小程序过程中会遇到需要将 H5 页面集成到小程序中情况,今天我们就来聊一聊怎么把 H5 页面塞到小程序中. 本篇文章将会从下面这几个方面来介绍: 小程序承载页面的前期准备 小程序如何承载 H5 ...
- ABB工业机器人控制柜IRC5维修具体细节
对于ABB机器人维修工作,需要具备专业的知识和技能,同时遵循维修步骤和注意事项.通过加强预防措施和建议的实施,可以有效降低ABB工业机器人控制柜IRC5的故障率,提高ABB工业机器人的整体运行效率. ...
- ffmpeg-5.0-essentials_build 下载
ffmpeg-5.0-essentials_build下载放到蓝奏里了 https://wwz.lanzoub.com/if9xq02pttkb密码:ee8i
- mysql数据库表如何设计
单表数据量 所有表都需要添加注释,数据量建议控制在3000万以内 不保存大字段数据 不在数据库中存储图片.文件等大数据 表使用规范 拆分大字段和访问频率低的字段,分离冷热数据 单表字段数控制在 20 ...
- typecho引入五秒盾,缓解服务器压力
功能是:对访客的访问频率会先一步判断,根据用户自定义的范围,将频率过高的访客跳转向127.0.0.1,而没有达到频率的访客则会进行cookies验证,这样更大程序的对恶意流量攻击进行拦截,并且有效缓解 ...
- Datagrip 破解
题记部分 方法一 [参考链接]:DataGrip 2023.2最新安装使用教程(附激活码,亲测好用)_糖果果爱分享的技术博客_51CTO博客 [软件版本]:datagrip-2023.3.4.win ...
- Ansible - [07] 定义变量的几种方式
题记部分 Ansible 支持十几种定义变量的方式 Inventory 变量 Host Facts 变量 Register 变量 Playbook 变量 Playbook 提示变量 变量文件 命令行变 ...
- Processing模拟控制多台舵机-以距离为参数 程序参考
又是一次课程学习的结束,辅导学生的过程也很受益,温故而知新.该组同学需要Arduino控制多达6个舵机,而且基于距离这一参数,在不同距离值之间会有不同的触发事件,也就是6个舵机转的角度都有所不同,而且 ...