将Tweepy的数据提交到sqlite3数据库,无论我怎么做,数据库始终为空

3 投票
2 回答
702 浏览
提问于 2025-04-17 07:51

代码:

import time
import tweepy
import sqlite3

class Listener(tweepy.StreamListener):

    conn = sqlite3.connect('/home/daniel/Desktop/activeSites/djeep/djeep.db')

    def on_status(self, status):
        try:
            c = self.conn.cursor()
            c.execute("""insert into feed_post values (%r,'%s','%s',%d)""") % (status.id, status.text, status.author.screen_name, status.created_at)
            self.conn.commit()
        except:
            pass


    def on_error(self, status_code):
        print 'An error has occured! Status code = %s' % status_code
        return True  # keep stream alive

    def on_timeout(self):
        print 'timeout...'

def main():
    auth = tweepy.OAuthHandler('C_KEY', 'C_SECRET') 
    auth.set_access_token('ACCESS_TOKEN', 'ACCESS_SECRET') 
    stream = tweepy.Stream(auth=auth, listener=Listener())     
    stream.filter(track=('baseball',)) 

if __name__=="__main__":
    try:
        main()
    except KeyboardInterrupt:
        print "See ya!"

我逐行添加与数据库相关的代码,想找出到底是哪个部分出问题,结果发现是加上了 c.execute() 这一行。可是我就是搞不清楚我漏掉了什么!

2 个回答

0

试着把类里的自我引用去掉,或者用一个 __init__ 函数来初始化 self.conn。

def __init__(self):
    self.conn = sqlite3.connect('/home/daniel/Desktop/activeSites/djeep/djeep.db')

def on_status(self, status):
    try:
        c = self.conn.cursor()
        c.execute(SQL...)
        self.conn.commit()
    except:
        pass

我同意 machin 的看法,在你初始化对象的时候,把连接和游标对象作为参数传进去。

2

数据库的路径应该作为你脚本的一个参数,而不是写死在代码里。每次创建这个类的时候,都应该把路径传给它,而不是在类被创建的时候传。不过,目前还不清楚这是否是你问题的根源,也不清楚具体的问题是什么:

你的标题说你无法向数据库写入任何内容,但问题的描述又暗示在你添加 c.execute 时会出现“故障”——这两者哪个是对的呢?当出现“故障”时,具体有什么表现呢?

你使用的 try\yadda\except\pass 方式在默默地忽略所有可能的错误——不要这样做! 把 try\except\pass 去掉,只保留 yadda,回答上面的问题,然后告诉我们结果。

更新:你的 c.execute() 语句让人震惊。为了让它更易读,不用滚动,它相当于这样:

(
    c.execute("""insert into feed_post values (%r,'%s','%s',%d)""")
    % 
    (status.id, status.text, status.author.screen_name, status.created_at)
)

换句话说,你的右括号放错地方了。虽然语法上是有效的,但在运行时肯定会导致错误。

更糟的是:你这样做会让你的代码容易受到 SQL 注入攻击。应该使用参数,而不是字符串格式化:

sql = "insert into feed_post values (?,?,?,?)"
params = (status.id, status.text, status.author.screen_name, status.created_at)
c.execute(sql, params)

这种方法的一个好处是,它的运行速度会更快,因为引擎不需要为每一行写入解析(或者被不同的 SQL 语句缓存淹没)。

撰写回答