PyPDF2.utils.PdfReadError: Unexpected destination '/__WKANCHOR_2'

来源:互联网 发布:我的世界展示框js 编辑:程序博客网 时间:2024/06/05 01:14

在学习这篇文章之前,对于一点都不懂python的朋友,可以去看下我之前写过的博客文章,也都是学习过程中的一些收获,感兴趣的可以去看看http://www.flybi.net/blog/seng

之所以写这篇文章,是因为在学习《Python网络数据采集》的时候,书中提到了访问pdf的方法,于是我就想是否能将天善博客内容转成PDF文档,这个功能会很有用,以后可以方便查找。

思路:使用命令行工具wkhtmltopdf,可以将html 转成 PDF,Python有个包python-pdfkit,方便了wkhtmltopdf和Python的结合。不过目前wkhtmltopdf读取的页面数有限制,文档很多的话会生成多个PDF,这样就需要合并,试过很多种合并方法,最终使用ghostscript解决的。

接下来具体介绍一下做法。



1wkhtmltopdf功能简介




下载页面:http://wkhtmltopdf.org/downloads.html

 使用0.12.3 Linux版下载后直接解压即可。

 tar -xvf wkhtmltox-0.13.0-alpha-7b36694_linux-centos6-amd64.rpm.part
 sudo ln -s ./wkhtmltox/
bin/wkhtmltopdf /usr/bin/wkhtmltopdf

使用示例如下:

wkhtmltopdf  'http://www.flybi.net/blog/seng/3645' 'http://www.flybi.net/blog/seng/3599'  sengblog.pdf

注意:天善使用的javascript,好像对这个有影响,只能生成一个页面,要等javascript运行完,加参数即可--javascript-delay 2000,或者屏蔽掉也可以--disable-javascript

wkhtmltopdf  --javascript-delay 2000 'http://www.flybi.net/blog/seng/3645' 'http://www.flybi.net/blog/seng/3599'  sengblog.pdf

如果出问题,可以看一下大纲的信息:

wkhtmltopdf  --dump-outline out.xsl  toc 'http://www.flybi.net/blog/seng/3645' 'http://www.flybi.net/blog/seng/3599'  sengblog.pdf



2pdfkit调用的接口




参考网站:https://pypi.python.org/pypi/pdfkit

Install python-pdfkit:
$ pip install pdfkit
简单的示例:
import pdfkit
pdfkit.from_url([ 'http://www.flybi.net/blog/seng/3645',
'http://www.flybi.net/blog/seng/3599'], 'sengblog.pdf')  



3生成blog的PDF文件




以我的博客为例

我的首页:

http://www.flybi.net/people/seng

我的博客就5页,获取这些链接就可以了

http://www.flybi.net/blog/id-seng__page-1

核心逻辑如下:

(1)获取所有blog具体页面的URL;

(2)排序:暂时偷个懒,先按默认字符排序了;

(3)生成pdf文档,注意目前测试只能包含有限的页面,目前使用20个,按类似以下格式sengblog20160419_1_20生成;

(4)合并pdf文档。

目前没有现成代码,一开始使用http://www.pdfmerge.com/手工做的,后找到更好的办法,下面详细介绍如何合并。



4合并PDF文档




因为wkhtmltopdf有限制,文档多了,需要生成多个pdf文件,原来使用http://www.pdfmerge.com/在线服务合并文档,感觉不完美,合并更多文件就比较麻烦了,找了一些工具最终解决了,测试了PyPDF2、pdftk、ghostscript,都能合并,不过PyPDF2、pdftk对wkhtmltopdf生成的文档的outline合并有问题,特别是PyPDF2需要修改代码,才能完成合并。所以最后选用了ghostscript来完成合并。

相关工具版本要求:

ghostscript:9.19

wkhtmltopdf:0.12.3 (with patched qt)

ghostscript的安装使用:

下载:

http://ghostscript.com/download/gsdnld.html

帮助文档:

http://www.ghostscript.com/doc/9.19/Use.htm

命令示例:

gs-919-linux_x86_64 -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=./output/all_coffee.pdf coffee1_20.pdf coffee21_40.pdf
linux_x86_64 -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=all_seng.pdf seng*.pdf

PyPDF2的安装使用:

PyPDF2版本:1.25.1

https://pypi.python.org/pypi/PyPDF2/1.25.1

https://github.com/mstamy2/PyPDF2

安装:

pip install PyPDF2

使用示例:

from PyPDF2 import PdfFileMerger
merger = PdfFileMerger()
input1 = 
open("hql_1_20.pdf""rb")
input2 = 
open("hql_21_40.pdf""rb")
merger.append(input1)
merger.append(input2)
# Write to an output PDF document
output = 
open("hql_all.pdf""wb")
merger.
write(output)

--------------------

注意合并wkhtmltopdf系统会出错:

PdfReadError: Unexpected destination '/__WKANCHOR_2'

#fix PyPDF2 merge outline出问题的解决

#参考https://github.com/mstamy2/PyPDF2/issues/193

I had the same problem. For a quick and dirty fix I commented out the lines 1225 and 1226 in the file pdf.py of the package PyPDF2 which raise the exception:

    # if destination found, then create outline    if dest:        if isinstance(dest, ArrayObject):            outline = self._buildDestination(title, dest)        elif isinstance(dest, Str) and dest in self._namedDests:            outline = self._namedDests[dest]            outline[NameObject("/Title")] = title        # else:        #     raise utils.PdfReadError("Unexpected destination %r" % dest)    return outline

pdf.py 1225-1226按如下屏蔽即可
# if destination found, then 
create outline
if dest:
    
if isinstance(dest, ArrayObject):
        
outline = self._buildDestination(title, dest)
    elif isinstance(dest, 
Strand dest in self._namedDests:
        
outline = self._namedDests[dest]
        
outline[NameObject("/Title")] = title
    #### 
else:
    ####     
raise utils.PdfReadError("Unexpected destination %r" % dest)
return outline

pdftk的安装使用:

安装:

sudo yum install libgcj
sudo rpm -
i pdftk-2.02-1.*.rpm

使用:

pdftk a1*.pdf cat output combined.pdf  

outline的手工修复:

pdftk支持outline的编辑,可以参考这个,

http://stackoverflow.com/questions/296****79/merge-pdfs-with-pdftk-with-bookmarks

pdftk hql_1_20.pdf dump_data > in1.info

#手工修改in1.info文件

pdftk hql_1_20.pdf update_info in1.info output out.pdf.

当然程序还有些欠缺:

1.uft8的文件名在linux能使用,到windows下就软乱码了。

2.wkhtmltopdf读取html遇到503错误,需要再次检查和重新读取。


原创粉丝点击