【问题标题】:Clean fix to KeyError NoneType while parsing JSON解析 JSON 时对 KeyError NoneType 的清理修复
【发布时间】:2017-02-19 07:48:36
【问题描述】:

我很菜鸟,使用一些借来的 python 代码对我用 tweepy 提取的推文进行非常简单的 JSON 解析。我已经尝试解决自己的问题,但似乎会产生更多问题。

.txt 文件中的几行会导致问题。一方面,该文件定期包含以下内容:

{"limit":{"track":3,"timestamp_ms":"1487481419833"}}

另一方面,对于某些推文,推文字段都在那里,但似乎不是 JSON 格式(例如,Sublime 无法识别这样的语法)。

结果是下面的代码给了我一个 KeyError 'text'

tweets['text'] = map(lambda tweet: tweet['text'], tweets_data)

所以我把它改成:

tweets['text'] = map(lambda tweet: tweet.get('text', None), tweets_data)

但是,现在我在稍后的代码中使用时遇到了不同的错误:

def word_in_text(word, text):
word = word.lower()
text = text.lower()
match = re.search(word, text)
if match:
    return True
return False

我得到错误:

AttributeError: 'NoneType' 对象没有属性 'lower'

我认为必须有一个更清洁、更简单的解决方案来解决所有这些问题。有什么建议么?下面是完整的代码(减去我正在打印的一些图表和我在 dataFrame 中创建的更多列)。

非常感谢,如果我没有遵守适当的发帖礼仪,我们深表歉意。

import json
import pandas as pd
import matplotlib.pyplot as plt
import re

tweets_data_path = '[...trump_tweets.txt]'

tweets_data = []
tweets_file = open(tweets_data_path, "r")
for line in tweets_file:
try:
    tweet = json.loads(line)
    tweets_data.append(tweet)
except:
    continue

print "Number of tweets included is " + str(len(tweets_data))

tweets = pd.DataFrame()

tweets['text'] = map(lambda tweet: tweet.get('text', None), tweets_data)
tweets['lang'] = map(lambda tweet: tweet.get('lang', None), tweets_data)
tweets['country'] = map(lambda tweet: tweet.get('place', None), tweets_data)

def word_in_text(word, text):
word = word.lower()
text = text.lower()
match = re.search(word, text)
if match:
    return True
return False

search_term_1 = 'America'
search_term_2 = 'POTUS'
search_term_3 = 'ban'

tweets[search_term_1] = tweets['text'].apply(lambda tweet: word_in_text(search_term_1, tweet))
tweets[search_term_2] = tweets['text'].apply(lambda tweet: word_in_text(search_term_2, tweet))
tweets[search_term_3] = tweets['text'].apply(lambda tweet: word_in_text(search_term_3, tweet))

print "tweets mentioning search_term_1: " + str(tweets[search_term_1].value_counts()[True])
print "tweets mentioning search_term_2: " + str(tweets[search_term_2].value_counts()[True])
print "tweets mentioning search_term_3: " + str(tweets[search_term_3].value_counts()[True])

【问题讨论】:

  • 可能其中一条推文没有文字?您是否尝试过打印推文并调查叛逆的推文?
  • @omri_saadon 是的,事实上我可以看到问题——这就是我试图在顶部解释的内容。 .txt 文件中偶尔会出现“限制”标记,并且其他推文没有以正确的语法出现(对于那些我猜是缺少字段或其他东西的人)。
  • 在那种情况下,我猜你会得到 rateLimitException,是这样吗?你想完成什么?避免错误或不迭代格式错误的推文?
  • 谢谢,我收到了错误 KeyError 'text' 我想我想避免错误并继续前进,我认为 @gryf 代码可以做到这一点。 (从 .txt 文件中删除这些行也很好,但不是必需的)

标签: python json twitter nonetype


【解决方案1】:

怎么样:

tweets['text'] = map(lambda tweet: tweet.get('text', ''), tweets_data)

字典方法.get() 默认返回None 以防缺少键,但它可能是任何对象。在这种情况下,tweet['text'] 可能是一个字符串,因此最好将其留空以表示缺失。

【讨论】:

  • 啊,太简单了,谢谢!这似乎让我度过了难关。你知道为什么这条线不能类似地工作吗? tweets['country'] = map(lambda tweet: tweet.get('place', '')('country', '') if tweet.get('place', '') != None else None, tweets_data)
  • this:tweet.get('place', '')('country', '') 似乎在调用一个函数,这可能不是您想要的。这个if tweet.get('place', '') != None 永远不会是None
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多