写点什么

半小时手工解决的活,让我意外学会了 python 的 pdfkit 库

发布于: 2020 年 05 月 19 日
半小时手工解决的活,让我意外学会了 python 的 pdfkit 库



事情的起因是,我遇到了这样的问题:



系统里有很多个 pdf 需要打印。一共有 48 个页面,且 URL 都很有规律。

在这个 URL 下,需要点击 “打印” 按钮,才可以弹出打印画面。

也就是说,我需要保存 48 个 PDF。手动的话就是不停的点点点,我觉得无聊透了。

致力于寻求编程自动化解决问题的我开始了自动化求解的尝试。



环境



操作系统 Windows

浏览器 Chrome

python Anaconda 下面的 Jupyter






首先爬取网页,request 一下。为避免泄露,对代码进行了部分处理。

import requests
import pandas as pd
cookies = {
'UM_distinctid': '-000--de5ff',
'ASPSESSIONIDQARDAQSA': 'NPNN---CCH',
'ASP.NET_SessionId': 'q4-en-o-',
'__RequestVerificationToken_L29mZmljZQ2': '--------',
}
headers = {
'Proxy-Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'DNT': '1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Language': 'zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7,en-US;q=0.6',
}
url = 'http://jdiogsig?xh=52646876546'
response = requests.get(url, headers=headers, cookies=cookies, verify=False)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('http://***.****.edu.cn/', headers=headers, cookies=cookies, verify=False)



先说明一下为什么不直接用 with open 的方法保存为 html 文件,后缀不管是 html 还是 pdf,结果都大同小异:



with open('D:\\t\\1.pdf','wb') as f:
f.write(r.content)

因为它的效果把表格转成了文本。

根本没有表格的样子了好不。

(这里原本想上传图片,但是截图上传后无法发布文章,提示图片错误。另外,代码块的字体有点小,也无法调整呢)



1 库的安装



在 Anaconda 的环境下,pip install pdfkit

第一次尝试失败,但是第二次重新试了一下又可以了。

运行报错



根据提示还需要安装 wkhtmltopdf.exe

下载地址:https://wkhtmltopdf.org/downloads.html



且为了不报错,需要把 wkhtmltopdf.exe 的文件目录放进去。

所以有了 2 (1)代码中的:path_wkconfigconfiguration = config



2 思路:

pdfkit.from_url 直接从 URL 生成 PDF。

path_wk = r'F:\anaconda\Lib\site-packages\wkhtmltox\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf = path_wk)
options = {'page-size': 'A4','margin-top': '0mm','margin-right': '0mm','margin-bottom': '0mm',
'margin-left': '0mm',
'cookie':[('UM_distinctid','-000--de5ff'),
('ASPSESSIONIDQARDAQSA','NPNNNNODOAOHJDAIAGAKBCCH'),
('ASP.NET_SessionId','q40nquowd5zpxfbdkiw'),
('__RequestVerificationToken_L29mZmljZQ2','VOWLriqJwjmomrfo')]}
pdfkit.from_url(url,'1.pdf', configuration = config, options = options) #注意这里的 URL 和之前的保持一致了。



3 细节



pdfkit 中 cookie 的引用:

options = {'cookie': [('cookie-name1', 'cookie-value1'), ('cookie-name2', 'cookie-value2')]}
pdfkit.from_url('http://google.com', 'out.pdf', options=options)



最初爬网页时写 cookie, 我都是老老实实的找到,然后复制粘贴。

这次因为 pdfkit 库传递 cookie 的方式,必须要找到 cookie 中:

('cookie-name1', 'cookie-value1')



于是偷懒利器:https://curl.trillworks.com/ 上场。

找到真正的 URL 以后,右键点击复制 cURL,复制到网页左边输入框,右边就会自动解析出 python 所需要的格式。

如第一行:'UM_distinctid' 就相当于 'cookie-name1''-000--de5ff' 就相当于 'cookie-value1'



于是代入的话就有了:

with open('1.html','r', encoding = 'utf-8') as f:
path_wk = r'F:\anaconda\Lib\site-packages\wkhtmltox\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf = path_wk)
options = {'page-size': 'A4','margin-top': '0mm','margin-right': '0mm','margin-bottom': '0mm',
'margin-left': '0mm',
'cookie':[('UM_distinctid','-000--de5ff'),
('ASPSESSIONIDQARDAQSA','NPNNNNODOAOHJDAIAGAKBCCH'),
('ASP.NET_SessionId','q40nquenqlxowd5zpxfbdkiw'),
('__RequestVerificationToken_L29mZmljZQ2','VO2Gort9WWLrNg4-AHiEiqJwjg_i8wBraNQV4OFEp1_7dQiXbfA_eHZdHBkp3kLfzpMoIsxP6yRjxvg0VWdTmomrx2uxQs0fo94QzZHXi3E1')]}
pdfkit.from_url(url,'1.pdf', configuration = config, options = options)



纸张为 A4 纸大小。和真实点出来再打印的效果还是有出入的。在 options 里调整大小:

options = {'page-size': 'A4', #设置纸张
'dpi': 400,
'cookie':[(''........),(),()]}

几次尝试,有次放大后字和阴影重合了!效果太差劲了。

所以,最后还是选择了 手工解决。



4 参考链接及我给自己挖坑的地方



(1)pdfkit:https://juejin.im/post/5c6d2591e51d457fd033e305

(2)在我不知道 cookie 怎么插入的时候,大佬丢给了我这样一个链接:

https://www.soinside.com/question/aKUWwtvfZZGEV5EQNbwJrC

可是我没仔细看,直接学了提问者的方式,妥妥的报错。甚至是非常长的错误提示。

然后又看了一眼,回答席的提示,也就是第 3 点的内容,成功的写对了 options 里的 cookie。又迎来报错:

OSError: wkhtmltopdf exited with non-zero code 1. error:

这是因为,用了传递 cookie 的方法,那就只能是 pdfkit.from_url 了,可我写的是 pdfkit.from_file 。

所以,复制粘贴前多给代码块写注释,下次就会避免再犯同样的错误了。



总结



知耻而后勇,我要学 selenium。

selenium 可以模拟浏览器的操作,只是由于我目测了一下现学的复杂程度和时间限制,我就选择了日后再学,先手动搞定。安心做的话,鼠标配合键盘,半个小时不到就处理完毕了。

只是做得很无聊、很没劲、很工具人罢了。



技能不到位,要么无聊的完成,要么苦学。

然后等下一次无聊的工作降临时,轻松的解决它。

:)

发布于: 2020 年 05 月 19 日阅读数: 669
用户头像

进一寸有进一寸的欢喜 2019.07.22 加入

我只不过是一位在海滩上贪玩的拾贝者。 更多非技术类文章在微信公众号:小匚,欢迎关注。

评论 (1 条评论)

发布
用户头像
“ 技能不到位,要么无聊的完成,要么苦学。
然后等下一次无聊的工作降临时,轻松的解决它。”
实在!
2020 年 05 月 19 日 13:17
回复
没有更多了
半小时手工解决的活,让我意外学会了 python 的 pdfkit 库