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

Selenium动态爬取ESCO技能页面:展开按钮定位问题排查

ESCO技能页面动态展开爬取问题修复

问题说明

尝试爬取ESCO技能分类页面(动态加载),需要展开所有“+”按钮以获取完整数据,但全量展开时触发超时错误,怀疑是XPATH定位语句存在问题。

原代码核心问题

原XPATH存在语法错误:末尾多了一个多余的],导致无法正确定位元素:

# 错误XPATH,多了闭合的]
expand_buttons = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//div[@class='classification_item cont_change_right hierarchy_active']]//span[@class='api_hierarchy has-child-link']")))

此外,原逻辑一次性查找所有按钮并点击,容易因DOM频繁更新触发StaleElementReferenceException,且未判断按钮是否已经展开,重复点击会导致无效操作,进而触发超时。

修复方案

  1. 修正XPATH语法错误
  2. 每次仅定位当前可见且未展开的按钮(通过按钮文本判断)
  3. 分批点击并等待DOM加载稳定,避免一次性发送过多请求
  4. 优化循环逻辑,直到没有可展开按钮为止

修正后的完整代码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
from bs4 import BeautifulSoup
import json

# 初始化浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("http://data.europa.eu/esco/skill/f8c676de-c871-424f-9a65-77059d07910a")
wait = WebDriverWait(driver, 20)

def click_expand_buttons():
    while True:
        try:
            # 修正XPATH,定位所有未展开的"+"按钮(仅匹配当前可见的)
            expand_buttons = wait.until(EC.visibility_of_all_elements_located(
                (By.XPATH, "//div[@class='classification_item cont_change_right hierarchy_active']//span[@class='api_hierarchy has-child-link' and text()='+']")
            ))
            
            if not expand_buttons:
                break
            
            # 逐个点击,每次点击后等待DOM稳定
            for idx, button in enumerate(expand_buttons):
                try:
                    # 用JS点击避免元素遮挡问题
                    driver.execute_script("arguments[0].click();", button)
                    # 等待当前节点加载完成,减少服务器请求压力
                    time.sleep(0.5)
                    # 每点击5个按钮重新查找一次,避免元素过期
                    if idx % 5 == 0:
                        break
                except StaleElementReferenceException:
                    break
        except TimeoutException:
            # 超时说明没有更多可展开按钮
            break

# 执行展开操作
click_expand_buttons()

# 提取页面数据
html_source = driver.page_source
soup = BeautifulSoup(html_source, 'html.parser')

skills = []
# 根据实际页面结构调整选择器
for skill_element in soup.find_all("div", class_="skill-class"):
    skill_name = skill_element.find("h2", class_="skill-name").text.strip() if skill_element.find("h2", class_="skill-name") else "无名称"
    skill_description = skill_element.find("p", class_="skill-description").text.strip() if skill_element.find("p", class_="skill-description") else "无描述"
    skills.append({"name": skill_name, "description": skill_description})

# 保存数据到JSON
with open("/Users/federiconutarelli/Desktop/escodata/expanded_esco_skills_page.json", "w", encoding="utf-8") as json_file:
    json.dump(skills, json_file, indent=4, ensure_ascii=False)

driver.quit()

关键优化点

  • XPATH修正:移除多余的],并增加text()='+'过滤已展开的按钮
  • 分批点击:每点击5个按钮就重新查找,避免元素过期
  • 等待策略:每次点击后短时间等待,降低服务器请求频率,避免超时
  • 容错处理:增加对TimeoutException的捕获,确保循环正常退出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:07:35