如何使用CSV中的ID重复调用API并将输出写入新CSV?

时间:2013-09-10 20:31:04

标签: python api csv

我正试图从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)

1 个答案:

答案 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