Python - 在浏览器中将PDF特定页面的表列读取为NumPy数组

1 投票
2 回答
36 浏览
提问于 2025-04-14 16:54

任务

在这个PDF的第10页上,有一个表格1。我想把“WHO世界标准*”这一列读成一个NumPy数组。

尝试(失败)

  1. 使用Tabula时出现了一个错误:urllib.error.HTTPError: HTTP Error 403: Forbidden
    import tabula
    pdf = "https://cdn.who.int/media/docs/default-source/gho-documents/global-health-estimates/gpe_discussion_paper_series_paper31_2001_age_standardization_rates.pdf"
    tables = tabula.read_pdf(pdf, pages=10)
    
  2. PDFPlumber找不到这个网址/PDF文件。
    import pdfplumber
    
    
    with pdfplumber.open("https://cdn.who.int/media/docs/default-source/gho-documents/global-health-estimates/gpe_discussion_paper_series_paper31_2001_age_standardization_rates.pdf") as pdf:
       page = pdf.pages[9]
       table = page.extract_table()
       header_row = table[0]
       who_std_col_idx = header_row.index("WHO World Standard*")
       who_std_values = [row[who_std_col_idx] for row in table[1:]]
       print(who_std_values)
    

附加要求

如果能仅使用Conda中可用的Python包来完成那就更好了,因为我希望为我的项目创建一个requirements.txt文件。

2 个回答

1

Camelot看起来运行得非常好:

import camelot
tables = camelot.read_pdf('https://cdn.who.int/...', pages='10')
df = tables[0].df

这段代码会生成一个pandas的数据框(DataFrame),不过还需要稍微调整一下。

1

你可以试着创建一个BytesIO对象,然后把它传给read_pdf,接着进行一些后续处理:

import requests
from io import BytesIO

URL = "https://cdn.who.int/.../...aper31_2001_age_standardization_rates.pdf"

PN = 10 # page number
TN = 1  # table number 
CN = -1 # last col / "WHO World Standard*"

arr = (
    pd.to_numeric(
        tabula.read_pdf(BytesIO(requests.get(URL).content), pages=PN)[TN-1]
        .iloc[1:, CN].str.split(expand=True).iloc[:, CN],
        errors="coerce",
    ).dropna().to_numpy()[:-1]
)

或者使用,用相同的思路:

import fitz # pip install pymupdf

with fitz.open(stream=requests.get(URL).content) as pdf:
    arr = (
        pd.to_numeric(
            pdf[PN-1].find_tables()[TN-1].to_pandas().iloc[:, CN],
            errors="coerce",
        ).dropna().to_numpy()[:-1]
    )

输出结果:

array([8.86, 8.69, 8.6 , 8.47, 8.22, 7.93, 7.61, 7.15, 6.59, 6.04, 5.37,
       4.55, 3.72, 2.96, 2.21, 1.52, 0.91, 0.63])

撰写回答