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

如何用Python的Selenium提取data-v-xxx,实现num值校验后获取venuen-name

问题解决:基于模块关联的元素定位方案

问题描述

我需要遍历所有class为num的元素,判断其文本值是否大于0;如果满足条件,就获取对应模块中venuen-name元素的文本。观察到同一模块的元素带有相同的data-v-<哈希值>属性,尝试通过提取这个哈希值来关联查找venuen-name,但多次尝试都失败了,求可行的解决方案。

DOM结构示例

<div data-v-3122d63c="" class="el-row chooseTime" data-v-012d0593="">
    <div data-v-3122d63c="" class="el-col el-col-5 el-col-xs-0">
        <img data-v-174fb000="" data-v-3122d63c=""
            src="https://lcsd-smartplay.oss-cn-hongkong.aliyuncs.com/pic/default_facility.jpeg" alt="smartplay"
            class="venuen-img">
    </div>
    <div data-v-3122d63c="" class="el-col el-col-9 el-col-xs-24">
        <h3 data-v-3122d63c="" class="venuen-name">foo</h3>
    </div>
    <div data-v-3122d63c="" class="el-col el-col-10 el-col-xs-24">
        <div data-v-3122d63c="" class="el-row">
            <div data-v-3122d63c="" class="site el-col el-col-24">boo</div>
            <div data-v-3122d63c="" class="el-col el-col-24 el-col-xs-24" style="padding: 2px 0px;">
                <div data-v-752ea580="" data-v-3122d63c="" class="facilities-date-list-box">
                    <div data-v-42c8b4a0="" data-v-752ea580="">
                        <div data-v-42c8b4a0="" class="smart-play-mobile">

                        </div><!----><!----><!---->
                        <div data-v-42c8b4a0="" class="smart-play-mobile-tablet">

                        </div>
                    </div>
                    <div data-v-752ea580="" class="facilities-date-list-hidden scroll-wrap-223-308">
                        <div data-v-752ea580="" class="facilities-date-list-scroll scroll-223-308">
                            <div data-v-752ea580="" class="facilities-date-list-item">
                                <div data-v-752ea580="" class="relative item-num-box-disable">
                                    <div data-v-752ea580="" class="time flex">yyy</div>
                                    <div data-v-752ea580="" class="num">0</div><!---->
                                </div>
                            </div>
                            <div data-v-752ea580="" class="facilities-date-list-item">
                                <div data-v-752ea580="" class="relative item-num-box-disable">
                                    <div data-v-752ea580="" class="time flex">xxx</div>
                                    <div data-v-752ea580="" class="num">0</div><!---->
                                </div>
                            </div>
                        </div>
                    </div>
                    <div data-v-42c8b4a0="" data-v-752ea580="">
                        <div data-v-42c8b4a0="" class="smart-play-mobile"></div><!----><!----><!---->
                        <div data-v-42c8b4a0="" class="smart-play-mobile-tablet"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

尝试过的代码

for element in driver.find_elements(By.CLASS_NAME, 'num'):
        if int(element.text) == 1:
            vue_hash = element.find_element(By.XPATH, "./ancestor::div[contains(@data-v-,'')]").text

解决方案

问题分析

你尝试的XPath写法有两处错误:

  1. contains(@data-v-,'')无法匹配属性名前缀为data-v-的元素,需要用starts-with(@attribute-name, 'prefix')语法
  2. 直接取.text是错误的,我们需要提取的是元素的data-v-xxx属性值,而非文本内容

另外,依赖data-v哈希值的方案稳定性较差——Vue重新打包后哈希值会变化,推荐直接基于模块容器定位。

方案一:基于模块容器直接定位(推荐)

每个设施模块的最外层是el-row chooseTime,直接向上定位这个容器,再在容器内查找venuen-name:

from selenium.common.exceptions import NoSuchElementException

for num_element in driver.find_elements(By.CLASS_NAME, 'num'):
    try:
        num_text = num_element.text.strip()
        if not num_text:
            continue
        num_value = int(num_text)
        if num_value > 0:
            # 定位当前num元素所在的模块容器
            module_container = num_element.find_element(By.XPATH, "./ancestor::div[contains(@class, 'chooseTime')]")
            # 在容器内获取venuen-name文本
            venuen_name = module_container.find_element(By.CLASS_NAME, 'venuen-name').text
            print(f"可用设施:{venuen_name}")
    except (ValueError, NoSuchElementException):
        # 处理文本转数字失败、元素不存在等异常
        continue

方案二:基于data-v属性关联定位

如果一定要依赖data-v属性,可按以下方式实现:

from selenium.common.exceptions import NoSuchElementException

for num_element in driver.find_elements(By.CLASS_NAME, 'num'):
    try:
        num_text = num_element.text.strip()
        if not num_text or int(num_text) <= 0:
            continue
        # 找到带有data-v前缀属性的最外层组件根节点
        component_root = num_element.find_element(By.XPATH, "./ancestor::div[starts-with(@data-v-, '')]")
        # 提取组件的data-v属性名(如data-v-3122d63c)
        data_v_attr = [attr.split('=')[0] for attr in component_root.get_attribute('outerHTML').split() if attr.startswith('data-v-')][0]
        # 通过data-v属性和class定位venuen-name
        venuen_name = component_root.find_element(By.XPATH, f".//h3[contains(@{data_v_attr}, '') and @class='venuen-name']").text
        print(f"可用设施:{venuen_name}")
    except (ValueError, NoSuchElementException, IndexError):
        continue

说明

  • 方案一不依赖Vue生成的data-v哈希值,仅使用业务定义的模块class,稳定性更强
  • 两种方案都加入了异常处理,避免因元素状态异常导致程序崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:54:49