// Parser for Google Translate package main import ( "fmt" "net/http" "net/url" "golang.org/x/net/html" ) // Requests and parses translation from Google func Translate(fromLang, toLang, text string) (string, error) { // Escape parameters before embedding in URL fromLang = url.QueryEscape(fromLang) toLang = url.QueryEscape(toLang) text = url.QueryEscape(text) url := fmt.Sprintf("https://translate.google.com/m?sl=%s&tl=%s&q=%s", fromLang, toLang, text) resp, err := http.Get(url) if err != nil { return "", fmt.Errorf("Request failed: %v", err) } doc, err := html.Parse(resp.Body) if err != nil { return "", fmt.Errorf("HTML parsing failed: %v", err) } res, err := walk(doc) if err != nil { return "", fmt.Errorf("Error parsing translation page: %v", err) } return res, nil } func walk(node *html.Node) (string, error) { // Check if element has a class of result-container if node.Type == html.ElementNode && node.Data == "div" { for _, attr := range node.Attr { if attr.Key == "class" && attr.Val == "result-container" { // Retrieve the content of it if content := node.FirstChild; content != nil { return content.Data, nil } else { return "", fmt.Errorf("result-container is empty") } } } } // Recursively walk through subelements for c := node.FirstChild; c != nil; c = c.NextSibling { if res, err := walk(c); err == nil { return res, err } } return "", fmt.Errorf("no result") }