使用Tweepy获取推文时出错

6

我有一个Python脚本,用于获取推特信息。在脚本中,我使用了库 Tweepy。我使用了有效的身份验证参数。运行此脚本后,一些推文被存储在我的MongoDB中,而另一些则被if语句拒绝。但是,我仍然收到错误提示。

requests.packages.urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(0 bytes read, 2457 more expected)'

我的问题是如何改进脚本的哪个部分,以避免出现上述错误。
这是我的脚本:
    from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
import time
import json
from pymongo import MongoClient

#Mongo Settings
client = MongoClient()
db = client.Sentiment
Tweets = db.Tweet

#Twitter Credentials
ckey ='myckey'
csecret ='mycsecret'
atoken = 'myatoken'
asecret = 'myasecret'

class listener(StreamListener):

    def on_data(self, data):
        try:  

            tweet = json.loads(data)

            if tweet["lang"] == "nl":
                print tweet["id"]
                Tweets.insert(tweet)



            return True
        except BaseException, e:
            print 'failed on_date,', str(e)
            time.sleep(5)

    def on_error(self, status):
        print status

auth = OAuthHandler(ckey, csecret)
auth.set_access_token(atoken, asecret)
twitterStream = Stream(auth, listener())
twitterStream.filter( track=["geld lenen"
                            ,"lening"
                            ,"Defam"
                            ,"DEFAM"
                            ,"Credivance"
                            ,"CREDIVANCE"
                            ,"Alpha Credit"
                            ,"ALPHA CREDIT"
                            ,"Advanced Finance"
                            ,"krediet"
                            ,"KREDIET"
                            ,"private lease"
                            ,"ing"
                            ,"Rabobank"
                            ,"Interbank"
                            ,"Nationale Nerderlanden"
                            ,"Geldshop"
                            ,"Geldlenen"
                            ,"ABN AMBRO"
                            ,"Independer"
                            ,"DGA adviseur"
                            ,"VDZ"
                            ,"vdz"
                            ,"Financieel Attent"
                            ,"Anderslenen"
                            ,"De Nederlandse Kredietmaatschappij"
                            ,"Moneycare"
                            ,"De Financiele Makelaar Kredieten"
                            ,"Finanplaza"
                            ,"Krediet"
                            ,"CFSN Kredietendesk"
                            ,"De Graaf Assurantien en Financieel Adviseurs"
                            ,"AMBTENARENLENING"
                            ,"VDZ Geldzaken"
                            ,"Financium Primae"
                            ,"SNS"
                            ,"AlfamConsumerCredit"
                            ,"GreenLoans"
                            ], languages="nl" 
                     )

I hope you can help me...

3个回答

14
IncompleteRead 错误通常在您消费传入的推文开始落后时发生,考虑到您要跟踪的长列表,这很有道理。大多数人似乎采取的一般方法(包括我自己)是简单地抑制此错误并继续收集(请参见上面的链接)。
我无法完全记得 IncompleteRead 是否会关闭您的连接(我认为可能会,因为我的个人解决方案会重新连接我的流),但您可以考虑类似以下内容的东西(我只是随便说说,它可能需要重新修改以适应您的情况):
# from httplib import IncompleteRead # Python 2
from http.client import IncompleteRead # Python 3
...
while True:
    try:
        # Connect/reconnect the stream
        stream = Stream(auth, listener)
        # DON'T run this approach async or you'll just create a ton of streams!
        stream.filter(terms)
    except IncompleteRead:
        # Oh well, reconnect and keep trucking
        continue
    except KeyboardInterrupt:
        # Or however you want to exit this loop
        stream.disconnect()
        break
...

再次强调,这只是个人的猜测,但故事的道德就是通常采用的方法是抑制错误并继续执行。


编辑(2016年10月11日): 对于处理大量推文的人来说,有一个有用的技巧-一种处理该情况的方法不会丢失连接时间或推文,那就是将传入的推文放入排队解决方案(RabbitMQ、Kafka等),由从队列中读取数据的应用程序进行摄取/处理。

这将瓶颈从Twitter API转移到您的队列上,它应该没有问题等待您消耗数据。

这更像是一种“生产”软件解决方案,因此,如果您不关心丢失推文或重新连接,则上述解决方案仍然完全有效。


1
我在 http 包中找不到 client。我已经安装了 http,但当我写 from http.client import IncompleteRead 时,会收到 ImportError: No module named client 的错误。有什么想法吗? - Valerio D. Ciotti
在这种情况下,你会如何启动服务器? - geekoraul
对于Python 2,您应该能够直接从http包导入IncompleteReadfrom http import IncompleteRead。在Python 3中,它被移动到了http.client - dbernard
1
@dbernard 你好,我尝试了这种方法 - 如问题中所述,实际上抛出的不是 IncompleteRead 异常,而是需要处理的 ProtocolError。您能否更新您的答案? - Toivo Säwén
在 on_data 函数中将数据放入 Kinesis 仍然会出现相同的错误,我已经检查了 Kinesis 是否正常工作。这只是为了让遇到相同问题的人可以参考。 - A-nak Wannapaschaiyong

2

我遇到了同样的问题,在从过滤函数中删除languages后解决了这个问题。

因为它尚未正常工作,尽管Twitter表示它正在运行。

相反,我像您在on_data(..)中所做的那样保持语言检查。

此外,我使用以下on_status(..)而不是on_data(..)

def on_status(self, status):
    ...
    tweet = json.dumps(status)
    if tweet["lang"] == "nl":
        print tweet["id"]
        Tweets.insert(tweet)
    ...

有其他人报告说使用twitterStream.filter(track=['word'], languages=['nl']),但对我没有用。


0

IncompleteRead 错误是网络相关问题的诊断。你在哪里运行这个脚本?如果运行此脚本的主机位于防火墙、负载均衡器等后面,网络包可能因某些原因而被丢弃。


Kadir,感谢您快速回复我的问题。我从我的主机上运行这个程序。我该怎么做才能减少这个错误信息呢?或者保持连接的活跃! - Erik hoeven
你好,首先,如果你的主机是公司网络的一部分,那么它可能会违反网络政策。其次,请检查你的主机是否运行防火墙或安全应用程序(如杀毒软件等),将它们关闭后再尝试。 - Kadir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接