使用Tweepy拉取推文存SQLite时存在created_at仍报KeyError问题
问题原因
- Twitter流接口返回的不全是普通推文数据,还包含删除通知、限速提醒、权限告警等控制类消息,这类数据结构不包含
created_at、text等推文专属字段,直接按键取值必然触发KeyError - 代码中
stream.start("python")传入的是字符串,而tweepy.Stream.filter的track参数要求传入列表,会导致参数解析异常,返回非预期结构的数据 - 部分特殊推文(比如被删除的、权限受限的)或新版API返回的字段有删减,部分嵌套字段(比如用户的时区等信息)可能已经被废弃不存在
排查步骤
- 先打印返回的原始数据确认结构:在
all_data = json.loads(raw_data)之后增加一行print(json.dumps(all_data, indent=2)),查看当前返回的到底是什么数据,是否真的存在created_at字段 - 检查参数传入是否正确:流跟踪的关键词必须用列表包裹,不能直接传字符串
解决方法
- 加字段存在性判断,非推文数据直接跳过处理
- 用字典的
get()方法取值,给缺失字段设置默认值,避免直接按键取值抛出异常 - 修正参数传入错误
- 可选:捕获全局异常,跳过异常数据不影响整个流运行
核心代码修改示例
修正on_data方法
def on_data(self, raw_data): try: all_data = json.loads(raw_data) # 先判断是不是普通推文,缺少核心字段直接跳过 if 'created_at' not in all_data or 'user' not in all_data: return True # 用get方法取值,设置默认值 created_at = all_data.get('created_at', '') favorite_count = all_data.get("favorite_count", 0) favorited = all_data.get("favorited", False) filter_level = all_data.get("filter_level", '') lang = all_data.get("lang", '') retweet_count = all_data.get("retweet_count", 0) retweeted = all_data.get("retweeted", False) source = all_data.get("source", '') text = all_data.get("text", '') truncated = all_data.get("truncated", False) user = all_data.get('user', {}) user_created_at = user.get("created_at", '') user_followers_count = user.get("followers_count", 0) user_location = user.get("location", '') user_lang = user.get("lang", '') user_name = user.get("name", '') user_screen_name = user.get("screen_name", '') user_time_zone = user.get("time_zone", '') user_utc_offset = user.get("utc_offset", '') user_friends_count = user.get("friends_count", 0) c.execute("INSERT INTO tweets2(created_at, favorite_count, favorited, filter_level, lang, retweet_count, retweeted, source, text, truncated, user_created_at, user_followers_count, user_location, user_lang, user_name, user_screen_name, user_time_zone, user_utc_offset, user_friends_count) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", (created_at, favorite_count, favorited, filter_level, lang, retweet_count, retweeted, source, text, truncated, user_created_at, user_followers_count, user_location, user_lang, user_name, user_screen_name, user_time_zone, user_utc_offset, user_friends_count)) conn.commit() except Exception as e: # 打印异常不中断流运行 print(f"处理数据出错: {e}") return True
修正关键词传入
stream.start(["python"])
其他代码问题修复
- 建表时的
conn.commit后面没加括号,不会实际执行建表提交,要改成conn.commit() MaxStream类的__init__方法参数名listner拼写错误,虽然不影响运行,建议改成正确拼写避免混淆
内容的提问来源于stack exchange,提问作者Nimesh Kumar
相关产品推荐
相关产品推荐

