You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest中mock HTML文件内链接的请求?

解决HTML转PDF时Mock外部链接请求无效的问题

requests_mock只拦截基于requests库发起的HTTP请求,但绝大多数HTML转PDF工具(比如pdfkit/wkhtmltopdf、WeasyPrint、Pyppeteer)都是用自身底层的网络模块处理请求,完全不依赖requests,所以你的mock代码根本拦截不到这些请求,自然无效。

根据你使用的PDF渲染工具,对应以下解决方案:

1. 使用pdfkit/wkhtmltopdf

wkhtmltopdf自带参数可以直接禁用或替换外部链接:

  • 禁用所有外部请求(最简单,适合你不需要响应内容的场景):
    import pdfkit
    options = {
        'disable-external-links': None  # wkhtmltopdf的无值参数用None表示
    }
    pdfkit.from_file('your.html', 'output.pdf', options=options)
    
  • 替换指定链接的内容(如果需要自定义mock内容):
    import pdfkit
    options = {
        'replace': 'https://example.com=<div>Mocked Content</div>'
    }
    pdfkit.from_file('your.html', 'output.pdf', options=options)
    

2. 使用WeasyPrint

WeasyPrint支持自定义URL fetcher,直接替换请求逻辑:

from weasyprint import HTML

def mock_url_fetcher(url):
    if url == 'https://example.com':
        # 返回自定义的mock响应
        return {
            'content': b'<html><body>Mocked Content</body></html>',
            'mime_type': 'text/html',
            'encoding': 'utf-8'
        }
    # 其他未mock的请求可以直接抛出异常或忽略
    raise ValueError(f"Unmocked URL: {url}")

# 传入自定义fetcher渲染PDF
html = HTML(filename='your.html', url_fetcher=mock_url_fetcher)
html.write_pdf('output.pdf')

3. 使用Pyppeteer/Playwright

这类基于浏览器的工具可以直接拦截页面网络请求:

Pyppeteer示例

import asyncio
from pyppeteer import launch

async def render_mocked_pdf():
    browser = await launch()
    page = await browser.newPage()
    
    # 开启请求拦截
    await page.setRequestInterception(True)
    async def intercept_request(req):
        if req.url == 'https://example.com':
            # 返回mock响应
            await req.respond({
                'status': 200,
                'contentType': 'text/html',
                'body': '<div>Mocked Content</div>'
            })
        else:
            # 其他请求正常处理
            await req.continue_()
    
    page.on('request', intercept_request)
    # 加载本地HTML文件(需传入绝对路径)
    await page.goto('file:///absolute/path/to/your.html')
    await page.pdf(path='output.pdf')
    
    await browser.close()

asyncio.run(render_mocked_pdf())

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:40:13