Selenium爬取flex布局DIV中asset_id属性值失败求助
问题描述
使用Selenium爬取页面https://www.jpg.store/collection/hungrycowsbymuesliswap?tab=items时,无法获取标记为flex的DIV中的数据,目标是提取其中标记为黄色的asset_id属性值。当前代码仅能定位到目标值上层的DIV,若在XPath中添加一个div节点则抛出如下异常:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//body/div/div[1]/main/div[2]/div/section/div/div[2]/div/div/div[1]/div"}
原代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") headless driver = webdriver.Chrome(options=chrome_options) url = 'https://www.jpg.store/collection/hungrycowsbymuesliswap?tab=items' driver.set_page_load_timeout(4) driver.get(url) element = driver.find_element(By.XPATH, "//body/div/div[1]/main/div[2]/div/section/div/div[2]/div/div/div[1]") print(element.get_attribute('outerHTML'))
解决思路与方案
问题根源主要是绝对XPath稳定性差、页面动态加载未完成就执行定位,以及原代码存在语法错误。以下是针对性解决步骤:
1. 修正语法错误
原代码中chrome_options.add_argument("--disable-gpu")后多余的headless字符串会导致语法报错,需移除。
2. 使用显式等待确保元素加载
页面采用动态渲染,仅设置页面加载超时无法保证目标元素已渲染完成,改用WebDriverWait显式等待元素出现。
3. 采用健壮的相对XPath定位
放弃脆弱的绝对路径,基于元素的flex类属性和asset_id属性特征进行定位,避免页面结构小范围变动导致定位失效。
修改后的代码(提取单个asset_id)
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=chrome_options) url = 'https://www.jpg.store/collection/hungrycowsbymuesliswap?tab=items' driver.get(url) # 显式等待目标元素,最长等待10秒 wait = WebDriverWait(driver, 10) # 定位包含asset_id属性的flex容器 target_element = wait.until(EC.presence_of_element_located( (By.XPATH, "//div[contains(@class, 'flex') and @asset_id]") )) # 提取asset_id属性值 asset_id = target_element.get_attribute('asset_id') print(f"提取到的asset_id: {asset_id}") driver.quit()
提取所有asset_id的代码
如果需要页面中所有符合条件的asset_id,可使用find_elements方法:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=chrome_options) url = 'https://www.jpg.store/collection/hungrycowsbymuesliswap?tab=items' driver.get(url) wait = WebDriverWait(driver, 10) # 定位所有包含asset_id的flex div target_elements = wait.until(EC.presence_of_all_elements_located( (By.XPATH, "//div[contains(@class, 'flex') and @asset_id]") )) # 遍历输出所有asset_id for idx, elem in enumerate(target_elements, 1): print(f"第{idx}个asset_id: {elem.get_attribute('asset_id')}") driver.quit()
关键说明
- 显式等待:确保元素在DOM中存在后再执行操作,彻底解决动态加载导致的元素未找到问题。
- 相对XPath:基于元素自身特征定位,比绝对路径更稳定,即使页面局部结构变化也能正常定位。
- 无语法错误:修正原代码中多余的字符串,保证代码可正常运行。
内容的提问来源于stack exchange,提问作者motylas
相关产品推荐
相关产品推荐

