使用Python从PDF网址文件中提取文本

3
我想从某个网站上的 PDF 文件中提取文本。该网站包含到 PDF 文档的链接,但当我点击该链接时,它会自动下载该文件。是否可能在不下载该文件的情况下提取其中的文本?
import fitz  # this is pymupdf lib for text extraction
from bs4 import BeautifulSoup
import requests
from io import StringIO

url = "https://www.blv.admin.ch/blv/de/home/lebensmittel-und-ernaehrung/publikationen-und-forschung/statistik-und-berichte-lebensmittelsicherheit.html"

headers = {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}


response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')

all_news = soup.select("div.mod.mod-download a")[0]
pdf = "https://www.blv.admin.ch"+all_news["href"]

#https://www.blv.admin.ch/dam/blv/de/dokumente/lebensmittel-und-ernaehrung/publikationen-forschung/jahresbericht-2017-2019-oew-rr-rasff.pdf.download.pdf/Jahresbericht_2017-2019_DE.pdf

这是从PDF文件中提取文本的代码。当文件被下载时,它的工作效果很好:

my_pdf_doc = fitz.open(pdf)
text = ""
for page in my_pdf_doc:
    text += page.getText()

print(text)

同样的问题是,如果链接不会自动下载PDF文件,例如此链接:

"https://amsoldingen.ch/images/files/Bekanntgabe-Stimmausschuss-13.12.2020.pdf"

我该如何从那个文件中提取文本

我也尝试过这个方法:

pdf_content = requests.get(pdf)
print(type(pdf_content.content))

file = StringIO() 
print(file.write(pdf_content.content.decode("utf-32")))

但是我遇到错误:

Traceback (most recent call last):
  File "/Users/aleksandardevedzic/Desktop/pdf extraction scrapping.py", line 25, in <module>
    print(file.write(pdf_content.content.decode("utf-32")))
UnicodeDecodeError: 'utf-32-le' codec can't decode bytes in position 0-3: code point not in range(0x110000)

您可以使用BytesIO将文件下载到内存中:https://dev59.com/3mEh5IYBdhLWcg3wfzlE - Ramon Medeiros
这在我的电脑上不起作用,它给了我一个错误。 - taga
你能展示一下如何在我的代码中应用它吗?也许我做错了什么。 - taga
4个回答

5

下面是使用 PyPDF2 的示例。

安装方式

pip install PyPDF2

import requests, PyPDF2
from io import BytesIO

url = 'https://www.blv.admin.ch/dam/blv/de/dokumente/lebensmittel-und-ernaehrung/publikationen-forschung/jahresbericht-2017-2019-oew-rr-rasff.pdf.download.pdf/Jahresbericht_2017-2019_DE.pdf'
response = requests.get(url)
my_raw_data = response.content

with BytesIO(my_raw_data) as data:
    read_pdf = PyPDF2.PdfFileReader(data)

    for page in range(read_pdf.getNumPages()):
        print(read_pdf.getPage(page).extractText())

输出:

' 1/21  Fad \nŒ 24.08.2020\n      Bericht 2017\n Œ 2019: Öffentliche Warnungen, \nRückrufe und Schnellwarnsystem RASFF\n      '

刚刚添加了循环。 - Ramon Medeiros
问题在于我得到的结果非常混乱,没有组织。 - taga
1
问题已经超出了范围。第一个问题已经得到了回答(如何在不下载文件的情况下读取PDF文件)。现在我建议您通过查阅此库的文档来学习如何读取PDF:https://pythonhosted.org/PyPDF2/。 - Ramon Medeiros

2
PyMuPDF允许我们直接打开BytesIO流,如文档中所述。
import requests
import fitz
import io

url = "your-url.pdf"
request = requests.get(url)
filestream = io.BytesIO(request.content)
pdf = fitz.open(stream=filestream, filetype="pdf")

pdf可以像常规的PyMuPDF文档一样进行解析,如此处所示。

P.S. 这是我在Stack Overflow上的第一个答案,欢迎任何改进/建议。


0

我已经尝试了@Vihaan Thora的解决方案,它对我有效。

!pip install PyMuPDF

import requests
import fitz
import io

url = "https://www.livelaw.in/pdf_upload/vsa02052022matfc1162021145829-416435.pdf"
request = requests.get(url)
filestream = io.BytesIO(request.content)
with fitz.open(stream=filestream, filetype="pdf") as doc:
    detail_judgement = ""
    for page in doc:
        detail_judgement += page.get_text()
print(detail_judgement)

0

如果一个网络应用程序/ pdf 文件在远程位置(比如服务器上),那么在没有“下载”操作的情况下,是不可能阅读它的。浏览器/阅读器/文本提取器是本地的,HTTPS 安全性要求文件在本地作为超文本传输(除非服务器未经特别配置允许客户端对其提供的文件进行管理编辑)。

由于我的浏览器用户设置只能安全下载而不能在浏览器中运行容易受攻击的视图,所以你所提供的两个链接都会立即下载到我的浏览器中。

因此,要提取文本,你需要在本地设备文件系统内获取一个临时副本(这通常使用硬盘缓存),有人建议可以使用 Python FileStream IO 来实现。然而,这与下载的方式并没有太大区别。

该文件可以使用内存转换为临时 IO,作为高效的文件字节来传输。

Curl -O https://www.blv.admin.ch/dam/blv/de/dokumente/lebensmittel-und-ernaehrung/publikationen-forschung/jahresbericht-2017-2019-oew-rr-rasff.pdf.download.pdf/Jahresbericht_2017-2019_DE.pdf

然后使用相关的Python操作系统命令

pdftotext Jahresbericht_2017-2019_DE.pdf | Find "whatever you need"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接