JSONDecoder Error – While accessing Google Translate API with Python

I am learning to use HTTP requests in Python, using this HTTP request provided by a TopCoder training challenge (learning purposes only! no compensation of any sort) in which you have to access the Google Translate API:

curl --location --request POST 'https://translate.google.com/translate_a/single?client=at&dt=t&dt=ld&dt=qca&dt=rm&dt=bd&dj=1&hl=%25s&ie=UTF-8&oe=UTF-8&inputm=2&otf=2&iid=1dd3b944-fa62-4b55-b330-74909a99969e&' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'User-Agent: AndroidTranslate/5.3.0.RC02.130475354-53000263 5.1 phone TRANSLATE_OPM5_TEST_1' \ --data-urlencode 'sl=de' \ --data-urlencode 'tl=en' \ --data-urlencode 'q=Hallo'  

and I’m wondering how to make the equivalent request in my Python application? Any help is appreciated.

So far I have:

  • installed and imported requests
  • understood that I need to store my POST request in a variable and parse it with JSON.

The issue is that I get a JSONDecoder error

Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "C:\Users\myname\Documents\Code\GoogleTranslateApiPy\env\lib\site-packages\requests\models.py", line 898, in json     return complexjson.loads(self.text, **kwargs)   File "c:\users\myname\appdata\local\programs\python\python38-32\lib\json\__init__.py", line 357, in loads     return _default_decoder.decode(s)   File "c:\users\myname\appdata\local\programs\python\python38-32\lib\json\decoder.py", line 337, in decode     obj, end = self.raw_decode(s, idx=_w(s, 0).end())   File "c:\users\myname\appdata\local\programs\python\python38-32\lib\json\decoder.py", line 355, in raw_decode     raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 

with this Python request (I tried to translate the curl request as best as I could):

import requests  headers = {     'Content-Type': 'application/x-www-form-urlencoded',     'User-Agent': 'AndroidTranslate/5.3.0.RC02.130475354-53000263 5.1 phone TRANSLATE_OPM5_TEST_1', }  params = (     ('client', 'at'),     ('dt', ['t', 'ld', 'qca', 'rm', 'bd']),     ('dj', '1'),     ('hl', '%s'),     ('ie', 'UTF-8'),     ('oe', 'UTF-8'),     ('inputm', '2'),     ('otf', '2'),     ('iid', '1dd3b944-fa62-4b55-b330-74909a99969e'),     ('', ''), )  response = requests.get('https://translate.google.com/translate_a/single', headers=headers, params=params) 

I feel that there’s something fundamental I’m missing here. The request in the current documentation by Google for Translate differs from this provided request, but I’d like to know how I could get this way to work, in case I’m ever provided with a curl command like this in the future.

Add Comment
2 Answer(s)

Two things:

  1. You must do a POST request (currently you are doing a get request)
  1. You are not including the body of the request. For example, the curl call includes url encoded data like this: data-urlencode ‘q=Hallo’. You must include this parameters in your post request too, the provided link shows you how. This are key values that will go inside a dictionary, for example {q: ‘Hallo’, …}

PS: I’m 90% sure that you should also convert to a dictionary the query params you currently have inside tuples. So, you’d have post with headers, params and data.

Add Comment

It’s not clear if you’re trying to use Google Translate API or scraping from the website.

If you’re using Google API, then have a look at their documentation cloud.google.com/translate/docs/reference/rest/v2/translate. Note this requires signing up and getting a free key.

Your code is specifying the content type as application/x-www-form-urlencoded. However they return application-json. You don’t need to specify content-type, and you don’t need to send a fake user-agent.

Here is a working example:

import requests  params = {     'key': 'ABCDED1234' # TODO This is a 41 characters API Key. You'll need to generate one (it's not part of the json certificate)     'q': 'cheese', # TODO supply the phraze you to transalte     'target': 'fr'    }  response = requests.get('https://translation.googleapis.com/language/translate/v2', params=params) response.raise_for_status() # this throws error if status is 4xx or 5xx  results = response.json() translatedPhraze = results['data']['translations'][0]['translatedText'] print(translatedPhraze) 

Output:

fromage 

Also Google have produced their own set of APIs in python. This is generally the recommended approach (but I can see this is just a learning exercise). See pypi.org/project/google-cloud-translate/.

Answered on July 16, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.