Selenium网页爬取循环成功运行数次后无法正常提取数据问题
问题根因
你的代码出现偶发索引越界主要是4个核心问题导致的:
- 没有等待页面异步元素加载完成就提取数据:点击
tab_info标签后,accordion-content类的内容是异步渲染的,你没有加等待逻辑直接读取,经常会出现内容没加载完、读空/读不全的情况 - 数据提取逻辑强依赖固定索引:直接用
lst[1]、list_total[9]这种硬编码索引取值,只要某条数据缺字段(比如部分上报数据本身就没填坡度/坡向)、或者内容加载不全,直接触发索引越界 - 列表项遍历逻辑不稳定:通过硬修改XPath字符串第56位的数字实现遍历,只要页面结构稍有变化、或者分页/滚动导致列表项位置偏移,就会出现点错条目、读不到数据的问题
- 冗余浏览器实例冲突:代码开头启动了两次ChromeDriver,多余的实例可能造成资源冲突,也会影响稳定性
修复方案
1. 清理冗余代码
删除开头多余的谷歌页面启动逻辑,你不需要先打开谷歌页面,直接启动Lawis对应的浏览器实例即可。
2. 增加异步元素等待逻辑
读取accordion-content前,先等待所有对应类的元素加载完成,再读取内容:
# 替换你原来读取lst的那段逻辑 from selenium.common.exceptions import NoSuchElementException import time # 点击info tab后加等待 WebDriverWait(driver, 20).until(EC.presence_of_all_elements_located((By.XPATH, '//*[@class="accordion-content"]'))) # 加1秒缓冲避免渲染延迟,运行不稳定可以适当延长 time.sleep(1) lst = [] for elem in driver.find_elements_by_xpath('//*[@class="accordion-content"]'): text = elem.text.strip() if text: lst.append(text)
3. 替换硬索引提取逻辑,改用键值匹配取值
不要按索引取字段,改成按字段前缀匹配,哪怕缺字段也不会崩:
# 替换原来按索引取变量的逻辑 data_dict = {} # 把所有字段转成字典 for item in list_total: if ':' in item: key, value = item.split(':', 1) data_dict[key.strip()] = value.strip() # 取值的时候如果缺字段就填空字符串 observation_date = data_dict.get('Observation date', '') reporting_date = data_dict.get('Reporting Date', '') name = data_dict.get('Name', '') email = data_dict.get('e-mail', '') profile_id = data_dict.get('Profile ID', '') place = data_dict.get('Place', '') region = data_dict.get('Region', '') location = data_dict.get('Location', '') elevation = data_dict.get('Elevation', '') incline = data_dict.get('Incline', '') aspect = data_dict.get('Aspect', '')
4. 替换不稳定的列表遍历逻辑
不要硬改XPath的位置,直接先获取所有列表项的元素列表,再逐个遍历,比硬改XPath可靠得多:
# 进入列表页后先获取所有可点击的列表项 list_items = WebDriverWait(driver, 20).until(EC.presence_of_all_elements_located((By.XPATH, '/html/body/div/main/div[2]/div[2]/div[1]/table/tbody/tr'))) # 遍历前15条数据,对应你原来的tobechanged_index <16的逻辑 for item in list_items[:15]: # 滚动到当前元素可见再点击,避免滚动导致的点击失效 driver.execute_script("arguments[0].scrollIntoView();", item) WebDriverWait(driver, 10).until(EC.element_to_be_clickable(item)).click() # 后面接你原来的读取info tab、提取数据的逻辑
5. 加异常捕获兜底
给单次条目的提取逻辑加try-except捕获,单条数据读失败跳过即可,不会导致整个程序崩溃:
# 遍历逻辑里加异常捕获 for item in list_items[:15]: try: # 你原来的单条数据提取逻辑全放这里 except Exception as e: print(f"第{list_items.index(item)+1}条数据提取失败,错误:{e}") # 可以跳过当前条目继续跑 continue
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

