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

Python/WebKit代码遗漏<tbody>标签求助:动态JS渲染异常

解决PyQt5渲染页面时缺失内容的幽灵数据问题

我之前处理过几乎一模一样的问题,你碰到的这个「幽灵数据」本质是页面动态渲染的时机问题——你的代码在页面初始加载完成就立刻抓取HTML,但表格的<tbody>内容是JavaScript后续动态生成的,这时候还没来得及渲染出来。

问题根源

QWebPage的loadFinished信号只是表示页面的初始HTML和静态资源加载完成,但很多现代页面会在这之后通过AJAX请求数据、DOM操作等方式动态生成内容。你的代码在loadFinished触发后立即调用toHtml(),自然拿不到还没被JS注入的<tbody>及其内容。

解决方案:等待JS完成渲染

这里有两种可靠的处理方式,你可以根据需求选择:

1. 固定延迟等待(简单直接)

给页面留足够的时间让JS执行完成,用QTimer.singleShot设置延迟后再抓取HTML:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWidgets import QApplication

class Render(QWebPage):
    def __init__(self, url, wait_ms=3000):
        self.app = QApplication(sys.argv)
        QWebPage.__init__(self)
        self.wait_ms = wait_ms
        self.loadFinished.connect(self._on_load_finished)
        self.mainFrame().load(QUrl(url))
        self.app.exec_()

    def _on_load_finished(self, result):
        # 延迟指定毫秒后再获取渲染完成的HTML
        QTimer.singleShot(self.wait_ms, self._extract_html)

    def _extract_html(self):
        self.frame = self.mainFrame()
        self.result = self.frame.toHtml()
        self.app.quit()

url = 'https://cib.societegenerale.com/fileadmin/indices_feeds/ti_screen/index.html'
# 可以根据页面加载速度调整等待时间,比如4000ms
renderer = Render(url, wait_ms=4000)
print(renderer.result)

2. 监听目标元素(精准可靠)

如果固定延迟不够稳定(比如网络波动导致加载速度变化),可以通过执行JS检查目标元素(<tbody>)是否存在,确认后再抓取HTML:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWidgets import QApplication

class Render(QWebPage):
    def __init__(self, url):
        self.app = QApplication(sys.argv)
        QWebPage.__init__(self)
        self.loadFinished.connect(self._start_checking)
        self.mainFrame().load(QUrl(url))
        self.app.exec_()

    def _start_checking(self, result):
        # 每隔500ms检查一次tbody是否存在
        self.check_timer = QTimer()
        self.check_timer.timeout.connect(self._verify_tbody)
        self.check_timer.start(500)

    def _verify_tbody(self):
        # 执行JavaScript检查目标元素是否存在
        tbody_exists = self.mainFrame().evaluateJavaScript(
            "document.querySelector('#watchlistTable tbody') !== null"
        )
        if tbody_exists:
            self.check_timer.stop()
            self._extract_html()

    def _extract_html(self):
        self.frame = self.mainFrame()
        self.result = self.frame.toHtml()
        self.app.quit()

url = 'https://cib.societegenerale.com/fileadmin/indices_feeds/ti_screen/index.html'
renderer = Render(url)
print(renderer.result)

额外建议

QtWebKit是比较老旧的模块了,对现代JavaScript的支持有限。如果你的项目可以升级,建议换成PyQt5中的QtWebEngineWidgets模块,它基于Chromium内核,对动态页面的渲染兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:56:43