Question:
Good day.
Faced such a problem: some sites are parsed adequately – the text from the forms gets in a readable encoding, and some do not.
At first, I sinned on UTF-8 on the site, but Go is a little bit with UTF-8 only and works by default
I get the page like this:
func FetchHTML(url string) (string, bool){
page := ""
resp, HttpErr := http.Get(url)
if HttpErr != nil {
err := HTTPError{url, "", HttpErr.Error()}
fmt.Println(err.Error())
return "", false
}
defer resp.Body.Close()
body, IoErr := ioutil.ReadAll(resp.Body)
if IoErr != nil {
fmt.Println("IO error: ", IoErr.Error())
return "", false
}
fmt.Println(body)
page = string(body)
fetched = true
return page, true
}
Examples:
For example, let's parse a quote from everyone's favorite ithappens.
I pass the page to the parser at http://ithappens.me/story/623
We get:
#623
КПД 100%
26 февраля 2009, 11:00
Приятель-программист поделился историей: написал для внутреннего пользования бенчмарк — в шестнадцати потоках перемножаются здоровенные матрицы. Все скомилировалось, запустилось и заработало, причем не просто быстро, а слишком быстро.
Матрицы перемножались мгновенно!
После разбора причин происходящего выяснилось, что тестовые матрицы представляли из себя массивы нулей. Умный интеловский компилято решил не загружать процессор перемножением и сложением нулей и оптимизировал код таким образом, чтобы сразу заполнить матрицы необходимого размера нулями.
Rating: 1866
Tags: чудеса техники, программы
Now we are trying to do the same, for example, with http://bash.im/quote/435048
We get:
#435048
2015-08-06 12:13
���: �� �������� ���� �������� ������, ��������� 15 ��� ������
���: ����� �������: ����, �� �� �����, �� ��� �� ������
���: �� ���, �� � ����. ��� � �� �����, � ����� ������� ����.
���: ���� �������, � ��� ��� ����� ��� ������ �����, �������� ������������ �� ������ ��������� ����� ������ ������
���: �� � � ������� �������, �������� - ���� �������������, ���������. �������������. ������: ���� �����, 158, 161, 162 (�����, ������, ������), ��������� ��� ��� �� �������� - ���� ����� ������� �� ������ �� ����������. (�� ����� ���� - �����, ����� ����� �� ���� � ������ ������ ������). �, ������, ���������, �� ��� ��� � �� �������.
���: ��� ��������, ��������
���: � ��� �������, ��� �� ��� ������.
���: ��������� ���������. ��������� �� ���������, �� 4 �����, ������� � ���� - ������ ������. ���� ������� �� �����, ������������ ������ - ����� ��� � �������� �����. ���, ��, ����� ����, ����� ����... ���� ����, ��� ���� �������� � ���� �����, ��� ��� � � ����� ����� ���� ����� ����� ��. � ������: ��-�������, ���� �������� �������.
���: ����!!! � � ���� ��������, �� ������� ������, �� �������!!!
Rating:
I noticed that while the bytes of text with ithappens are 1??, the bytes of text bash.im are over 200. What could be the problem and how to solve it?
Answer:
I recommend using the golang.org/x/net/html/charset package and its NewReader function itself.
This function takes the actual io.Reader
and Content-Type
header if present. The function parses the Content-Type
and the first 1024 bytes of the body and returns a UTF-8
encoded io.Reader
and an error, if any. Everything is simple and cool.
For example:
package main
import (
"fmt"
"golang.org/x/net/html/charset"
"io/ioutil"
"net/http"
)
func main() {
url := "http://bash.im/quote/435048"
resp, err := http.Get(url)
if err != nil {
fmt.Println("HTTP error:", err)
return
}
defer resp.Body.Close()
// вот здесь и начинается самое интересное
utf8, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type"))
if err != nil {
fmt.Println("Encoding error:", err)
return
}
// оп-па-ча, готово
body, err := ioutil.ReadAll(utf8)
if err != nil {
fmt.Println("IO error:", err)
return
}
fmt.Println(string(body))
}
What is good about this method is that it is universal. You can easily apply it to any site. And there's no need to fiddle around with tags like <meta ...>