使用 Tweepy 获取推文时出错

Error while fetching Tweets with Tweepy

我有一个 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" 
                     )

希望你能帮帮我...

IncompleteRead 错误是对网络相关问题的诊断。你运行那个脚本在哪里?如果主机 运行 宁此脚本是在防火墙、负载平衡器等之后。网络包可能由于某种原因而被丢弃。

IncompleteRead 错误通常会在您使用传入的推文 starts to fall behind 时发生,考虑到您要跟踪的一长串术语,这在您的情况下是有意义的。大多数人(包括我自己)似乎采取的一般方法是简单地抑制此错误并继续您的收集(参见上面的 link)。

我不完全记得 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 等)中,由应用程序读取 来自 ingested/processed ]那个队列。

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

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

我遇到了同样的问题,当我从过滤器函数中删除 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']),但我没有。