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

如何抓取动态渲染页面?Uniswap核心数据抓取失败求助

解决Uniswap信息站数据抓取的元素定位问题

问题根源

  1. 动态渲染的SPA页面:Uniswap信息站是React构建的单页应用,核心数据通过AJAX动态加载,直接获取page_source时可能内容还未渲染完成。
  2. 错误的无头模式参数:代码中--headlesss多了一个s,导致无头模式未正确启用;即使启用,未设置窗口大小也可能引发页面布局异常,元素无法正常渲染。
  3. 无效的元素定位方式:使用的sc-jKJlTe sc-hMqMXs sc-hSdWYo eJnjNO是CSS Modules生成的动态类名,每次部署都会变化,无法稳定定位元素。
  4. 错误的等待逻辑:WebDriverWait(driver, 20)仅声明了等待对象,但未指定等待条件(如元素可见),等同于未等待数据加载。

解决方案

1. 修正无头模式参数

将错误的--headlesss改为--headless=new(Chrome 112+推荐的新无头模式,兼容性更好),同时添加窗口大小参数避免布局异常:

options.add_argument('--headless=new')
options.add_argument('--window-size=1920x1080')

2. 实现正确的等待逻辑

通过WebDriverWait配合expected_conditions,等待目标元素加载完成后再获取页面源码,确保数据渲染完毕。

3. 换用稳定的元素定位方式

优先使用页面提供的data-testid属性(查看开发者工具可知,Volume、Fees、TVL的容器分别对应stat-card-volume、stat-card-fees、stat-card-tvl),这类属性专为测试/爬虫设计,稳定性远高于动态类名。

修改后的完整代码

'''
THIS CODE WILL BE USED TO EXTRACT ETHERIUM DATA FROM UNISWAP V3 SITE
'''
# import required files
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup as BSoup

# base url
eth_uniswap_url = 'https://info.uniswap.org/#/'

# function to get driver
def get_driver():
    options = Options()
    options.add_argument('--no-sandbox')
    options.add_argument('--headless=new')  # 修正无头模式参数
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--window-size=1920x1080')  # 添加窗口大小,避免布局异常
    
    webdriver_service = Service("D:\Software\Selenium WebDrivers\chrome_v107\chromedriver_win32\chromedriver.exe")
    driver = webdriver.Chrome(options=options, service=webdriver_service)
    return driver

# function to open site
def access_site(driver,url):
    driver.get(url)
    # 等待目标元素加载完成,确保数据渲染完毕
    WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.DATA_TEST_ID, "stat-card-volume"))
    )
    bs_Object = BSoup(driver.page_source, 'html.parser')
    return bs_Object

if __name__ == '__main__':
    print('We are going to create the driver')
    
    driver = get_driver()
    
    print('We are now going to access the page')
    
    site_access = access_site(driver, eth_uniswap_url)

    # 使用data-testid定位核心数据卡片,稳定性更高
    volume_card = site_access.find('div', {'data-testid': 'stat-card-volume'})
    fees_card = site_access.find('div', {'data-testid': 'stat-card-fees'})
    tvl_card = site_access.find('div', {'data-testid': 'stat-card-tvl'})

    # 提取数值和标签文本
    def extract_stat(card):
        if card:
            value = card.select_one('div.sc-hKgILt').text
            label = card.select_one('div.sc-hAZoDl').text
            return f"{label}: {value}"
        return "未找到对应数据"

    print(extract_stat(volume_card))
    print(extract_stat(fees_card))
    print(extract_stat(tvl_card))
    
    driver.quit()  # 关闭浏览器,释放资源

额外说明

  • 如果data-testid发生变化,可改用XPath根据文本定位,示例:
    volume_value = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'Volume')]/../div[1]"))).text
    
  • 确保ChromeDriver版本与本地Chrome浏览器版本完全匹配,避免兼容性报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:40:28