Имеется проблема с парсингом страниц абстрактного сайта.
Изначально отправлялся запрос посредством модуля request, где в body приходили верные данные, но потом возникла потребность имитировать браузер через puppeteer (chromium).
Прямое открытие страницы браузером через GET выдаёт так называемые "кракозябры", однако AJAX запрос возвращает нормальный ответ.
Заголовки ответа:
content-encoding: br
content-type: text/plain
Данные при открытии страницы (мониторинг сети):
Preview: ХОНДА ЦИВИК
Response: ХОÐДРЦИВИК
Отображение на самой странице: ХОНДА Р¦РР’РРљ
Простой AJAX запрос:
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "<url>");
oReq.send();
и верный ответ: ХОНДА ЦИВИК
Попытки раскодировки (с помощью модуля iconv-lite/iconv) имеют неполный успех, некоторые данные теряются.
Первая проба - раскодировать ответ, который де-факто отображается.
page.goto(uri).then(async (response) => {
const content = await page.evaluate(() => document.body.innerText);
const dataToSave = iconv.encode(iconv.decode(Buffer.from(content), 'utf8'), 'win1251').toString();
//ХОНДА Ц�?В�?К , потеряна заглавная И (� ), в других словах могут быть потеряны также некоторые другие буквы русского алфавита.
})
Вторая попытка - получить буфер и попытаться раскодировать его, имея приблизительные данные о возможной кодировке.
page.goto(uri).then(async (response) => {
const data = await response.buffer();
iconv.encode(iconv.decode(data, 'utf8'), "windows-1252");
//ХО�?Д�? ЦИВИК , потери более явные, из замеченного - э я с А Н Ё
iconv.encode(iconv.decode(data, 'utf8'), "iso88591");
//Х�?Н�?А Ц�?�?�?�? , потеряно более чем
iconv.encode(iconv.decode(data, 'utf8'), "binary");
//Х�~Н�А Ц������a
})
Буфер, получаемый через 2 способ ( C3 90 C2 A5 C3 90 C5 BE C3 90 C2 9D C3 90 E2 80 9D C3 90 C2 90 20 C3 90 C2 A6 C3 90 CB 9C C3 90 E2 80 99 C3 90 CB 9C C3 90 C5 A1 ) попытался прогнать по всем доступным кодировкам iconv-lite:
iconv.encodings = require("iconv-lite/encodings");
const uniqEncodings = [];
for(const encoding in iconv.encodings) {
if(iconv.encodings[encoding].constructor.name == "Object") {
uniqEncodings.push(encoding);
}
}
const hex = `C3 90 C2 A5 C3 90 C5 BE C3 90 C2 9D C3 90 E2 80 9D C3 90 C2 90 20 C3 90 C2 A6 C3 90 CB 9C C3 90 E2 80 99 C3 90 CB 9C C3 90 C5 A1`.toLowerCase().replace(/ /g, "");
let txtTest = "";
const buffer = Buffer.from(hex, "hex");
for(let i = 0; i < uniqEncodings.length; ++i) {
txtTest += `${uniqEncodings[i]}: ${iconv.encode(buffer, uniqEncodings[i]).toString()}\n`;
}
Результат
utf8: ХОÐДРЦИВИК
cesu8: ХОÐДРЦИВИК
ucs2: � � � ~� � � � � � � � �� � �� a
binary: Х�~Н�А Ц������a
base64:
hex:
utf32le: � � � ~ � � � � � � � � � � � � � a
utf32be: � � � ~ � � � � � � � � � � � � � a
maccenteuro: ???�???�?? ?????�???�
cp808: ?????????? ??????????
mik: ?????????? ??????????
cp720: ?????????� ??????????
windows874: ???????�?? ?????�????
windows1250: ???�???�?? ?�???�???�
windows1251: ???????�?? ?�???�????
windows1252: ХО�?Д�? ЦИВИК
windows1253: ?�?????�?? ?�???�????
windows1254: ?�?????�?? ?�?�?�?�?�
windows1255: ?�?????�?? ?�?�?�?�??
windows1256: ?�?????�?? ?�???�????
windows1257: ???�???�?? ?�???�???�
windows1258: ?�?????�?? ?�?�?�?�??
iso88591: Х�?Н�?А Ц�?�?�?�?
iso88592: ???�?�???� ?????????�
iso88593: ?????�???� ??????????
iso88594: ???�?�???� ?????????�
iso88595: ?????�???� ??????????
iso88596: ?????�???� ??????????
iso88597: ?????�???� ?�???�????
iso88598: ?�???�???� ?�????????
iso88599: ?�???�???� ?�????????
iso885910: �?мН�?А �?�?�?�?к
iso885911: ?????�???� ??????????
iso885913: ???�?�?�?� ?�???�???�
iso885914: ?????�???� ??????????
iso885915: ХиН�?А �?�?�?�?Ш
iso885916: ???�?�?�?� ?????????�
cp437: ?�???????? ??????????
cp737: ?????????? ??????????
cp775: ???�???�?? ?�???�???�
cp850: Ѿ�?�?�?�? ���?�?�?�?
cp852: ???�?????? ?????????�
cp855: ?????????? ??????????
cp856: ?�???????? ?�????????
cp857: ?�???????? ?�????????
cp858: Ѿ�?�?�?�? ���?�?�?�?
cp860: ?????????? ??????????
cp861: �?�?�?�?�? �?�?�?�?�?
cp862: ?�???????? ??????????
cp863: ?????????? ?�????????
cp864: ?????????? ?�????????
cp865: ?????????? ??????????
cp866: ?????????? ??????????
cp869: ?????????? ?�???�????
cp922: ?�?�?�???� ?�???????�
cp1046: ?????????? ??????????
cp1124: ?????�???� ??????????
cp1125: ?????????? ??????????
cp1129: ?�???�???� ?�????????
cp1133: ?????�???� ?�????????
cp1161: ?????????? ?�????????
cp1162: ?????�?�?� ?????�????
cp1163: ?�???�???� ?�????????
maccroatian: ???�???�?? ???�?�?�?�
maccyrillic: ???????�?? ?????�????
macgreek: ?�?????�?? ?�???�????
maciceland: ܴ�?�?���? �?�������?
macroman: ?�?????�?? ???�?�?�??
macromania: ?�?????�?? ???�?�?�??
macthai: ???????�?? ?????�????
macturkish: ?�?????�?? ???�?�?�??
macukraine: ???????�?? ?????�????
koi8r: ?????????? ??????????
koi8u: ?????????? ??????????
koi8ru: ?????????? ??????????
koi8t: ???????�?? ?�???�????
armscii8: ?????�???� ??????????
rk1048: ???????�?? ?�???�????
tcvn: ?????????? ??????????
georgianacademy: ?�???�?�?� ?�?�?�?�?�
georgianps: ?�???�?�?� ?�?�?�?�?�
pt154: ???????�?? ?????�????
viscii: ?????????? ??????????
iso646cn: ?$???????? ??????????
iso646jp: ?\???????? ??????????
hproman8: ��?��?� �?��?���
macintosh: ?�?????�?? ???�?�?�??
ascii: ?????????? ??????????
tis620: ?????????? ??????????
shiftjis: ?\?????�h?? ?????�f????
eucjp: ?\?���???��?? ?���???��???���
cp936: ???????��?? ?????��????
gbk: ???????��?? ?????��????
gb18030: �0�4�0�6�0�4�0�6�0�4�0�9�0�4���0�4�0�6 �0�4�0�7�0�4�0�0�0�4���0�4�0�0�0�4�0�8
cp949: ��?��?��?������? ��?��?������?��?
cp950: ???????��?? ?????��????
big5hkscs: ???????��?? ?????��????
Попытка раскодировать оригинальный ответ (ХОÐДРЦИВИК) посредством сторонних сайтов в условных 9/10 случаев дал абсолютно аналогичный iconv-lite'у результат, однако единственный 1/10 с помощью
2cyr с исходным в utf8, отображаемым как cp1252, собственно, конвертировал в абсолютно верные данные (не учитывая Р, которая при повторном копировании зашифрованного текста превращается в неизвестный символ по причине изменения пробела на nbsp).
В Firefox имеется функция угадывания правильной кодировки текста по содержимому страницы, что также работает превосходно. Модуль iconv-lite и iconv ранее работали в соответствии с нормами, кроме того, пробовал более нативные способы конвертации, а также некоторые специализирующиеся сайты декодеры, что приводило к потере.
Какой может быть источник проблемы? И как, если так выражаться, "по нормальному" получать то что требуется?
Из костыльных мыслей имеется имитация AJAX запроса в evaluate, вывод в консоль и перехват с помощью page.on("console"), но это же есть не совсем корректно, не так ли?