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 文件中。我将这些推文(我尝试)填充到推文的 locationtext 字段的 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。如果是这样,geocoordinatesplace 字段可能包含地理标记信息。

至于缺少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 &lt;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的主要内容,如果未能解决你的问题,请参考以下文章

从 twitter 找出 Flume 下载的推文的位置

Python 脚本,用于转发特定推文的 twitter 机器人

如何获取 Twitter 上发布的签到推文的地理位置和地点 ID

将 Twitter 时间转换为特定格式的日期时间,以计算一天的推文频率

特定推文的 Twitter 链接的 URL

特定推文的Twitter链接的URL