使用metapub与PubMed获取PDF异常:仅下载到数字1的排查求助
问题分析与修正方案
代码中的核心问题
- 未指定PDF下载路径:
urlretrieve(url)没有传入保存路径参数,下载的PDF并没有保存到你指定的another_path目录下,后续textract.process(out_file)处理的是一个新建的空文件,而非目标PDF。 - 文件操作逻辑颠倒:你试图直接将文本提取结果写入
out_file,但此时out_file还不是下载好的PDF文件,逻辑完全错误——应该先把PDF下载到本地,再对这个PDF文件执行文本提取,最后保存提取后的文本。 - 缺少文件后缀:保存的PDF文件没有
.pdf后缀,textract无法正确识别文件类型,会导致提取失败。 - 文件打开模式错误:
textract.process()返回的是字节数据,用"w"文本模式写入会引发编码错误,需使用"wb"二进制模式;如果是保存提取后的文本,应先将字节解码为字符串,再用文本模式写入。 - 宽泛的异常捕获:
except:会忽略所有错误,无法定位具体问题(比如PDF无法下载、提取失败等),不利于调试。
修正后的代码
import metapub from urllib.request import urlretrieve, URLError import textract from pathlib import Path another_path = '/content/Articles/' # 确保目录存在,避免路径不存在的错误 Path(another_path).mkdir(parents=True, exist_ok=True) pmid_list = ['35566889','33538053', '30848212'] for pmid in pmid_list: try: # 获取PDF链接 findit = metapub.FindIt(pmid) pdf_url = findit.url if not pdf_url: print(f"无法获取PMID {pmid}的PDF链接") continue # 定义PDF保存路径(带.pdf后缀) pdf_file_path = f"{another_path}{pmid}.pdf" # 下载PDF到指定路径 urlretrieve(pdf_url, pdf_file_path) print(f"已下载PMID {pmid}的PDF到{pdf_file_path}") # 提取PDF文本并解码为字符串 text_content = textract.process(pdf_file_path, method='pdftotext', encoding='utf_8').decode('utf_8') # 定义文本保存路径 text_file_path = f"{another_path}{pmid}.txt" # 写入文本文件 with open(text_file_path, "w", encoding="utf_8") as textfile: textfile.write(text_content) print(f"已提取PMID {pmid}的文本到{text_file_path}") except URLError as e: print(f"下载PMID {pmid}失败:{e}") except Exception as e: print(f"处理PMID {pmid}时出错:{e}")
关键修正说明
- 确保目录存在:用
Path(another_path).mkdir()提前创建目标目录,避免路径不存在的报错。 - 明确PDF保存路径:给
urlretrieve传入第二个参数,指定PDF的保存路径(带.pdf后缀)。 - 调整逻辑顺序:先下载PDF,再提取文本,最后保存文本结果,流程清晰合理。
- 正确处理字节与字符串:将
textract.process()返回的字节数据解码为字符串后,用文本模式写入.txt文件。 - 针对性异常捕获:区分网络错误和其他错误,打印具体错误信息,方便调试。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

