我正试图从Echonest API中提取一百首不同歌曲的歌曲数据。我在CSV文件中有每首歌的ID - 我正在尝试编写一个读取ID的脚本,将它们附加到API网址,然后将数据写入新的CSV,但我遇到了一些麻烦。
是否有一种很好的方法可以提取ID代码并将其附加到循环中的URL中?这就是我到目前为止所拥有的;不确定如何/在何处将有关将ID添加到URL的部分。
import urllib2
import json
import csv
from time import sleep
outfile_path='/Users/path/to/file.csv'
api_url = 'http://developer.echonest.com/api/v4/song/profile?'
API_KEY = ''
writer = csv.writer(open(outfile_path))
with open('/Users/path/to/file.csv') as f:
for row in csv.DictReader(f):
song_id = row['id']
qs = urllib.urlencode({"api_key": API_KEY,
"bucket": "audio_summary",
"id": song_id})
url = '{}?{}'.format(API_URL, qs)
parsed_json = json.load(resource)
for song in parsed_json['results']:
row = []
writer.writerow({k: v.encode('utf-8') for k, v in song.items()})
sleep(5)
答案 0 :(得分:1)
我不确定你坚持使用哪一部分(你发布的代码存在很多问题,这些问题会阻止它进行编译,更不用说解决你真正的问题了,而且你已经&# 39; t描述了问题),但似乎有两个可能的地方。
首先,我不确定您是否知道如何打开CSV文件并从中获取值。您尝试打开目录而不是文件,并且您没有对行执行任何操作,然后您尝试为100行中的每一行执行内循环100次我99%肯定你只想为你的100行中的每一行做一次。
如果您使用csv.reader
,则必须知道ID所在的列号;使用csv.DictReader
可以轻松实现,因为您只需知道列名称是什么。所以,让我们这样做:
with open('/path/to/inputfile.csv') as f:
for row in csv.DictReader(f):
song_id = row['id']
# make and process request with song_id
如果您的CSV文件没有标题行,那么只需使用reader
,并将列号(例如,0
替换为第一列)代替{{ 1}}。
现在,您要对该ID执行的操作是将每个ID粘贴到URL中。您可以使用字符串格式来完成此操作。例如:
'id'
您还需要填写URL_TEMPLATE = 'http://developer.echonest.com/api/v4/song/profile?api_key=&bucket=audio_summary&id={}'
# ... inside the for loop ...
song_id = row['id']
url = URL_TEMPLATE.format(song_id)
resource = urllib2.urlopen(url)
parsed_json = json.load(resource)
,或者EchoNest不接受您的查询,所以:
api_key
但是,使用urlencode
生成查询字符串通常更好,而不是尝试通过字符串方法来完成。除了更具可读性之外,它还会处理您可能无法想到的事情,比如在您的值中编码任何不友好的URL字符。所以:
URL_TEMPLATE = 'http://developer.echonest.com/api/v4/song/profile?api_key={}&bucket=audio_summary&id={}'
API_KEY = "<your API key goes here>"
# ... inside the for loop ...
url = URL_TEMPLATE.format(API_KEY, song_id)
然后你只需要循环API_URL = 'http://developer.echonest.com/api/v4/song/profile'
# ... inside the for loop ...
qs = urllib.urlencode({"api_key": API_KEY,
"bucket": "audio_summary",
"id": song_id})
url = '{}?{}'.format(API_URL, qs)
的部分并写出你已经写过的行。但有两点说明。
首先,parsed_join['results']
是不必要的; str(foo.encode('utf-8'))
已经返回encode
。
其次,您已经获得了大量不必要的重复代码来构建str
。您为row
词典中的每个键执行相同的操作,那么为什么不使用song
并将其保留为词典:
DictWriter
...或者,如果您更喜欢使用writer.writerow({k: v.encode('utf-8') for k, v in song.items()})
,只需使用writer
将所有内容一次性提取到列表中:
operator.itemgetter