Google language / detect API

Code-Stücke können hier veröffentlicht werden.
Antworten
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Nichts besonderes, 2 Funktionen, eine Funktion "übersetzt" einen String, mit der Google language API und die Andere "erkennt" die Sprache in der der String geschrieben ist, mit der Google detect API

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
if sys.version_info[0] < 3:
    import urllib2 as ulib
    from urllib import quote_plus
else:
    import urllib.request as ulib
    from urllib.parse import quote_plus

import json

TRANSLATE_URL = 'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s%%7C%s'
DETECT_URL = 'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=%s'

def google_translate(text, from_, to):
    '''Translates a text, from a given language to a given language
    using the google language-API'''
    if not all([text, from_, to]):
        return ''
    
    r = ulib.urlopen(TRANSLATE_URL % tuple(map(quote_plus, [text, from_, to])))
    json_data = json.load(r)
    r.close()
    
    if json_data['responseStatus'] == 200:
        return json_data['responseData']['translatedText']
    else:
        return ''

def google_detect_lang(text):
    '''Detects a language with the google detect-API'''
    r = ulib.urlopen(DETECT_URL % (quote_plus(text)))
    json_data = json.load(r)
    r.close()
        
    if json_data['responseStatus'] == 200:
        return json_data['responseData']['language']
    else:
        return ''

auto_google_translate = lambda text, to: google_translate(text, google_detect_lang(text), to)

if __name__ == '__main__':
    text = raw_input('Text to translate: ')
    to = raw_input('Translate to?: ')
    #lang = google_detect_lang(text)
    #print lang
    #print google_translate(text, lang, to)
    print auto_google_translate(text, to)
Es wäre schön wenn einer das Skript mit python 3 testen könnte
the more they change the more they stay the same
lunar

Mit "return ''" ungültige Parameter stillschweigend zu "verschlucken" ist unschön. Ein "ValueError" wäre da die richtige Lösung.

Außerdem sollte man with verwenden. Statt

Code: Alles auswählen

r = ulib.urlopen(DETECT_URL % (quote_plus(text)))
json_data = json.load(r)
r.close()
besser

Code: Alles auswählen

with closing(ulib.urlopen(DETECT_URL % (quote_plus(text)))) as stream:
    response = json.load(stream)
r und json_data sind auch keine schönen Namen.

Das Alias "ulib" gefällt mir auch nicht. Warum machst Du es bei "urlopen" anders als bei "quote_plus" und führst noch ein Modul-Alias ein? Du hättest die Funktion mit "from urlib2 import urlopen" bzw. "from urlib.request import urlopen" auch direkt importieren können …
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

ulib liegt daran weil ich am Anfang mehr aus der urllib2 gebraucht habe u.a Request

Wo hast du das "closing" "her"?

Was passt den an json_data nicht?
r = response, bin einfach nur schreibfaul ;)
the more they change the more they stay the same
lunar

"closing" kommt aus contextlib.

"json_data" suggeriert, das gebundene Objekt enthielte Daten im JSON-Format, was nicht stimmt. "json.load()" parst JSON ja und gibt dann ein Objekt zurück, dass mit JSON eigentlich nichts mehr zu tun hat. Anders gesagt: In "json_data" ist kein JSON mehr drinnen ;)

Und Abkürzungen ala "r" macht man nicht ... wenn Du schreibfaul bist, dann such Dir ein anderes Hobby ;)
Zuletzt geändert von lunar am Sonntag 14. Februar 2010, 15:54, insgesamt 1-mal geändert.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Ok, danke für den Hinweis "closing"

Jetzt wo du es sagst klingts logisch (json_data), ich bennene es um zu parsed_response

zum Letzten geht nicht, ich bin zu faul :P
the more they change the more they stay the same
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Übrigens, Google sagt "An area to pay special attention to relates to correctly identifying yourself in your requests. Applications MUST always include a valid and accurate http referer header in their requests. In addition, we ask, but not require, that each request contains a valid API Key. By providing a key, your application provides us with a secondary identification mechanism that is useful should we need to contact you in order to correct any problems."

Da fehlt also noch das setzen der entsprechenden Header vor dem Abschicken des Request. Und was mich wundert (weswegen ich da überhaupt in die Dokumentation geschaut habe) dass es immer GET sein soll, was die Menge des Textes, den man übersetzen will, doch beschränken kann, da häufig Proxy-Systeme nicht mit beliebig langen URLs klar kommen. Offenbar kann man für's Übersetzen, aber nicht für das Erkennen einer Sprache auch POST benutzen.

Stefan
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Das mit den Headern hab ich überlesen und ich hab auch nicht danach gesucht weil es funktionierte, aber gut zu wissen ;), danke!

Wo hast du die Information mit den Post-Requsten her?

//Edit gefunden :lol:
the more they change the more they stay the same
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

So, eine neue Version

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import with_statement
import sys
if sys.version_info[0] < 3:
    from urllib2 import urlopen, Request
    from urllib import quote_plus, urlencode
else:
    from urllib.request import urlopen, Request
    from urllib.parse import quote_plus, urlencode

from contextlib import closing
import json

TRANSLATE_URL = 'http://ajax.googleapis.com/ajax/services/language/translate'
DETECT_URL = 'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q='

class MyBaseException(Exception):
    def __init__(self, val):
        self.val = val
    def __str__(self):
        return repr(self.val)

class TranslationError(MyBaseException):
    pass

class DetectError(MyBaseException):
    pass

def google_translate(text, from_, to, referer):
    '''Translates a text, from a given language to a given language
    using the google language-API'''
    if not all([text, from_, to]):
        raise ValueError('one or more empty argument(s)')
    
    data = urlencode({'v' : '1.0', 'q' : text, 'langpair' : '|'.join([from_, to])})
    request = Request(TRANSLATE_URL, data, {'Referer': referer})
    with closing(urlopen(request)) as stream:
        parsed_response = json.load(stream)
    
    if parsed_response['responseStatus'] == 200:
        return parsed_response['responseData']['translatedText']
    else:
        raise TranslationError(parsed_response['responseDetails'])
        
def google_detect_lang(text):
    '''Detects a language with the google detect-API'''
    with closing(urlopen(DETECT_URL  + quote_plus(text))) as stream:
        parsed_response = json.load(stream)
        
    if parsed_response['responseStatus'] == 200:
        return parsed_response['responseData']['language']
    else:
        raise DetectError(parsed_response['responseDetails'])

auto_google_translate = lambda text, to, ref: google_translate(text, google_detect_lang(text), to, ref)

if __name__ == '__main__':
    text = raw_input('Text to translate: ')
    to = raw_input('Translate to?: ')
    ref = raw_input('Referer?:' )
    #lang = google_detect_lang(text)
    #print lang
    #print google_translate(text, lang, to, ref)
    print auto_google_translate(text, to, ref)
the more they change the more they stay the same
Antworten