Python从SQLite提取笑话推送Telegram频道重复发送问题求助
问题根源
你当前的代码每次执行时,都会固定查询jok表中ROWID升序排列的前chand条数据,没有对已发送的笑话做标记,所以重复运行必然返回完全相同的内容。
解决方案(推荐:新增已发送状态字段)
这是可靠性最高的实现方式,不会因为本地缓存文件丢失导致重复发送:
- 先执行一次SQL命令给jok表新增状态字段(只需要执行一次,后续不需要重复运行):
ALTER TABLE jok ADD COLUMN is_sent INTEGER DEFAULT 0;
字段默认值0代表未发送,1代表已发送。
- 修改后的完整代码如下:
import requests import sqlite3 import random import re def send(msg,token,ca): url = f"https://api.telegram.org/bot{token}/sendMessage?chat_id={ca}&text={msg}" mypay = {"UrlBox":url,"AgentBox" : "Google Chrome","VersionsList" : "HTTP/1.1","MethodList" : "GET"} http = requests.post("http://httpdebugger.com/tools/ViewHttpHeaders.aspx",data=mypay) conn = sqlite3.connect("jokjok.db") c = conn.cursor() emoji_list = ["🤣","😂😂","🤣😂🤣😂","😁😎😂"] emoji_taki = ["😂","😁","🤣","🤩","😍","🤣"] chand = 5 # 只查询未发送的笑话,最多取chand条,用参数化查询避免SQL注入风险 c.execute("SELECT ROWID, * FROM jok WHERE is_sent = 0 ORDER BY ROWID ASC LIMIT ?", (chand,)) unsent_jokes = c.fetchall() # 处理未发送笑话数量不足的情况,可根据需求自行调整逻辑 if len(unsent_jokes) < chand: print(f"剩余未发送笑话数量不足{chand}条,当前仅剩{len(unsent_jokes)}条") for jok_item in unsent_jokes: rowid = jok_item[0] jok = str(jok_item[1:]) # 原有字符串处理逻辑保留 jok = jok.replace("(","") jok = jok.replace(")","") jok = jok.replace("'","") jok = jok.replace("\\u200c"," ") jok = jok.replace("\"","") jok = jok.replace("[","") jok = jok.replace("]","") jok = jok.replace("\\n",""" """) jok = jok.replace("\\","") jok = re.sub(",$", "", jok) jok = f"{jok} {random.choice(emoji_list)}" send(jok,"mykey","@jok_khone_channel") if random.choice([False]*8 + [True]*4): send(random.choice(emoji_taki),"mykey","@jok_khone_channel") # 标记当前笑话为已发送 c.execute("UPDATE jok SET is_sent = 1 WHERE ROWID = ?", (rowid,)) conn.commit() conn.close()
替代方案(不想修改表结构时使用)
如果不方便修改数据库表结构,可以把最后一次发送的最大ROWID存在本地文件中,下次查询时只取大于该ROWID的笑话:
- 首次运行时读取本地文件不存在,就默认从0开始查询
- 每次发送完成后把本次发送的最大ROWID写入本地文件
last_sent_id.txt即可
该方案的缺点是如果本地文件丢失,会出现重复发送的情况。
内容的提问来源于stack exchange,提问作者nimafanniasl
相关产品推荐
相关产品推荐

