python爬虫读取pdf_python爬虫处理在线预览的pdf文档

引言

最近在爬一个网站,然后爬到详情页的时候发现,目标内容是用pdf在线预览的

比如如下网站:

https://camelot-py.readthedocs.io/en/master/_static/pdf/foo.pdf

1249183-20191228125247341-186370863.png

根据我的分析发现,这样的在线预览pdf的采用了pdfjs加载预览,用爬虫的方法根本无法直接拿到pdf内的内容的,对的,你注意到了我说的【根本无法直接拿到】中的直接两个字,确实直接无法拿到,怎么办呢?只能把pdf先下载到本地,然后用工具转了,经过我查阅大量的相关资料发现,工具还是有很多:

1.借用第三方的pdf转换网站转出来

2.使用Python的包来转:如:pyPdf,pyPdf2,pyPdf4,pdfrw等工具

这些工具在pypi社区一搜一大把:

1249183-20191228125920925-1003953344.png

但是效果怎么样就不知道了,只能一个一个去试了,到后面我终于找到个库,非常符合我的需求的库 ——camelot

camelot可以读取pdf文件中的数据,并且自动转换成pandas库(数据分析相关)里的DataFrame类型,然后可以通过DataFrame转为csv,json,html都行,我的目标要的就是转为html格式,好,废话不多说,开始搞

开始解析

1.安装camelot:

pip install camelot-py

pip install cv2 (因为camelot需要用到这个库)

2.下载pdf:因为在线的pdf其实就是二进制流,所以得按照下载图片和视频的方式下载,然后存到本地的一个文件里,这个步骤就不多说了

3.解析:

importcamelot

file= 'temp.pdf'table= camelot.read_pdf(file,flavor='stream')

table[0].df.to_html('temp.html')

以上的temp.html就是我希望得到的数据了,然后根据我的分析发现,在read_pdf方法里一定带上参数 【flavor='stream'】,不然的话就报这个错:

RuntimeError: Please make sure that Ghostscript is installed

原因就是,read_pdf默认的flavor参数是lattice,这个模式的话需要安装ghostscript库,然后你需要去下载Python的ghostscript包和ghostscript驱动(跟使用selenium需要下载浏览器驱动一个原理),而默认我们的电脑肯定是没有安装这个驱动的,所以就会报上面那个错。我试着去装了这个驱动和这个包,去read_pdf时其实感觉没有本质区别,是一样的,所以带上参数flavor='stream'即可,当然如果你硬要用lattice模式的话,安装完ghostscript包和ghostscript驱动之后,记得在当前py文件用 【import ghostscript】导入下这个包,不然还是会报如上错误

继续走,发现能拿到我想要的数据了,非常nice,然后突然的,报了如下错误:

PyPDF2.utils.PdfReadError: EOF marker not found

1249183-20191228124646673-1062571937.png

当时就是卧槽,这什么情况,我开始去研究EOF marker是什么意思,但是我直接打开这个pdf文件又是正常的

1249183-20191228124653677-725491303.png

非常诡异,网上查阅了一堆,大概意思就是说,没有EOF结束符,这个东西在之前我做js开发的时候遇到过,js的语句体{},少了最后的【}】,

我又去了解了下EOF到底在二进制文件指的什么,然后看到老外的这个帖子:

1249183-20191228124700170-1782528254.png

我用同样的方法查看数据的前五个字符和后五个字符:

1249183-20191228124726842-1071596144.png

1249183-20191228124944838-1159645717.png

好像有了眉目,我以文本的方式打开了我下载到本地的一个pdf,在%%EOF结尾之后还有很多的null

1249183-20191228124954617-931817814.png

难道是NULL的问题?我手动删掉null之后,单独对这个修改过的pdf用pdf查看器打开,正常打开,没有问题,我接着用代码针对这个文件执行read_pdf,发现非常神奇的不会报错了,那还真是结尾的NULL元素了。

然后我在从网上读取到pdf之后的二进制部分用字符串的strip()方法,以为用strip可以去除那些null,结果发现还是如此

1249183-20191228125005939-844813831.png

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

那就只有先锁定 %%EOF 所在位置,然后切片操作了,部分代码如下,果然问题解决,但同时又报了一个新的错,这个就是个编码问题了,相信搞爬虫的朋友们对这个问题非常熟悉了

1249183-20191228125018559-762565105.png

先暂时不管这个问题,我又改了下目标网站的指定页码

1249183-20191228130306970-1405769904.png

1249183-20191228130324518-1987598181.png

pdfminer.psparser.SyntaxError: Invalid dictionary construct: [/'Type', /'Font', /'Subtype', /'Type0', /'BaseFont', /b"b'", /"ABCDEE+\\xcb\\xce\\xcc\\xe5'", /'Encoding', /'Identity-H', /'DescendantFonts',

1249183-20191230092702896-1320633983.png

1249183-20191230092730028-1996893729.png

1249183-20191230092831098-203380189.png

1249183-20191230093101629-1714015591.png

1249183-20191228130333736-1850656966.png

1249183-20191228130340541-701645269.png

1249183-20191228130349297-2118990302.png

1249183-20191228130402245-2106098483.png

1249183-20191228130412199-1893038492.png

1249183-20191228130422302-2029657265.png

1249183-20191228130435036-106030662.png

1249183-20191228130504317-868241857.png

1249183-20191228130509190-261401898.png

1249183-20191228130517694-655323077.png

1249183-20191228130527514-788738324.png

1249183-20200214115236503-824162559.png

1249183-20200214115829015-1959941984.png

1249183-20200214120733875-1163679852.png

1249183-20200214120850538-534757767.png