使用Python Selenium爬取爱尔兰无家可归人数图表数据遇阻
解决Selenium爬取爱尔兰无家可归人数图表数据的问题
嘿,我帮你捋捋为啥你之前的XPath定位失败,再给你俩靠谱的解决方案~
首先,你遇到的问题大概率是因为这个图表是JavaScript动态渲染的(比如用Highcharts这类库生成),页面加载后元素不会立刻出现在DOM里,而且你用的//*[@id='chart']/div[7]这种固定索引的XPath太脆弱了——只要页面结构稍微调整,这个定位就失效了。
下面给你两种可行的解决办法:
方法一:直接通过JavaScript获取图表数据源(最可靠)
这类网站的图表基本都是Highcharts生成的,页面里会有Highcharts的实例,直接调用它的API拿数据比定位DOM元素靠谱多了,代码示例:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://www.focusireland.ie/resource-hub/latest-figures-homelessness-ireland/") # 先等图表容器加载完成,确保Highcharts实例已初始化 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "chart")) ) # 执行JavaScript获取目标数据 target_value = driver.execute_script(""" // 获取页面上的第一个Highcharts实例(就是目标图表) const chart = Highcharts.charts[0]; // 拿到图表的所有数据点 const dataPoints = chart.series[0].data; // 遍历找到category为Jul-14的数据点,返回它的y值(就是人数) let result = null; dataPoints.forEach(point => { if (point.category === 'Jul-14') { result = point.y; } }); return result; """) print(f"Jul-14对应的无家可归人数:{target_value}") # 会输出3258 driver.quit()
这个方法的好处是完全不依赖DOM结构,哪怕页面更新,只要图表的数据源逻辑不变,就能拿到正确的数据,而且速度更快。
方法二:改进元素定位方式(如果不想用JS)
如果你坚持要通过定位DOM元素来获取数据,可以用更精准的选择器,同时确保元素完全加载:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://www.focusireland.ie/resource-hub/latest-figures-homelessness-ireland/") # 等待所有数据标签加载完成 WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".highcharts-data-label")) ) # 遍历所有数据标签,找到对应Jul-14的数值 data_labels = driver.find_elements(By.CSS_SELECTOR, ".highcharts-data-label") for label in data_labels: # 通过JS获取这个标签关联的数据点信息 point_info = driver.execute_script("return arguments[0].point;", label) if point_info["category"] == "Jul-14": print(f"Jul-14对应的数值:{point_info['y']}") break driver.quit()
额外注意事项
- 一定要用
WebDriverWait等待元素加载,不要直接用time.sleep(),前者更高效且稳定 - 避免使用固定索引的XPath/CSS选择器,这类选择器很容易因为页面更新失效
- 如果遇到反爬限制,可以尝试添加
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")滚动到图表位置,或者更换User-Agent
内容的提问来源于stack exchange,提问作者Student of the Digital World
相关产品推荐
相关产品推荐

