PDFは、多くの治療のPDFライブラリがあり、異常なピットの父のことですが、完璧ではありません。
、pdfminer3k
pdfminer3kは、主にPDFファイルにテキストを読むために、のpython3バージョンpdfminerです。
ただ、あまりにも複雑で、約Pythonのシンプルに反しTucaoしたい、オンライン多くのpdfminer3kコード例がある、と後で読みます。
PDFDocument、からインポートPDFParserのpdfminer.pdfparser インポートPDFResourceManager、PDFPageInterpreter pdfminer.pdfinterpから インポートPDFPageAggregator pdfminer.converterから LTTextBox、インポートLAParams pdfminer.layoutから インポートPDFTextExtractionNotAllowedのpdfminer.pdfinterpから パス= "test.pdfという" 作成するファイルオブジェクトと# PDF文書アナライザ praser = PDFParser(オープン(パス、 'RB')) #PDF文書作成 DOC = PDFDocument() ドキュメントオブジェクトと#パーサー接続 praser.set_document(DOC) doc.set_parser(praser) #を初期化コードを提供 #あなたは空の文字列にパスワードを作成していない場合は doc.initializeを() #はTXTドキュメントの変換は、無視を提供していないかどうかを検出 doc.is_extractableされていない場合: 昇給はPDFTextExtractionNotAllowed 他: #は、PDFエクスプローラは、共有リソースを管理するために作成 rsrcmgr = PDFResourceManager() #PDFデバイスオブジェクト作成 laparams =のLAParams() デバイス= PDFPageAggregator(rsrcmgr、laparams = laparams) PDFインタプリタは、オブジェクトを作成位 インタプリタ= PDFPageInterpreter(rsrcmgr、装置) リストを#ループ、各コンテンツのページを扱う doc.get_pagesにページの(): interpreter.process_page(ページ) #ページLTPage対象受け入れる レイアウト= device.get_result() ここで#はLTPageレイアウト・オブジェクトです、さまざまなオブジェクト内に格納され、このページには、解析された ようLTTextBox、LTFigure、LTImage、LTTextBoxHorizontalを含める#を :Xにおけるレイアウトの でisinstance(X、LTTextBox)IF: 印刷(。x.get_text()ストリップ())
処理のためのpdfminerたちはフォーマットテキストを抽出することはできませんが、非常に非友好を形成します:
PDFファイル形式のスクリーンショット:
コード実行中の結果:
この結果は、テーブルを復元することは容易ではないしたい、プラス多くのルールは、必然的に衰退の多様性につながります。
二、タブラ-PY
CSV、Excel形式へのPDFの書き出しをサポートしながらタブラは、PDF形式のデータを抽出するように設計されていますが、このツールは、Javaで書かれている、java7 / 8を利用しています。タブラ-PYそれはPythonのパッケージングの層で作られ、それはまた、java7 / 8に依存します。
コードは簡単です:
インポートタブラの パス= 'test.pdfという' DF = tabula.read_pdf(パスエンコード= 'GBK'、ページ= 'すべて') df.indexでindexs用: プリント(df.loc [indexs] .values) #1タブラ。 convert_into(パス、os.path.splitext(パス)[0] + 'CSV'、ページ= 'すべて')
それは、PDFの専門取り扱いの形が、実際の効果として知られているが、あなたがたではありません。次のようにまたはPDF、pdfminerの業績は以下のとおりです。
この結果は、実際には非常に恥ずかしいああ、間違って識別するための最初のテーブルで、そこにPDF内の2つのテーブルがあり、私はテーブルを区別するためにどのように見つけることができませんでした。
三、pdfplumber
pdfplumberは、すべてのテキストを処理するために、PDFのページに基づいており、ページを取得し、フォームを抽出するための単一の方法を提供することができます。
import pdfplumber path = 'test.pdf' pdf = pdfplumber.open(path) for page in pdf.pages: # 获取当前页面的全部文本信息,包括表格中的文字 # print(page.extract_text()) for table in page.extract_tables(): # print(table) for row in table: print(row) print('---------- 分割线 ----------') pdf.close()
得到的 table 是个 string 类型的二维数组,这里为了跟 tabula 比较,按行输出显示。
可以看到,跟 tabula 相比,首先是可以区分表格,其次,准确率也提高了很多,表头的识别完全正确。对于表格中有换行的,识别还不是很正确,但至少列的划分没问题,所以还是能处理的。
import pdfplumber import re path = 'test1.pdf' pdf = pdfplumber.open(path) for page in pdf.pages: print(page.extract_text()) for pdf_table in page.extract_tables(): table = [] cells = [] for row in pdf_table: if not any(row): # 如果一行全为空,则视为一条记录结束 if any(cells): table.append(cells) cells = [] elif all(row): # 如果一行全不为空,则本条为新行,上一条结束 if any(cells): table.append(cells) cells = [] table.append(row) else: if len(cells) == 0: cells = row else: for i in range(len(row)): if row[i] is not None: cells[i] = row[i] if cells[i] is None else cells[i] + row[i] for row in table: print([re.sub('\s+', '', cell) if cell is not None else None for cell in row]) print('---------- 分割线 ----------') pdf.close()
经过处理后,运行得到结果:
这结果已经完全正确了,而用 tabula,即便是经过处理也是无法得到这样的结果的。当然对于不同的 pdf,可能需要不同的处理,实际情况还是要自己分析。
pdfplumber 也有处理不准确的时候,主要表现在缺列:
我找了另一个 pdf,表格部分截图如下:
解析结果如下:
4列变成了两列,另外,如果表格有合并单元格的情况,也会有这种问题,我挑这个表格展示是因为比较特殊,没有合并单元格也缺列了。这应该跟 pdf 生成的时候有关。
但其实数据是获取完整的,并没有丢,只是被认为是非表格了。输出 page.extract_text() 如下:
然后,我又用 tabula 试了下,结果如下:
列是齐了,但是,表头呢???
pdfplumber 还提供了图形Debug功能,可以获得PDF页面的截图,并且用方框框起识别到的文字或表格,帮助判断PDF的识别情况,并且进行配置的调整。要使用这个功能,还需要安装ImageMagick。因为没有用到,所以暂时没有去细究。
四、后记
我们在做爬虫的时候,难免会遇到 pdf 需要解析,主要还是针对文本和表格的数据提取。而 python 处理 pdf 的库实在是太多太多了,比如还有 pypdf2,网上资料也比较多,但是我试了,读出来是乱码,没有仔细的读源码所以这个问题也没有解决。
而我对比较常用的3个库比较后觉得,还是 pdfplumber 比较好用,对表格的支持最好。
相关博文推荐: