【问题标题】:Writing to csv error handling写入 csv 错误处理
【发布时间】:2014-11-18 11:45:05
【问题描述】:

目前我的流程如下:

  1. 构建并向 API 发送请求
  2. 接收响应
  3. 解析 JSON 响应
  4. 将解析后的值写入 csv

我收到了来自 Google Directions API 的 JSON 响应。我的代码在 99% 的情况下都能正常工作,但如果我没有按预期收到 JSON 数组,则会失败。由于我在此循环之后将响应批量写入 csv,因此如果发生错误,我会丢失所有结果。

代码如下:

import requests
import csv
import json
import urlparse
import hashlib
import base64
import hmac
import sys
import time
from pprint import pprint

url_raw = 'https://maps.googleapis.com/maps/api/directions/json'
Private_Key = ''
client = ''
decodedkey = base64.urlsafe_b64decode(Private_Key)

with open('./Origins.csv', 'rU') as csvfile:
    reader = csv.DictReader(csvfile)
    origincoords = ['{Y},{X}'.format(**row) for row in reader]

with open('./Destinations.csv', 'rU') as csvfile:
    reader = csv.DictReader(csvfile)
    destinationcoords = ['{Y},{X}'.format(**row) for row in reader]

results=[]
session = requests.session()

for origin, destination in zip(origincoords, destinationcoords):
    params ={'origin': origin, 'destination': destination, 'client': client}
    request = requests.Request('GET', url_raw, params=params).prepare()
    parsed_url = urlparse.urlparse(request.url)
    Signature = hmac.new(decodedkey, '{}?{}'.format(parsed_url.path, parsed_url.query), hashlib.sha1).digest() 
    request.prepare_url(request.url, {'signature': base64.urlsafe_b64encode(Signature)})
    response = session.send(request)
    directions = response.json()
    time.sleep(0.0)
    results.append(directions)

pprint(results)

output = open('duration_distance_results.csv', 'w+')
writer = csv.DictWriter(output, delimiter=',', fieldnames=['duration(s)', 'distance(m)'])
writer.writeheader()

for route in results:
    for leg in route['routes'][0]['legs']:
        params = {
            "duration(s)": leg['duration']['value'],
            "distance(m)": leg['distance']['value'],
        }
        print(params)
        writer.writerow(params)

如果我没有在预期的数组中得到 JSON 响应,我会得到一个列表索引超出范围错误,并且通过这个松散的内容到目前为止已经完成了。

理想情况下,我认为如果我在循环中写入 csv 会更健壮,因为收到每个结果,而不是在收到所有结果后才这样做。或者,正如我所尝试的,使用 if 语句 -

  1. 我尝试了一个 if 语句,如果存在值,则写入该值,如果不存在,则写入错误。但是,我收到以下错误“NameError: name 'leg' is not defined”

    如果路线中的腿['routes'][0]['legs'] == 值: 对于结果中的路线: 对于路线中的腿['路线'] [0] ['腿']: 参数 = { “持续时间”:腿['持续时间']['价值'], “距离(米)”:腿['距离']['值'], } 打印(参数) writer.writerow(params)

    其他: 结果中的价值: 错误 = { “持续时间”:“错误”, “距离(米)”:'错误', } 打印(错误) writer.writerow(错误)

  2. 我尝试了一个 if 语句来查看从 Google 返回的状态消息。但是,这会失败并出现错误“for error_message in results['results'][0]['error_message']: TypeError: 列表索引必须是整数,而不是 str"

    对于结果中的 error_message['results'][0]['error_message']: 参数 = { "error_message": error_message}

    if error_message == value:
        for route in results:
            for leg in route['routes'][0]['legs']:
                params = {
                "duration(s)": leg['duration']['value'],
                "distance(m)": leg['distance']['value'],
                }
                print(params)
                writer.writerow(params)
    
    else:
        for value in results:
            error = {
            "duration(s)": 'error',
            "distance(m)": 'error',
            }
            print(error)
            writer.writerow(error)
    

    pprint(结果)

很明显,我在这里学习缓慢。对处理错误的最佳方法的评论将不胜感激。

【问题讨论】:

    标签: python json csv


    【解决方案1】:

    首先要做的是检查response 对象的HTTP 状态代码。它不是 Google API 文档的明确部分,但显然不是 200(“找到”)HTTP 状态代码意味着您有问题,您甚至不能期望在响应的正文中得到任何有用的东西。 HTTP 响应代码记录在 HTTP RFC 中。

    然后,如果您阅读 API 的文档 (https://developers.google.com/maps/documentation/directions/),您会发现返回的 json dict 有一个“状态”键,这些值也记录在案。因此,接下来要检查此状态代码并采取适当的行为,即:

    for result in results: 
        if result["status"] == "OK":
            for leg in result['routes'][0]['legs']:
                params = {
                  "duration(s)": leg['duration']['value'],
                  "distance(m)": leg['distance']['value'],
                }
                print(params)
                writer.writerow(params)
        else: 
          # not OK, let's check if we have an explicit error message:
          if "error_message" in result:
              print result["error_message"]
          # handle the error case...
    

    【讨论】:

    • 谢谢@bruno。这运作良好。我刚刚跑了 20,000 次,没有任何问题,结果非常好
    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    相关资源
    最近更新 更多