Selenium爬取数据后向sqlite插入单列数据失败报StaleElementReferenceException错
错误原因与修复方案
1 初始StaleElementReferenceException报错原因
你第一次代码运行报错,是因为Selenium获取到的Example1/Example2/Example3都是WebElement对象,这类对象绑定了对应页面的DOM节点。你每次调用driver.get跳转到新页面后,前一个页面的DOM会被销毁,之前获取的WebElement就变成了无效的过时引用。
你虽然在爬取时打印过一次.text属性,但后续组装Values参数时又重新调用了一次.text,此时元素已经失效,所以触发了这个异常。另外你的driver.close没有加括号,本质是引用了方法对象而非执行关闭操作,不过这不是核心报错原因。
2 调整后代码的遗留问题
你提前把文本存到SerieA_text这类变量的操作,已经解决了元素过时的问题,但现在的问题出在SQLite的executemany参数格式错误:executemany要求传入的参数是可迭代的元组序列,每一个元组对应一行要插入的数据。你现在写的Values = ((SerieA_text), (SerieB_text), ...)本质是一个普通的字符串元组,单括号包裹字符串没有加逗号的情况下,不会被识别为单元素元组,执行时会出错。
修复方法
快速修复
只需要修改Values的构造格式,给每个字符串后加逗号,生成单元素元组即可:
# 每个元素后加逗号,才会被识别为单元素元组 Values = ((SerieA_text,), (SerieB_text,), (SerieC_A_text,), (SerieC_B_text,), (SerieC_C_text,), (SerieD_I_text,), (SerieD_H_text,), (PremierLeague_text,), (Championship_text,), (Liga_text,), (Bundesliga_text,), (Ligue1_text,)) sqlite_insert_query = 'INSERT INTO ARCHIVIO_Campionati (Nome_Campionato) VALUES (?);' count = cursor.executemany(sqlite_insert_query, Values)
优化写法
避免重复写大量冗余的爬取代码,可以用循环统一处理:
import sqlite3 from selenium import webdriver driver = webdriver.Chrome() # 按顺序存入所有要爬取的链接 crawl_links = [ "Serie A的链接", "Serie B的链接", "Serie C - Gir A的链接", # 剩余其他所有链接按顺序填入 ] insert_params = [] for link in crawl_links: driver.get(link) element = driver.find_element_by_class_name("teamHeader__name") text = element.text print(text) insert_params.append((text,)) # 直接构造executemany需要的单元素元组格式 # 数据库写入 con = sqlite3.connect('/home/mypc/Scrivania/aaaaa/Database.db') cursor = con.cursor() sqlite_insert_query = 'INSERT INTO ARCHIVIO_Campionati (Nome_Campionato) VALUES (?);' cursor.executemany(sqlite_insert_query, insert_params) con.commit() print("成功插入记录数:", cursor.rowcount) cursor.close() driver.quit() # 所有操作完成后统一关闭驱动即可,不需要每次跳转页面关标签
内容的提问来源于stack exchange,提问作者Frederick Man
相关产品推荐
相关产品推荐

