(1) 直接调用GROBID库出现问题
前几周使用GROBID库完成了几百个PDF文档的批量解析 如这两篇博客记录
GROBID库:Windows环境下运行GROBID库解析文档的解决方案
关键代码如下:
from grobid_client.grobid_client import GrobidClient
client = GrobidClient(config_path="./config.json")
client.process("processHeaderDocument","D:/pdf",output="D:/xml",consolidate_citations=True, tei_coordinates=True, force=True)
大致过程如下:
- GitHub上安装了该库 发觉不支持Windows系统
- 转用Docker完成了Windows环境下GROBID库的正常使用
- 阅读官方文档 调用API完成了批量解析
本以为这部分任务已经结束了 但是今天检查解析出的文档时 部分文件1kb大小:
很明显解析不正确 打开文档观察到这样的提示:
[BAD_INPUT_DATA] PDF to XML conversion failed with error code: 1
或这样的提示
[TIMEOUT] PDF to XML conversion timed out
那么如我之前那样简单调用Python API的方式已经不可取了 因其存在如下缺点:
-
运行速度极慢;多线程的情况下运行百个文档也需要数小时。
-
正确率低;解析文档常常报错未生成XML文档。
-
文档有误;即使生成XML文档 也常常得到错误结果。
当然也可能是因我个人的电脑配置不佳或者是部分参数设置错误 总之我决定尝试新的方法
(2) 网页解析与抓包
利用类似常规爬虫的套路 当然此处算不上什么爬虫 只是简单的网页请求
首先观察Grobid Web网页的结构:
用户动态在网页提交论文文件,下方请求服务,返回论文解析的结果,但网站地址栏保持不变。
很明显XML文件的数据是动态加载的,那么我们很容易联想到相关的技术 AJAX
利用开发者模式抓包 成功抓取到相关的请求
(3) 利用requests进行请求
那么接下来的工作 就很简单了
- 发送请求 上传文件
- 获得返回的XML二进制数据,写入本地文档中。
import os
import re
import requests
import glob
def getXml(filename, path):
url = "http://localhost:8070/api/processFulltextDocument"
params = dict(input=open(path + filename + ".pdf", 'rb'))
response = requests.post(url, files=params, timeout=300)
fh = open("D:/xml/" + filename + ".xml", "w", encoding="utf-8")
fh.write(response.text)
fh.close()
def main():
path = "D:/pdf/"
inpdf = glob.glob(path + '*')
for num in range(len(inpdf)):
filename = re.findall(r'\\(.*?)\.pdf', str(inpdf[num]))[0]
getXml(filename, path)
glob是为了获取文档的名称列表 re正则表达式是为提取全部地址中的文件名称
需要使用时调整好输入PDF与输出XML的文件夹地址即可。
五分钟可以解析近百个PDF并将XML文档保存在本地。