You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中PdfFileReader读取网络PDF失败,请求解决方案

解决内嵌在HTML中的PDF读取问题

嘿,我来帮你搞定这个PDF读取的麻烦!你遇到的问题根源很明确:第一个URL是直接返回PDF二进制文件流,所以PdfFileReader可以直接处理;但第二个URL返回的是包含PDF数据的HTML页面(也就是你说的"application data"形式),直接把这个URL传给PdfFileReader,它读到的是HTML代码而非真实的PDF内容,自然会报错。

下面分两种常见场景给你对应的代码修改方案:

场景1:PDF以Data URI形式内嵌在HTML标签中(比如iframe/embed)

大多数这类网站会把PDF编码成base64格式,放在iframeembed标签的src属性里(格式类似data:application/pdf;base64,JVBERi0xLjQK...)。我们需要先解析HTML提取出这段base64数据,解码后再传给PdfFileReader

示例代码:

import requests
from bs4 import BeautifulSoup
import PyPDF2
import base64
import io

# 替换成你的第二个URL
target_url = "https://example.com/your-page-with-embedded-pdf"

# 1. 获取HTML页面内容
response = requests.get(target_url)
response.raise_for_status()  # 确保请求成功,失败则抛出异常

# 2. 解析HTML,找到内嵌PDF的标签
soup = BeautifulSoup(response.text, "html.parser")
# 优先找iframe标签,也可以根据实际情况换成embed标签
pdf_element = soup.find("iframe", {"type": "application/pdf"}) or soup.find("embed", {"type": "application/pdf"})

if pdf_element:
    # 提取Data URI并拆分出base64部分
    pdf_data_uri = pdf_element["src"]
    try:
        _, base64_content = pdf_data_uri.split("base64,", 1)
    except ValueError:
        print("该PDF不是以base64编码的Data URI形式存在")
        exit()
    
    # 3. 解码base64为二进制PDF数据
    pdf_bytes = base64.b64decode(base64_content)
    # 4. 将二进制数据转为类文件对象,供PdfFileReader读取
    pdf_file = io.BytesIO(pdf_bytes)
    
    # 现在可以正常读取PDF了
    reader = PyPDF2.PdfFileReader(pdf_file)
    print(f"成功读取PDF,总页数:{reader.getNumPages()}")
else:
    print("在页面中未找到内嵌的PDF标签(iframe/embed)")

场景2:PDF是通过JavaScript动态加载的

如果网站的PDF是通过AJAX或者其他JS逻辑动态渲染到页面中的,用requests+BeautifulSoup可能抓不到数据,这时候需要用浏览器自动化工具(比如Selenium)模拟真实浏览器加载页面,获取渲染后的内容。

示例代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
import PyPDF2
import base64
import io

# 替换成你的第二个URL
target_url = "https://example.com/your-dynamic-page-with-pdf"

# 初始化浏览器(这里用Chrome,需要提前安装ChromeDriver)
driver = webdriver.Chrome()
driver.get(target_url)
driver.implicitly_wait(10)  # 等待页面加载完成

# 查找内嵌PDF的iframe标签
try:
    pdf_iframe = driver.find_element(By.TAG_NAME, "iframe")
    pdf_data_uri = pdf_iframe.get_attribute("src")
    
    # 后续解码步骤和场景1一致
    _, base64_content = pdf_data_uri.split("base64,", 1)
    pdf_bytes = base64.b64decode(base64_content)
    pdf_file = io.BytesIO(pdf_bytes)
    
    reader = PyPDF2.PdfFileReader(pdf_file)
    print(f"成功读取动态加载的PDF,总页数:{reader.getNumPages()}")
except Exception as e:
    print(f"读取失败:{str(e)}")
finally:
    driver.quit()  # 关闭浏览器

注意事项:

  • 不同网站的内嵌逻辑可能不同,你可以先打开目标页面的开发者工具(F12),查看HTML结构,确认PDF数据具体藏在哪个标签或位置,再调整代码中的查找逻辑。
  • 如果遇到反爬机制,可能需要给requests添加请求头(比如User-Agent),或者在Selenium中配置浏览器选项模拟正常用户行为。

内容的提问来源于stack exchange,提问作者Bosiwow

火山引擎 最新活动