关于提取json值并且翻译的疑问

  • 上周询问过这个问题并得到了解决,代码运行正常;但是重新使用代码的时候又报了错误。*

    工程结构:(PS:打叉的文件未使用)

关于提取json值并且翻译的疑问

Code:

import json
from youDaoApi.translate_api import translate
def jsonText():
    with open('/Users/scrooge/Desktop/json翻译/english#en.json', 'r') as f:
        readText = f.read()
        return readText
def convert(var):
    if isinstance(var, dict):
        return {key: convert(value) for key, value in var.items()}
    elif isinstance(var, list):
        return [convert(item) for item in var]
    elif isinstance(var, tuple):
        return (convert(item) for item in var)
    elif isinstance(var, str):

        return translate(word=var)
    else:
        return var
var = json.loads(jsonText())
print(type(var))
new_var = convert(var)
with open('ss.json', 'wt') as f:
    json.dump(new_var, f, ensure_ascii=False)

官方提供的translate.py

# -*- coding: utf-8 -*-
import sys
import uuid
import requests
import hashlib
from imp import reload
import json
import time
reload(sys)
YOUDAO_URL = 'https://openapi.youdao.com/api'
APP_KEY = '**********'
APP_SECRET = ''**********''
def encrypt(signStr):
    hash_algorithm = hashlib.sha256()
    hash_algorithm.update(signStr.encode('utf-8'))
    return hash_algorithm.hexdigest()
def truncate(q):
    if q is None:
        return None
  size = len(q)
    return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]
def do_request(data):
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    return requests.post(YOUDAO_URL, data=data, headers=headers)
def translate(word):
    q = word

    data = {}
    data['from'] = 'en'
  data['to'] = 'zh-CHS'
  data['signType'] = 'v3'
  curtime = str(int(time.time()))
    data['curtime'] = curtime
    salt = str(uuid.uuid1())
    signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
    sign = encrypt(signStr)
    data['appKey'] = APP_KEY
    data['q'] = q
    data['salt'] = salt
    data['sign'] = sign
    data['vocabId'] = "您的用户词表ID"

  response = do_request(data)
    contentType = response.headers['Content-Type']
    if contentType == "audio/mp3":
        millis = int(round(time.time() * 1000))
        filePath = "合成的音频存储路径" + str(millis) + ".mp3"
  fo = open(filePath, 'wb')
        fo.write(response.content)
        fo.close()
    else:
        # print(response.content.decode('utf-8'))
  var = response.content.decode('utf-8')
        var = json.loads(var)
        # print(type(var))
  word = []
        for i in var['web']:
            # print(i['value'][0])
 # print(type(i['value'][0]))  word.append(i['value'][0])
        print(
            str(word[0])
        )
        return str(word[0])

Error:

关于提取json值并且翻译的疑问

补充:

  • 调用的翻译api返回的值为 str 类型。
  • 运行代码出错感觉是快速请求有道翻译而导致ip被封,随后又注册了官方的api进行调用还是报错。
  • 因为水平有限读懂代码中定义的 convert() 函数有点吃力而难根据报错进行debug。

望指点迷津!

Jason990420
最佳答案

很明显你所谓官方提供的 translate.py, 里面的代码肯定不对

  1. 你要的是翻译, 那怎么会有这一段 ?
    if contentType == "audio/mp3":
        millis = int(round(time.time() * 1000))
        filePath = "合成的音频存储路径" + str(millis) + ".mp3"
        fo = open(filePath, 'wb')
        fo.write(response.content)
        fo.close()
  1. 這段的內容, 很明显有问题, 里面的 var 不是一定有 web 這個 key, 而且這個不是翻譯, 而是指网络上有類似的几個英文詞句的列表, 列表中英文詞句對應的的多個翻譯的結果列表.
  var = response.content.decode('utf-8')
        var = json.loads(var)
        # print(type(var))
  word = []
        for i in var['web']:
            # print(i['value'][0])
 # print(type(i['value'][0]))  word.append(i['value'][0])
        print(
            str(word[0])
        )
        return str(word[0])
  1. 如果你要的是傳入詞句的翻譯, 應該取的是 var['translation'][0], 下面是完整的代码. (記得把上面的 APP_KEY, APP_SECRET 去掉喔 !!)
