Selenium循环点击下一个按钮爬取数据后回退页面的问题求助
问题原因&解决方法
核心错误点
- 递归调用逻辑混乱:
name()、phone()、back()三个函数互相嵌套调用,完全脱离了for循环的控制,循环变量i根本不会按预期顺序递增,被递归逻辑打乱了执行顺序。 - 函数定义位置错误:三个函数都定义在for循环内部,每次循环都会重复定义函数,还会引发变量作用域异常。
- XPath索引起始值不匹配:
range(length)生成的i是从0开始计数的,但XPath的节点索引从1开始,你传入变量时实际执行的是(//a[@class = 'button'])[0],这个路径不存在,自然失效。 - 页面回退后元素过期:每次返回列表页后,整个页面DOM都会重新渲染,你进入页面前统计的按钮长度
length对应的元素已经是陈旧元素,动态渲染的场景下还会直接抛出异常。 - 逻辑冲突冗余:你提前单独点击了一次第一个按钮,和后续for循环的逻辑完全冲突,BeautifulSoup相关代码没有实际作用,可以删除。
修正后代码
import time from selenium import webdriver from selenium.webdriver.common.by import By from bs4 import BeautifulSoup # 初始化driver代码自行补充 driver = webdriver.Chrome() url ='https://www.healthgrades.com/family-marriage-counseling-directory' driver.minimize_window() driver.get(url) time.sleep(5) # 先统计当前页所有按钮的总数量 button_list = driver.find_elements(By.XPATH, "//a[@class = 'button']") length = len(button_list) for i in range(1, length+1): # 每次循环直接定位第i个按钮,XPath从1开始计数 current_btn = driver.find_element(By.XPATH, f"(//a[@class = 'button'])[{i}]") current_btn.click() time.sleep(3) # 等待详情页加载,可替换为显式等待 # 爬取姓名 for name in driver.find_elements(By.CSS_SELECTOR, "h1[data-qa-target='ProviderDisplayName']"): print(name.text) # 爬取手机号 for phone in driver.find_elements(By.CSS_SELECTOR, "a[class='click-to-call-button-secondary hg-track mobile-click-to-call']"): print(phone.text) # 返回列表页,等待页面加载完成 driver.execute_script("window.history.go(-1)") time.sleep(3) # 同样可替换为显式等待优化稳定性 driver.quit()
额外优化建议
- 把代码里的固定等待
time.sleep()替换为Selenium的显式等待WebDriverWait,可以大幅提升爬取效率和稳定性,避免页面没加载完成就执行下一步操作的问题。 - 如果列表页有分页,可以在当前页所有按钮处理完成后加一个点击下一页的逻辑,循环处理多页数据。
内容的提问来源于stack exchange,提问作者Adrian Reichert
相关产品推荐
相关产品推荐

