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

点击按钮后如何获取Scrapy-Playwright动态加载的新HTML内容?

解决Scrapy-Playwright无法获取PDF查看器动态内容的问题

问题核心

点击按钮打开PDF查看器后,networkidle状态可能在PDF文本层元素加载完成前就触发,导致获取的HTML仍是初始页面内容;部分网站的PDF查看器会用iframe承载内容,直接获取主页面内容会遗漏这部分动态渲染的文本。

修正方案

1. 等待目标元素加载完成

替换networkidle等待逻辑,直接等待PDF文本层元素div.page-text-layer出现,确保内容已实际渲染。

2. 处理iframe承载的PDF内容

部分网站会把PDF查看器放在iframe中,需要先切换到对应iframe才能获取内部的文本内容。

3. 优化超时与关闭逻辑

给元素等待添加超时设置,避免因网络延迟导致等待失败;确保内容获取完成后再关闭页面。

修正后的代码

import scrapy
from scrapy_playwright.page import PageMethod
from scrapy.selector import Selector

class SchifferstadtSpider(scrapy.Spider):
    name = 'schifferstadt'

    def start_requests(self):
        url = 'https://schifferstadt.more-rubin1.de/meeting.php?id=ni_2022-01-147'
        yield scrapy.http.Request(
            url, 
            callback=self.parse_sitzungen,
            meta=dict(
                playwright=True,
                playwright_include_page=True, 
                playwright_page_methods=[PageMethod('wait_for_selector', 'div.tabs-details')],
            ),
            errback=self.errback_close_page,
        )

    async def parse_sitzungen(self, response):
        page = response.meta["playwright_page"]
        
        # 点击按钮打开PDF查看器
        await page.get_by_role("button", name="Bekanntmachung").click()
        
        # 等待PDF文本层元素加载,设置10秒超时
        await page.wait_for_selector("div.page-text-layer", timeout=10000)
        
        # 检测是否存在承载PDF的iframe,有则切换到iframe内部
        iframe = page.locator("iframe[src*='pdf']").first
        if await iframe.count() > 0:
            await iframe.wait_for()
            pdf_frame = await iframe.content_frame()
            html = await pdf_frame.content()
        else:
            # 无iframe则直接获取当前页面内容
            html = await page.content()
        
        html_selector = Selector(text=html)
        content = ' '.join(html_selector.xpath("//div[@class='page-text-layer']/span/text()").getall())
         
        # 关闭查看器和页面
        await page.locator(".file-viewer-modal-document-close-button").click()
        await page.close()

        yield {'content': content}

    async def errback_close_page(self, failure):
        page = failure.request.meta["playwright_page"]
        await page.close()

关键修改说明

  • 精准等待:用wait_for_selector("div.page-text-layer")替代networkidle,确保PDF文本已渲染完成,而非仅网络请求结束。
  • iframe适配:增加iframe检测逻辑,针对网站的PDF承载方式切换上下文,避免遗漏iframe内的动态内容。
  • 超时保护:给元素等待添加10秒超时,防止因网络波动导致程序无响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:35:19