3

代码:

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()一行。我只是无法弄清楚我错过了什么!

4

2 回答 2

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 语句。

于 2011-12-06T23:55:48.837 回答
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

不过,我同意机器,在初始化对象时将连接和光标对象作为参数传递。

于 2011-12-06T23:41:00.320 回答