import sys
import time
import uuid
import json
import requests
import hashlib

YOUDAO_URL = 'https://openapi.youdao.com/api'
APP_KEY = '******************'
APP_SECRET = '*****************'

def encrypt(signStr):
    hash_algorithm = hashlib.sha256()
    hash_algorithm.update(signStr.encode('utf-8'))
    return hash_algorithm.hexdigest()

def truncate(q):
    if q is None:
        return None
    size = len(q)
    return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]

def do_request(data):
      headers = {'Content-Type': 'application/x-www-form-urlencoded'}
      return requests.post(YOUDAO_URL, data=data, headers=headers)

def translate(word):
    q = word
    curtime = str(int(time.time()))
    salt = str(uuid.uuid1())
    signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
    sign = encrypt(signStr)
    data = {
        'from'      : 'en',
        'to'        : 'zh-CHS',
        'signType'  : 'v3',
        'curtime'   : curtime,
        'appKey'    : APP_KEY,
        'q'         : q,
        'salt'      : salt,
        'sign'      : sign,
        'vocabId'   : "您的用户词表ID"
    }

    response = do_request(data)
    contentType = response.headers['Content-Type']

    if contentType == "audio/mp3":
        millis = int(round(time.time() * 1000))
        filePath = "合成的音频存储路径" + str(millis) + ".mp3"
        fo = open(filePath, 'wb')
        fo.write(response.content)
        fo.close()
        return ''           # return blank string to avoid exception in case if it happened.
    else:
        var = response.content.decode('utf-8')
        var = json.loads(var)
        return var['translation'][0]

def jsonText():
  with open('D:/input.json', 'r') as f:
      readText = f.read()
      return readText

def convert(var):
    if isinstance(var, dict):
        return {key: convert(value) for key, value in var.items()}
    elif isinstance(var, list):
        return [convert(item) for item in var]
    elif isinstance(var, tuple):
        return (convert(item) for item in var)
    elif isinstance(var, str):
        return translate(word=var)
    else:
        return var

var = json.loads(jsonText())
new_var = convert(var)

with open('d:/output.json', 'wt') as f:
    json.dump(new_var, f, ensure_ascii=False)
2年前 评论
Scrooge (楼主) 2年前
讨论数量: 5
Jason990420

很明顯出錯的腳本與你提供的腳本並不一樣, 怎麼找錯呢?

何況這個是什麼庫 ? from youDaoApi.translate_api import translate

以下腳本似乎不會有錯

import json
import requests

def translate(word):
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null'
    # 传输的参数,其中 i 为需要翻译的内容
    key = {
        'type': "AUTO",
        'i': word,
        "doctype": "json",
        "version": "2.1",
        "keyfrom": "fanyi.web",
        "ue": "UTF-8",
        "action": "FY_BY_CLICKBUTTON",
        "typoResult": "true"
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
    }
    # key 这个字典为发送给有道词典服务器的内容
    response = requests.post(url, data=key, headers=headers)
    # 判断服务器是否相应成功
    if response.status_code == 200:
        # 然后相应的结果
        result = json.loads(response.text)
        return [item[0]['tgt'] for item in result['translateResult']]
    else:
        print("有道词典调用失败")
        # 相应失败就返回空
        return None

def jsonText():
  with open('D:/input.json', 'r') as f:
      readText = f.read()
      return readText

def convert(var):
  if isinstance(var, dict):
      return {key: convert(value) for key, value in var.items()}
  elif isinstance(var, list):
      return [convert(item) for item in var]
  elif isinstance(var, tuple):
      return (convert(item) for item in var)
  elif isinstance(var, str):
      return translate(word=var)
  else:
      return var

