Python网页爬虫:解决慢网站固定Sleep引发的报错问题
解决Python爬虫因网站速度波动导致的加载报错问题
你当前用固定sleep()等待页面加载,遇到网站速度不稳定时经常因为元素未加载完成报错,核心问题是固定等待时间无法适配页面加载的波动。下面是具体的解决方案和修改后的代码:
核心优化方案
1. 改用Selenium显式等待
Selenium提供的WebDriverWait配合expected_conditions可以实现条件触发式等待——直到目标元素满足指定条件(比如可见、可点击)才继续执行,超时才抛出异常。这完全替代了固定sleep(),既保证等待足够时间,又不会浪费多余时间。
常用的等待条件:
EC.presence_of_element_located():元素存在于DOM中EC.visibility_of_element_located():元素可见EC.element_to_be_clickable():元素可点击
2. 增加异常捕获与重试
针对元素偶尔加载失败的情况,给关键操作加上异常捕获,配合简单的重试逻辑,能有效提升爬虫稳定性。
3. 可选:设置全局隐式等待
显式等待是针对单个元素的精准等待,隐式等待是全局设置——告诉WebDriver在找不到元素时,最多等待指定时间再抛出异常,可以作为显式等待的补充。
修改后的完整代码
from bs4 import BeautifulSoup from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, NoSuchElementException import pandas as pd import json from time import sleep # 初始化浏览器配置 options = Options() options.headless = True navegador = webdriver.Firefox(options=options) # 可选:设置全局隐式等待,最多等待10秒 navegador.implicitly_wait(10) # 定义显式等待对象,超时时间设为30秒(可根据网站调整) wait = WebDriverWait(navegador, 30) try: link = '****************************' navegador.get(link) # 等待用户名输入框可见并输入 usuario = wait.until(EC.visibility_of_element_located((By.ID, 'ctl00_ctl00_Content_Content_txtLogin'))) usuario.send_keys('****************************') # 等待密码输入框可见并输入 senha = wait.until(EC.visibility_of_element_located((By.ID, 'ctl00_ctl00_Content_Content_txtSenha'))) senha.send_keys('****************************') # 等待登录按钮可点击并点击 botaologin = wait.until(EC.element_to_be_clickable((By.ID, 'ctl00_ctl00_Content_Content_btnEnviar'))) botaologin.click() # 等待登录后的菜单元素可点击(替换原来的sleep(40)) agendamento = wait.until(EC.element_to_be_clickable((By.ID, 'ctl00_ctl00_Content_Content_TreeView2t8'))) agendamento.click() # 等待日期链接可点击并点击 selecdia = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[title='06 de dezembro']"))) selecdia.click() # 等待下拉框可点击并选择 selecterminal = wait.until(EC.element_to_be_clickable((By.ID, 'ctl00_ctl00_Content_Content_ddlVagasTerminalEmpresa'))) selecterminal.click() select = Select(wait.until(EC.visibility_of_element_located((By.ID, 'ctl00_ctl00_Content_Content_ddlVagasTerminalEmpresa')))) select.select_by_index(1) # 等待目标div加载完成 buscalink = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="divScroll"]'))) teste3 = buscalink.get_attribute('innerHTML') # 解析页面内容 soup = BeautifulSoup(teste3, "html.parser") Vagas = soup.find_all(title="Vaga disponível.") temp = [] for i in Vagas: on_click = i.get('onclick') temp.append(on_click) df = pd.DataFrame(temp) df.to_csv('test.csv', mode='a', header=False, index=False) except TimeoutException: print("页面加载超时,请检查网络或延长等待时间") except NoSuchElementException: print("未找到指定元素,请检查元素定位是否正确") finally: # 无论成功失败,都关闭浏览器 navegador.quit()
代码说明
- 所有固定
sleep()都替换成了显式等待,确保元素满足条件后才执行下一步 - 增加了异常捕获,处理超时和元素找不到的情况,避免程序直接崩溃
- 加入了
navegador.quit()在finally块中,确保浏览器资源被正确释放 - 全局隐式等待作为补充,处理一些未用显式等待的元素查找场景
内容的提问来源于stack exchange,提问作者Alexandre Rodrigues
相关产品推荐
相关产品推荐

