Python Webscraper无报错但不执行后续逻辑问题求助
Selenium+BeautifulSoup爬虫问题排查:仅执行搜索,后续逻辑无响应
问题描述
我用Selenium和BeautifulSoup编写的Python爬虫运行无报错,但仅完成自动搜索步骤,识别并点击“BREVES COMUNICAÇÕES”链接、爬取演讲内容的逻辑完全未执行。和同事测试均出现该情况,已排查HTML定位、代码缩进,仍未解决。代码由ChatGPT生成,需要除等待函数外的排查思路与解决建议。
核心排查思路与解决建议
1. 代码执行流错误(最关键)
原代码中,搜索循环的driver.back()直接回到初始搜索页,而链接识别、爬取的代码块完全在for循环外部,导致后续逻辑在错误的页面上下文(初始搜索页)执行,自然找不到结果页的元素。
- 解决:将链接识别、爬取的所有代码移入for循环内部,放在
time.sleep(60)之后、driver.back()之前,确保在搜索结果页执行后续操作。
2. XPath定位逻辑偏差
- tbody陷阱:很多动态生成的表格中,浏览器会自动添加
<tbody>标签,但实际网页源码中不存在,原XPath中的tbody会导致定位失败。修改XPath为://*[@id="content"]/div/table/tr/td[3](去掉tbody)。 - 列表操作错误:
find_elements()返回的是元素列表,直接调用click()会报错。需先判断列表是否非空,再取第一个元素操作,例如:link_elements = fase.find_elements(By.XPATH, '.following-sibling::td/a') if link_elements: link_elements[0].click() - 兄弟节点定位错误:原代码中
.following-sibling::td[4]可能不符合实际页面结构,需检查结果页HTML,确认目标链接所在的td是td[3]的第几个兄弟节点(通常是紧邻的下一个td,可简化为.following-sibling::td)。
3. 会话一致性问题
原代码用requests.get()单独请求链接,但requests不会携带Selenium中的Cookie,可能导致无法访问需要权限的内容。
- 解决:直接用Selenium获取当前页面的源码:
若链接在新窗口打开,需先切换窗口:soup = BeautifulSoup(driver.page_source, 'html.parser')if len(driver.window_handles) > 1: driver.switch_to.window(driver.window_handles[-1])
4. 异常捕获无效
原代码的try块仅覆盖部分逻辑,且find_elements()不会抛出NoSuchElementException(找不到元素时返回空列表),导致异常无法被捕获。
- 解决:扩展异常捕获范围,覆盖
ElementNotInteractableException、StaleElementReferenceException等常见Selenium异常;同时在遍历前检查元素列表是否为空:fases = driver.find_elements(By.XPATH, '//*[@id="content"]/div/table/tr/td[3]') if not fases: print("未找到任何阶段元素") continue
5. 文本匹配准确性问题
页面文本可能存在大小写、空格或特殊字符差异,导致'BREVES COMUNICAÇÕES' in fase.text匹配失败。
- 解决:统一转为大写/小写后匹配:
同时添加调试输出,打印每个if 'BREVES COMUNICAÇÕES' in fase.text.strip().upper():fase.text的实际内容,确认匹配条件是否正确。
修正后的完整代码示例
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.common.exceptions import NoSuchElementException, ElementNotInteractableException from selenium.webdriver.common.by import By from bs4 import BeautifulSoup edge_driver_path = 'C:/Users/IIIIIINGRID/OneDrive/Área de Trabalho/projetoretorica/edgedriver_win64/msedgedriver.exe' driver = webdriver.Edge(executable_path=edge_driver_path) driver.get('https://www.camara.leg.br/internet/sitaqweb/pesquisaDiscursos.asp') termos_de_pesquisa = ["Nikolas Ferreira", "Rosângela Moro", "Zé Neto", "Alice Portugal", "Sidney Leite", "Silvia Waiãpi", "Erika Kokay", "Geraldo Resende", "Marcel Van Hattem", "Fernanda Melchionna"] for termo in termos_de_pesquisa: # 执行搜索操作 pesquisa = driver.find_element(By.NAME, "txOrador") pesquisa.clear() pesquisa.send_keys(termo) pesquisa.send_keys(Keys.RETURN) time.sleep(5) # 可后续替换为显式等待优化 # 处理搜索结果页 discurso_encontrado = False try: # 定位所有阶段列,去掉浏览器自动生成的tbody fases = driver.find_elements(By.XPATH, '//*[@id="content"]/div/table/tr/td[3]') print(f"\n=== 处理搜索关键词: {termo} ===") print(f"找到{len(fases)}个阶段条目") if not fases: print("未找到任何阶段内容,跳过") driver.back() time.sleep(2) continue for fase in fases: fase_texto = fase.text.strip().upper() print(f"当前阶段: {fase_texto}") if 'BREVES COMUNICAÇÕES' in fase_texto: # 获取相邻td中的链接元素 link_elementos = fase.find_elements(By.XPATH, '.following-sibling::td/a') if link_elementos: link_elementos[0].click() print("成功点击演讲链接") # 处理新窗口(如果链接在新窗口打开) if len(driver.window_handles) > 1: driver.switch_to.window(driver.window_handles[-1]) # 解析当前页面内容 soup = BeautifulSoup(driver.page_source, 'html.parser') discurso_paragrafo = soup.find('p') if discurso_paragrafo: discurso_texto = discurso_paragrafo.get_text() # 提取第二个'-'之后的内容 def encontrar_segundo_hifen(texto): contador = 0 for indice, char in enumerate(texto): if char == "-": contador += 1 if contador == 2: return indice return -1 indice_hifen = encontrar_segundo_hifen(discurso_texto) if indice_hifen != -1: print("\n演讲内容:") print(discurso_texto[indice_hifen:]) else: print("未找到第二个'-'字符,无法截取内容") else: print("未找到包含演讲内容的p标签") # 切回原窗口并关闭新窗口(如果存在) if len(driver.window_handles) > 1: driver.close() driver.switch_to.window(driver.window_handles[0]) discurso_encontrado = True break else: print("当前阶段未找到演讲链接") else: print("当前阶段非目标类型,跳过") if not discurso_encontrado: print(f"未找到{termo}的BREVES COMUNICAÇÕES类型演讲") except (NoSuchElementException, ElementNotInteractableException) as e: print(f"处理过程中出错: {str(e)}") # 返回搜索页,准备下一次搜索 driver.back() time.sleep(2) driver.quit()
内容的提问来源于stack exchange,提问作者Beatriz Alves
相关产品推荐
相关产品推荐

