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

Selenium抓取非可视区域元素文本为空的解决方法

问题根因

空值问题确实和元素可视状态直接相关:

  • Selenium的.text属性严格遵循浏览器可见文本规则,仅会返回当前处于可视区域、未被CSS属性(visibility:hidden/display:none/偏移出视口)隐藏的元素文本。Swiper轮播组件默认会将非激活状态的slide通过CSS transform偏移到可视区域外,部分配置下还会对未激活slide的子节点做隐藏处理,这类元素调用.text只能拿到空字符串。
  • 添加--start-maximized参数后返回全空列表,是因为窗口尺寸变化触发Swiper执行响应式重算,轮播内容的渲染时机发生变化,页面加载完成后立即读取元素时,促销卡片的文本还未完成DOM注入。
  • Swiper开启循环模式时会自动生成带有swiper-slide-duplicate类名的占位节点,这些节点本身没有真实业务内容,也会被计入swiper-slide类元素的匹配结果。
修复方案

不需要将元素滚动到可视区域——这类操作会触发轮播切换动画,反而会提升抓取的不稳定性,直接按以下逻辑修改即可:

  • 替换文本取值逻辑:通过执行Javascript读取DOM节点的textContent属性,该属性直接从DOM树获取文本内容,完全不受元素可视状态、CSS隐藏规则的影响。
  • 增加显式等待:不要仅依赖全局隐式等待,等首个促销卡片的内容渲染完成后再开始批量抓取,避免拿到未完成渲染的空节点。
  • 过滤无效节点:遍历过程中跳过Swiper生成的重复占位slide,最终结果再过滤一遍空值项,避免无效数据。
  • 固定启动窗口尺寸:避免响应式重算导致的渲染时机错乱问题。
修正后可运行代码
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def get_promotion():
    '''
    Web scraping process to get Smiles promotion
    '''     
    promotions = []
    chrome_options = Options()
    chrome_options.add_argument("--disable-notifications")
    # 固定窗口尺寸,避免触发Swiper响应式重算
    chrome_options.add_argument("--window-size=1366,768")
    driver = webdriver.Chrome(options=chrome_options)
    driver.implicitly_wait(10)
    driver.get('https://www.smiles.com.br/home')

    # 显式等待促销卡片内容渲染完成,最长等待15秒
    WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, '.swiper-slide h3'))
    )

    site_promotion = driver.find_elements(By.CLASS_NAME, 'swiper-slide')  
    for promotion in site_promotion:
        # 过滤Swiper循环模式生成的重复占位节点
        slide_class = promotion.get_attribute('class')
        if 'swiper-slide-duplicate' in slide_class:
            continue
        # 定位各字段元素
        destination_el = promotion.find_element(By.XPATH, './a/div/div/h3')
        origin_el = promotion.find_element(By.XPATH, './a/div/div/h4/span[2]')
        diamont_value_el = promotion.find_element(By.XPATH, './a/div/div/div/span[2]/p[3]')
        normal_value_el = promotion.find_element(By.XPATH, './a/div/div/div/span[2]/p[2]')

        # 通过JS读取textContent,无视口可见要求,同时去除首尾空白字符
        promotions.append(
            { 
                'destination': driver.execute_script('return arguments[0].textContent.trim()', destination_el),
                'origin': driver.execute_script('return arguments[0].textContent.trim()', origin_el),
                'diamont_value': driver.execute_script('return arguments[0].textContent.trim()', diamont_value_el),
                'normal_value': driver.execute_script('return arguments[0].textContent.trim()', normal_value_el),
            }
        )
    # 二次过滤空内容的无效条目
    promotions = [item for item in promotions if item['destination']]
    driver.quit()
    return promotions

内容的提问来源于stack exchange,提问作者Gabriel Braico Dornas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:42:22