我正在按照本指南http://www.mikaelbrunila.fi/2017/03/27/scraping-extracting-mapping-geodata-twitter/使用python和geomap抓取一些推文。
存储推文后,我运行第二个包含
的脚本if tweet['coordinates']:
user_data["features"]["primary_geo"] = str(tweet['coordinates'][tweet['coordinates'].keys()[1]][1]) + ", " + str(tweet['coordinates'][tweet['coordinates'].keys()[1]][0])
user_data["features"]["geo_type"] = "Tweet coordinates"
我收到了消息
推文['坐标'] [推文['坐标']。键()[1]] [1])+"," + str( TypeError:' dict_keys' object不支持索引
我知道这是用python2编写的,而我现在正在使用python3.4所以也许str不能被索引了?
python3中的等价表达式是什么?
修改 脚本:
import json
# Tweets are stored in in file "fname". In the file used for this script,
# each tweet was stored on one line
fname = 'test_with_sample.json'
with open(fname, 'r') as f:
# Create dictionary to later be stored as JSON. All data will be included
# in the list 'data'
users_with_geodata = {
"data": []
}
all_users = []
total_tweets = 0
geo_tweets = 0
for line in f:
tweet = json.loads(line)
if tweet['user']['id']:
total_tweets += 1
user_id = tweet['user']['id']
if user_id not in all_users:
all_users.append(user_id)
# Give users some data to find them by. User_id listed separately
# to make iterating this data later easier
user_data = {
"user_id": tweet['user']['id'],
"features": {
"name": tweet['user']['name'],
"id": tweet['user']['id'],
"screen_name": tweet['user']['screen_name'],
"tweets": 1,
"location": tweet['user']['location'],
}
}
# Iterate through different types of geodata to get the variable primary_geo
tweet_coords = list(tweet['coordinates'][tweet['coordinates']]).keys()
tweet_coords2 = list(tweet['coordinates'][tweet['coordinates']]).keys()
if tweet['coordinates']:
# lon = tweet.coordinates['coordinates'][0]
# lat = tweet.coordinates['coordinates'][1]
# user_data["features"]["lon"] = lon
# user_data["features"]["lat"] = lat
user_data["features"]["primary_geo"] = str(tweet_coords[1][1]) + ", " + str(tweet_coords2[1][0])
user_data["features"]["geo_type"] = "Tweet coordinates"
if tweet['place']:
user_data["features"]["primary_geo"] = tweet['place']['full_name'] + ", " + tweet['place'][
'country']
user_data["features"]["geo_type"] = "Tweet place"
else:
user_data["features"]["primary_geo"] = tweet['user']['location']
user_data["features"]["geo_type"] = "User location"
# Add only tweets with some geo data to .json. Comment this if you want to include all tweets.
if user_data["features"]["primary_geo"]:
users_with_geodata['data'].append(user_data)
geo_tweets += 1
# If user already listed, increase their tweet count
elif user_id in all_users:
for user in users_with_geodata["data"]:
if user_id == user["user_id"]:
user["features"]["tweets"] += 1
#except KeyError:
# pass
# Count the total amount of tweets for those users that had geodata
for user in users_with_geodata["data"]:
geo_tweets = geo_tweets + user["features"]["tweets"]
# Get some aggregated numbers on the data
print
"The file included " + str(len(all_users)) + " unique users who tweeted with or without geo data"
print
"The file included " + str(
len(users_with_geodata['data'])) + " unique users who tweeted with geo data, including 'location'"
print
"The users with geo data tweeted " + str(geo_tweets) + " out of the total " + str(total_tweets) + " of tweets."
# Save data to JSON file
with open('users_geo_sample.json', 'w') as fout:
fout.write(json.dumps(users_with_geodata, indent=4))
答案 0 :(得分:1)
Dict键不是容器。他们只是在那里查看数据。
这很容易解决:
tweet_coords = list(tweet['coordinates'][tweet['coordinates'].keys())
tweet_coords2 = list(tweet['coordinates'][tweet['coordinates'].keys())
if tweet['coordinates']:
user_data["features"]["primary_geo"] = str(tweet_coords[1]][1]) + ", " + str(tweet_coords2[1]][0])
user_data["features"]["geo_type"] = "Tweet coordinates"
这样键就是python列表容器类型,而不是' dict键'类型。你应该从那里开始。如果我能进一步协助,请告诉我。
答案 1 :(得分:0)
毕竟这是一种数据类型的混淆:
Tweet['coordinates']
返回类型dict。 dict包含多个对象,其中一个是列表coordinates
。所以我能够使用以下方法获取坐标:
lat = (tweet['coordinates']['coordinates'])[0]
lot = (tweet['coordinates']['coordinates'])[1]