如何使用Tweepy执行全国范围的Twitter流搜索?
问题描述:
使用Twitter Stream API与Python进行大面积推文收集的最佳方式是什么?如何使用Tweepy执行全国范围的Twitter流搜索?
我对地理位置感兴趣,尤其是北美地区的全国范围内的推文收藏。我目前正在使用Python和Tweepy从推特流媒体API转储推文到MongoDB数据库。
我目前正在使用API的位置过滤器在边界框内拉动推文,然后我进一步过滤为仅存储带有坐标的推文。我发现,如果我的边界框足够大,我碰上一个Python连接错误:
raise ProtocolError('Connection broken: %r' % e, e)
requests.packages.urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))
我所做的边界盒小(我已经成功尝试NYC纽约和+新英格兰),但它看起来像错误返回一个足够大的边界框。我也尝试了同时运行多个StreamListeners的意图,但我不认为这个API允许这个(我得到了420个错误),或者至少不是我尝试的方式。
我使用Tweepy建立一个自定义StreamListener
类:
class MyListener(StreamListener):
"""Custom StreamListener for streaming data."""
# def __init__(self):
def on_data(self, data):
try:
db = pymongo.MongoClient(config.db_uri).twitter
col = db.tweets
decoded_json = json.loads(data)
geo = str(decoded_json['coordinates'])
user = decoded_json['user']['screen_name']
if geo != "None":
col.insert(decoded_json)
print("Geolocated tweet saved from user %s" % user)
else: print("No geo data from user %s" % user)
return True
except BaseException as e:
print("Error on_data: %s" % str(e))
time.sleep(5)
return True
def on_error(self, status):
print(status)
return True
这是我Thread
类的样子:
class myThread(threading.Thread):
def __init__(self, threadID, name, streamFilter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.streamFilter = streamFilter
def run(self):
print("Starting " + self.name)
#twitter_stream.filter(locations=self.streamFilter)
Stream(auth, MyListener()).filter(locations=self.streamFilter)
而且main
:
if __name__ == '__main__':
auth = OAuthHandler(config.consumer_key, config.consumer_secret)
auth.set_access_token(config.access_token, config.access_secret)
api = tweepy.API(auth)
twitter_stream = Stream(auth, MyListener())
# Bounding boxes:
northeast = [-78.44,40.88,-66.97,47.64]
texas = [-107.31,25.68,-93.25,36.7]
california = [-124.63,32.44,-113.47,42.2]
northeastThread = myThread(1,"ne-thread", northeast)
texasThread = myThread(2,"texas-thread", texas)
caliThread = myThread(3,"cali-thread", california)
northeastThread.start()
time.sleep(5)
texasThread.start()
time.sleep(10)
caliThread.start()
答
获得没有什么不好或不寻常的3210。连接不时会中断。你应该在你的代码中发现这个错误,并重新启动流。一切都会好起来的。
顺便说一句,我注意到你正在审问已弃用的geo
字段。您要的字段是coordinates
。您可能还会发现places
有用。
(Twitter的API文档说多路数据流的连接是不允许的。)
答
看来,当你尝试在一个大的地理搜索关键字的Twitter分配的鸣叫一块(比如说国家或城市)。我认为这可以通过同时运行多个程序流来克服,但作为单独的程序。