SQLite行迭代时get_tm_windows_access函数重复执行4次问题求助
问题原因分析
你遇到的重复调用问题其实很直观:在处理每一行船舶数据时,你多次调用了get_tm_windows_access函数——代码里先是单独调用了1次,然后在INSERT语句的字典参数里,又为了获取4个不同的返回值分别调用了4次,总共5次调用(你看到4次输出可能是某次调用没触发print(acces_code)?或者那个单独的调用是测试代码)。
每次调用这个函数都会完成一整套流程:请求页面、处理验证码、提交表单、解析结果,这不仅会重复打印你看到的内容,还会浪费大量网络资源,拖慢整个程序的运行速度。
解决方法
核心思路是:只调用一次get_tm_windows_access函数,把返回的结果存储到一个变量中,之后所有需要用到该结果的地方都直接从这个变量里提取。
修改后的代码片段如下:
def get_ship_tm_window(): # connect to database conn = sqlite3.connect('PSC.sdb') # create cursor c = conn.cursor() f = conn.cursor() c.execute("DELETE FROM 'inspections tm'") conn.commit() with requests.Session() as s: # 优化:把header设置移到循环外,避免重复设置 date_from = datetime.now() - relativedelta(months=36) date_to = datetime.now() header = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.', 'Cookies': 'PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx'} s.headers.update(header) for row in c.execute("SELECT * FROM ships ORDER BY ISM"): print(row) ship_imo = row[1] print(ship_imo) # 关键:仅调用一次函数,保存返回结果 tm_data = get_tm_windows_access(s, ship_imo) # 用已保存的结果填充INSERT参数 f.execute( "INSERT INTO 'inspections tm' VALUES(:name, :imoship, :lastinsp, :ship_risk, :date_pii , :date_pi, :prio)", { 'name': row[0], 'imoship': row[1], 'lastinsp': '', 'ship_risk': tm_data[0], 'date_pii': tm_data[2], 'date_pi': tm_data[3], 'prio': tm_data[1] }) conn.commit() conn.close() get_ship_tm_window()
另外我做了个小优化:把Session的header设置移到了循环外面,因为每次调用get_tm_windows_access都会重复设置header,这完全没必要——Session的header只需要设置一次就会在后续所有请求中生效。
额外建议
- 如果你的
ships表数据量很大,建议把conn.commit()移到循环外面(或者每处理50/100行提交一次),频繁的commit会大幅降低数据库操作的效率。 - 可以给
tm_data的元素单独赋值并加注释,比如ship_risk = tm_data[0],这样代码可读性会更好,避免后续维护时搞不清每个索引对应什么值。
内容的提问来源于stack exchange,提问作者Eduardo
相关产品推荐
相关产品推荐

