Twitter 流式处理脚本在推文的位置字段上抛出一个 keyerror
Posted
技术标签:
【中文标题】Twitter 流式处理脚本在推文的位置字段上抛出一个 keyerror【英文标题】:Twitter streaming script is throwing a keyerror on location field of the tweet 【发布时间】:2017-10-12 11:22:48 【问题描述】:到目前为止,我已经编写了一个 Python 脚本来流式传输推文,并且我已经使用了 tweepy 模块来执行此操作。在推文流式传输大约 3 分钟后,我将这些推文转储到 .json 文件中。我将这些推文(我尝试)填充到推文的 location 和 text 字段的 pandas 数据框中。推文的文本字段在 .json 文件中被填充但不是每个推文(问题 1),就位置字段而言,keyerror(问题 2 ) 被抛出。请问我到底出了什么问题。
twitter_stream_dump.py
import time
import json
import pandas as pd
import re
#tweepy based modules
import tweepy
from tweepy import OAuthHandler
from tweepy import Stream
from tweepy.streaming import StreamListener
#initializing authentication credentials
consumer_key = ''
consumer_secret = ''
access_key = ''
access_secret = ''
#This is a basic listener that just prints received tweets to stdout.
class StdOutListener(StreamListener) :
def __init__(self,time_limit) :
self.start_time = time.time()
self.limit = time_limit
self.saveFile = open('requests.json','a')
super(StdOutListener,self).__init__()
def on_data(self, data) :
if ((time.time() - self.start_time) < self.limit) :
self.saveFile.write(data)
self.saveFile.write('\n')
return True
else :
self.saveFile.close()
return False
def on_error(self, status) :
print(status)
def getwords(string) :
return re.findall(r"[\w'#]+|[.,!?;]",string)
if __name__ == '__main__' :
#This handles Twitter authetification and the connection to Twitter Streaming API
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
time_limit = input("Enter the time limit in minutes : ")
time_limit *= 60
stream = Stream(auth,listener = StdOutListener(time_limit))
string = raw_input("Enter the list of keywords/hashtags to be compared : ")
keyword_list = getwords(string)
#This line filter Twitter Streams to capture data by the keywords: 'python', 'javascript', 'ruby'
stream.filter(track = keyword_list)
tweets_data_path = 'requests.json'
tweets_data = []
tweet_list = []
tweets_file = open(tweets_data_path, "r")
for line in tweets_file :
try :
tweet = json.loads(line)
tweet_list.append(tweet)
except :
continue
num_tweets_collected = len(tweet_list)
#Creates a data frame structure
tweet_dataframe = pd.DataFrame()
text_dump = open('text_dump.txt', 'w')
#Populating the location field of the data frame
#tweet_dataframe['location'] = map(lambda tweet : tweet['location'], tweet_list)
tweet_dataframe['text'] = map(lambda tweet : tweet['text'], tweet_list)
print(tweet_dataframe['text'])
错误:
abhijeet-mohanty-2:Desktop SubrataMohanty$ python twitter_stream_dump.py
Enter the time limit in minutes : 3
Enter the list of keywords/hashtags to be compared : python ruby scala
Traceback (most recent call last):
File "twitter_stream_dump.py", line 81, in <module>
tweet_dataframe['location'] = map(lambda tweet : tweet['location'], tweet_list)
File "twitter_stream_dump.py", line 81, in <lambda>
tweet_dataframe['location'] = map(lambda tweet : tweet['location'], tweet_list)
KeyError: 'location'
requests.json(我的 .json 文件) https://drive.google.com/file/d/0B1p05OszaBkXLWFsQ2VmeWVjbDQ/view?usp=sharing
【问题讨论】:
【参考方案1】:location
字段是用户定义的值,有时不存在。
这就是您收到KeyError
的原因。
请注意,location
是推文附带的 "user profile" metadata 的一部分。它旨在描述用户的位置(如他们的家乡),不是给定推文的地理标记位置。
如果您对地理标签感兴趣,请先查看推文以查看 geo_enabled
字段是否为 true
。如果是这样,geo
、coordinates
和 place
字段可能包含地理标记信息。
至于缺少text
条目,我在使用您提供的数据时没有看到同样的问题。读取数据行时,问题可能是由您的 try
/except
子句引起的。考虑这种方法:
for i, line in enumerate(tweets_file):
if line.rstrip():
tweet = json.loads(line)
tweet_list.append(tweet)
num_tweets_collected = len(tweet_list)
texts = [tweet['text'] for tweet in tweet_list]
tweet_dataframe = pd.DataFrame(texts, columns=['text'])
样本输出:
print(tweet_dataframe.head())
# text
# 0 Tweets and python BFF <3 15121629.976126991
# 1 RT @zeroSteiner: Can now write more post modul...
# 2 •ruby• #MtvInstagLSelena #MtvColabTaylors
# 3 Ruby Necklace July Birthstone Jewelry Rosary...
# 4 @ossia I didn't see any such thing as Python. ...
一些快速摘要统计显示没有丢失任何行,也没有条目是null
:
print("N tweets: ".format(num_tweets_collected))
# N tweets: 286
print("N rows in dataframe: ".format(tweet_dataframe.shape[0]))
# N rows in dataframe: 286
null_count = tweet_dataframe.text.isnull().sum()
print("Tweets with no text field extracted: ".format(null_count))
# Tweets with no text field extracted: 0
【讨论】:
非常感谢您的帮助,但仍有办法从推文中收集位置字段。这样做的原因是我希望将每个位置条目标准化为标准化值。 简短的回答是否定的。更具体地说,这取决于您是否真的需要location
字段,它是用户配置文件的一部分,与特定推文无关,或者您是否需要推文的地理位置。如果用户没有为推文打开地理标记,那么您将无法获取地理位置数据。如果用户没有填写个人资料部分中的location
字段,您也将无法获得该字段。 FWIW,所有推文中只有很小一部分 (1-2%) 带有地理标记。以上是关于Twitter 流式处理脚本在推文的位置字段上抛出一个 keyerror的主要内容,如果未能解决你的问题,请参考以下文章
Python 脚本,用于转发特定推文的 twitter 机器人
如何获取 Twitter 上发布的签到推文的地理位置和地点 ID