最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何完整展开并抓取ESCO网站中S-skills分类下的全部层级内容
时间:2026-09-06 15:05:49 编辑:袖梨 来源:一聚教程网
本文介绍使用Selenium精准定位并递归展开ESCO正式S-skills分类下所有可折叠节点(“+”按钮),避免重复点击与页面重载问题,最终获取完整展开后的HTML源码。
本文介绍使用Selenium精准定位并递归展开ESCO正式S-skills分类下所有可折叠节点(“+”按钮),避免重复点击与页面重载问题,最终获取完整展开后的HTML源码。
在抓取类似ESCO(European Skills, Competences, Qualifications and Occupations)这类具有树状层级结构的 时,关键挑战在于:仅对目标分类(如 S - skills)执行深度展开,而非全局遍历所有节点。原始代码中使用 .api_hierarchy.has-child-link 全局选择器,会导致反复点击已展开/已失效的按钮(引发 StaleElementReferenceException),甚至陷入无限循环——因为每次点击都会动态插入新子节点,同时旧DOM元素被替换,原有元素引用失效。
要精准聚焦于 S - skills 分类,需采用上下文限定的选择策略:先定位到 S - skills 的父容器(即包含 <a> S - skills</a> 的 .main_item.classification_item 区块),再在其内部查找所有可展开的 span.api_hierarchy.has-child-link 元素。XPath 是实现该层级约束最直观的方式:
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.chrome.service import Servicefrom webdriver_manager.chrome import ChromeDriverManagerimport timedriver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))driver.get("https://esco.ec.europa.eu/en/classification/skill_main")driver.implicitly_wait(10)wait = WebDriverWait(driver, 20)def expand_s_skills_only():"""递归展开 S-skills 下所有可折叠节点,直至无新 '+' 按钮出现"""while True:# ✅ 精准定位:只在 'S - skills' 所在分类区块内查找展开按钮expand_buttons = wait.until(EC.presence_of_all_elements_located((By.XPATH,"//div[@class='main_item classification_item' and .//a[text()='S - skills']]//span[@class='api_hierarchy has-child-link']")))if not expand_buttons:print("✅ 所有 S-skills 层级已完全展开")break# 逐个点击(使用 execute_script 避免点击拦截)for i, button in enumerate(expand_buttons):try:driver.execute_script("arguments[0].click();", button)time.sleep(0.8)# 短暂等待动态内容加载(避免过快导致遗漏)except (StaleElementReferenceException, Exception) as e:# 当前按钮已失效 → 跳过,继续处理列表中剩余有效按钮continue# ⚠️ 关键:每次循环后强制刷新元素引用 —— 不依赖缓存列表# (因 DOM 已变更,原 expand_buttons 列表不可复用)# 执行展开expand_s_skills_only()# 获取完整展开后的页面源码html_source = driver.page_source# 保存结果(建议添加时间戳或版本标识)output_path = "/Users/federiconutarelli/Desktop/escodata/expanded_s_skills_full.html"with open(output_path, "w", encoding="utf-8") as f:f.write(html_source)print(f"? 已保存展开后HTML至:{output_path}")driver.quit()
注意事项与优化建议:
- ✅ XPath 表达式说明:
//div[@class='main_item classification_item' and .//a[text()='S - skills']]确保只匹配包含S - skills链接的顶级分类容器;后续//span[@class='api_hierarchy has-child-link']在其子树中查找,天然实现作用域隔离。 - ⚠️ 避免
StaleElementReferenceException:不在循环中复用已获取的expand_buttons列表,而是每次重新wait.until(...)查询最新 DOM,确保元素始终“鲜活”。 - ⏱️ 合理设置等待与延迟:
time.sleep(0.8)为经验性缓冲值,可依网络速度微调;若页面响应慢,建议改用WebDriverWait等待特定子节点出现(如新.classification_item加载完成)。 - ? 验证展开完整性:抓取后可用
BeautifulSoup解析 HTML,检查<span class="api_hierarchy has-child-link">是否在S - skills区域内彻底消失,作为自动化校验步骤。
通过以上方法,即可稳定、可控地获取 S-skills 分类下完整的、扁平化展开的 HTML 结构,为后续解析技能ID、名称、层级关系等结构化数据奠定可靠基础。