You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:47:37