gtranslate/translate.go

64 lines
1.4 KiB
Go
Raw Normal View History

2021-01-17 20:09:57 +00:00
// 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")
}