使用Tweepy获取Tweets时出错



我有一个Python脚本可以获取tweet。在脚本中,我使用了libaryTweepy。我使用了有效的身份验证参数。在运行这个脚本后,一些推文被存储在我的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" 
                     )

我希望你能帮助我…

这个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
...

再说一次,我只是随口说说,但故事的寓意是,这里采取的一般方法是抑制错误并继续下去。


EDIT(2016年11月10日):对于任何处理大量推文的人来说,这只是一个有用的花絮-在不损失连接时间或推文的情况下处理这种情况的一种方法是将传入的推文放入队列解决方案(RabbitMQ、Kafka等),由从该队列读取的应用程序接收/处理。

这将瓶颈从Twitterneneneba API移动到您的队列,等待您消费数据应该不会有问题。

这更像是一个"生产"软件解决方案,所以如果你不在乎丢失推文或重新连接,上述解决方案仍然完全有效。

我也遇到了同样的问题,当我从过滤函数中重新获得languages时,问题就解决了

因为它还没有发挥作用,尽管推特说它是

相反,我会像你在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']),但我没有。

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

最新更新