var = json.loads(jsonText())
print(type(var))
new_var = convert(var)

with open('d:/output.json', 'wt') as f:
  json.dump(new_var, f, ensure_ascii=False)
2年前 评论
Jason990420

所提问题

  • 源代码与异常列表内容明显匹配, 比如行号, 比如函数或模块不对
  • 异常列表明显被部份移除或有拼凑
  • 代码无 APP_KEY, APP_SECRET 以及用户词表ID, 他人无法执行, 请自行检视 response.content.decode('utf-8') 的内容, 是否有 web key.
  • 代码排版乱了
  • 其他
2年前 评论
Scrooge (楼主) 2年前
Jason990420

很明显你所谓官方提供的 translate.py, 里面的代码肯定不对

  1. 你要的是翻译, 那怎么会有这一段 ?
    if contentType == "audio/mp3":
        millis = int(round(time.time() * 1000))
        filePath = "合成的音频存储路径" + str(millis) + ".mp3"
        fo = open(filePath, 'wb')
        fo.write(response.content)
        fo.close()
  1. 這段的內容, 很明显有问题, 里面的 var 不是一定有 web 這個 key, 而且這個不是翻譯, 而是指网络上有類似的几個英文詞句的列表, 列表中英文詞句對應的的多個翻譯的結果列表.
  var = response.content.decode('utf-8')
        var = json.loads(var)
        # print(type(var))
  word = []
        for i in var['web']:
            # print(i['value'][0])
 # print(type(i['value'][0]))  word.append(i['value'][0])
        print(
            str(word[0])
        )
        return str(word[0])
  1. 如果你要的是傳入詞句的翻譯, 應該取的是 var['translation'][0], 下面是完整的代码. (記得把上面的 APP_KEY, APP_SECRET 去掉喔 !!)
import sys
import time
import uuid
import json
import requests
import hashlib

YOUDAO_URL = 'https://openapi.youdao.com/api'
APP_KEY = '******************'
APP_SECRET = '*****************'

def encrypt(signStr):
    hash_algorithm = hashlib.sha256()
    hash_algorithm.update(signStr.encode('utf-8'))
    return hash_algorithm.hexdigest()

def truncate(q):
    if q is None:
        return None
    size = len(q)
    return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]

def do_request(data):
      headers = {'Content-Type': 'application/x-www-form-urlencoded'}
      return requests.post(YOUDAO_URL, data=data, headers=headers)

def translate(word):
    q = word
    curtime = str(int(time.time()))
    salt = str(uuid.uuid1())
    signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
    sign = encrypt(signStr)
    data = {
        'from'      : 'en',
        'to'        : 'zh-CHS',
        'signType'  : 'v3',
        'curtime'   : curtime,
        'appKey'    : APP_KEY,
        'q'         : q,
        'salt'      : salt,
        'sign'      : sign,
        'vocabId'   : "您的用户词表ID"
    }

    response = do_request(data)
    contentType = response.headers['Content-Type']

    if contentType == "audio/mp3":
        millis = int(round(time.time() * 1000))
        filePath = "合成的音频存储路径" + str(millis) + ".mp3"
        fo = open(filePath, 'wb')
        fo.write(response.content)
        fo.close()
        return ''           # return blank string to avoid exception in case if it happened.
    else:
        var = response.content.decode('utf-8')
        var = json.loads(var)
        return var['translation'][0]

def jsonText():
  with open('D:/input.json', 'r') as f:
      readText = f.read()
      return readText

def convert(var):
    if isinstance(var, dict):
        return {key: convert(value) for key, value in var.items()}
    elif isinstance(var, list):
        return [convert(item) for item in var]
    elif isinstance(var, tuple):
        return (convert(item) for item in var)
    elif isinstance(var, str):
        return translate(word=var)
    else:
        return var

var = json.loads(jsonText())
new_var = convert(var)

with open('d:/output.json', 'wt') as f:
    json.dump(new_var, f, ensure_ascii=False)
2年前 评论
Scrooge (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!