如何使用Selenium定位符合特定条件的元素并爬取网页数据?
解决Selenium爬取财报数据的标签定位问题
问题诊断
你的代码存在几个核心问题:
- 用
By.CSS_SELECTOR,'p'会抓取页面所有<p>标签,数据冗余且无关 By.CLASS_NAME,'sticky-col.first-col'写法错误:CLASS_NAME不支持多类名(空格分隔的多个class),需改用CSS选择器或XPATH- 缺少页面加载等待逻辑:点击"按季度"按钮后,页面数据是异步加载的,直接抓取会获取不到最新数据
修正后的代码
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 import pandas as pd # 初始化浏览器(注意:ChromeDriver需匹配你的Chrome版本,也可使用Service类替代executable_path) browser = webdriver.Chrome(executable_path="./chromedriver.exe") wait = WebDriverWait(browser, 10) # 设置10秒等待超时 url = 'https://24hmoney.vn/stock/HAG/financial-report' browser.get(url) # 点击"按季度"按钮(改用相对XPATH,避免绝对路径失效) btn_quarter = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(), 'Theo quý')]"))) btn_quarter.click() # 等待财报表格加载完成 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".sticky-col.first-col"))) # 抓取财报指标标题(正确定位多class元素) titles = browser.find_elements(By.CSS_SELECTOR, ".sticky-col.first-col") title_list = [title.text.strip() for title in titles if title.text.strip()] # 抓取对应季度数据(假设数据在标题相邻的td/p标签中,根据页面结构调整) data_rows = [] for title in titles: # 定位当前指标对应的所有季度数据单元格 data_cells = title.find_elements(By.XPATH, "./following-sibling::td//p") row_data = [cell.text.strip() for cell in data_cells if cell.text.strip()] data_rows.append(row_data) # 整理成DataFrame并保存 df = pd.DataFrame(data_rows, index=title_list).transpose() df.to_csv("HAG_financial_report.csv", index=False, encoding="utf-8-sig") browser.quit()
关键优化点
- 等待机制:用
WebDriverWait替代直接元素定位,确保页面元素加载完成后再操作,避免异步加载导致的空数据 - 元素定位:
- 按钮定位改用包含文本的相对XPATH,避免绝对路径因页面结构变动失效
- 多class元素用CSS选择器
.sticky-col.first-col定位,CLASS_NAME仅支持单个类名
- 数据清洗:过滤空文本,确保数据有效性
- 数据结构:将指标作为索引,季度数据作为列,更符合财报的阅读逻辑
内容的提问来源于stack exchange,提问作者Quốc Việt Đặng
相关产品推荐
相关产品推荐

