Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   Получение метатега keywords (https://javascript.ru/forum/server/72167-poluchenie-metatega-keywords.html)

wadim 14.01.2018 18:53

Почитал, много времени надо. Есть проще способ определить кодировку, пусть с и с большей погрешностью? Не понял зачем нужен вывод ошибок:
libxml_use_internal_errors(true); ??

Получение метатега - это ISO-8859-1

Даю полный код:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">



<?php

$value_title= '�òðàòåãèÿ èãðà';

echo iconv("CP1251", "UTF-8", $value_title);

?>


�òðàòåãèÿ èãðà - это CP1251 (должен быть, не точно)
Выдает: �òðà òåãèÿ ГЁГЈГ°Г
Раскодировать точно можно, правда первый символ не раскодируется.

laimas 14.01.2018 19:58

Цитата:

Сообщение от wadim
Есть проще способ определить кодировку, пусть с и с большей погрешностью?

Тут проблема несколько в иной плоскости. Страница эта не имеет мета тега указывающего кодировку, а переданная сервером через заголовок не учитывается. Если вы углублялись по данному вопросу, то читали видимо пути решения проблемы, как-то добавление в документ такого мета тега.

Конструктор DOMDocument позволяет указать кодировку документа, но это не действует на открываемый из файла документ, она определяется для операций сохранения.

Ваш код не поможет - уже на входе распознано не верно. А чтобы определить, что и как распознано неверно нужно перебрать символы и определить.

Если вся эта затея ради граббера со страниц, то лучше использовать парсеры готовые, которые не испытывают таких проблем. И таких много, и с ними можно оперировать структурой документа например также как в jQuery.

К примеру, получите эту страницу как file_get_contents() и выведите на экран, проблем с кодировкой не будет.


Цитата:

Сообщение от wadim
Не понял зачем нужен вывод ошибок: libxml_use_internal_errors(true); ??

С точки зрения DOMDocument эта страница не является HTML эталоном, имеет ошибки и парсер вместо работы будет их вываливать. При этом игнорировать их вывод через параметры в методе loadHTMLFile не получится, а libxml_use_internal_errors решает эту проблему.

wadim 14.01.2018 20:40

В моем коде чуть Выше все должно работать, если Вы смотрели внимательно. iconv, mb_convert_encoding - вообще не работают, так что давайте по порядку. Мне нужно чтобы работали эти функции или предложте аналог, или простой (относительно код замены кодировки). Парсеры - это сторонние проги, которые могут грузить сервер и не столь просты в освоении. file_get_contents() не подходит, в начале я писал какой метод (стандартный) использую для получения страницы сайта. Вот напишите код на подобии моего (который чуть выше) - чтобы работало, тогда будет гуд!

laimas 14.01.2018 20:49

Цитата:

Сообщение от wadim
iconv, mb_convert_encoding - вообще не работают

Почему не работают, все работает, если к месту. Заметьте, что в коде, что я писал, как таковая кодировка не изменятся, она как была UTF так и осталась, страница ее представления была распознана не та, и mb_convert_encoding просто вернул правильное представление.

Вы же не воочию открываете документ, а скриптом, а значит чтобы распознать всевозможные баги с кодировкой, нужно еще программно определить, во что не так определено. Для этого нет и не может быть "волшебного" кода в одну строку.

Цитата:

Сообщение от wadim
Парсеры - это сторонние проги, которые могут грузить сервер и не столь просты в освоении.

Парсеров много, и не все грузные, а уж освоение для многих и не требуется, достаточно знать CSS селекторы и методы JS/jQuery.

wadim 14.01.2018 21:10

Почему у меня mb_convert_encoding не вернул правильное представление?
Вот Вы уходите от ответа, спасибо что отвечаете вообще. Вот я писал что нужно правильно отобразить $value_title= '�òðàòåãèÿ èãðà'; Вот отобразите. Там CP1251 или CP1252 (надеюсь).

Кода в одну строку не надо, но и тяжелые решения все-равно выкину. Вот Вы utf-8 преобразуете в windows-1252:
$title = mb_convert_encoding($title, 'windows-1252', 'utf-8');
Не знаю почему но если брать стр с javascript.ru, то работает. Вообще мне utf-8 нужен как бы.

Еще странность есть - исходник у меня в windows-1251, а mb_detect_encoding() определяется как utf-8, как тут можно куда то двигаться?

Aetae 14.01.2018 21:36

Потому что всё это гадание на кофейной гуще. Встроенные функции чудес не творят. Отличить 1251 от 1252(или любой иной на 256 символов) можно только эвристически, чем встроенные функции не занимаются.(они делают очень приблизительные предположения на основе пары символов)
Способ, работающий в большинстве случаев: брать кодировку из хэдэра ответа и пулять оную сразу в new DomDocument('1.0', 'кодировка');. Если в хэдере нет кодировки и первый символ не BOM - считаем её равной 1251.
Ещё можно следующим шагом сначала брать meta charset и если ошиблись - уже перекодировать с точно известными параметрами.
Ну или гуглите многомудрые анализаторы, которые всё равно не дадут гарантии.

laimas 14.01.2018 21:58

Цитата:

Сообщение от wadim
Почему у меня mb_convert_encoding не вернул правильное представление?

Потому, что неверное определение. В get_headers(url) можно узнать точно в какой кодировке документ. А что касается того как ее распознал DOMDocument, то ответ на этот вопрос более сложный. Вы что собираетесь на пару со скриптом работать, он будет определять, а вы глядя на вывод сообщать ему верно ли и если нет то как исправить? :) Ведь мало того, что неверно определена кодировка, надо учитывать и то, в кокой кодировке вы это '�òðàòåãèÿ èãðà' отображаете. Возьмите этот текст и выведите его в браузере на странице с объявленными кодировками 1251 и utf, разница будет поразительная, а если при этом еще и саму страницу сохранять с разными кодировками, то результат будет также иным. То есть вы можете видеть совсем не то, что на самом деле есть. Определите запросом заголовков кодировку источника, чтобы хотя бы знать то ли вы видите на самом деле.

По ссылке есть картинка, и надо будет проверять комбинации на ней указанные чтобы определить.

laimas 14.01.2018 22:01

Цитата:

Сообщение от Aetae
брать кодировку из хэдэра ответа и пулять оную сразу в new DomDocument('1.0', 'кодировка');.

Это не поможет, это объявление не определяет кодировки документа открываемого из файла, если только не "угадал".

wadim 14.01.2018 22:48

Вот что может вернуть get_headers(url):
[0] => HTTP/1.1 200 OK
[1] => Date: Sat, 29 May 2004 12:28:13 GMT
[2] => Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
[3] => Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
[4] => ETag: "3f80f-1b6-3e1cb03b"
[5] => Accept-Ranges: bytes
[6] => Content-Length: 438
[7] => Connection: close
[8] => Content-Type: text/html

Где здесь кодировка указана? Остальные Ваши ответы завтра читать буду.

laimas 14.01.2018 22:55

Цитата:

Сообщение от wadim
Где здесь кодировка указана?

Значит мета тегом передается. Вот заголовки вашей темы:

[0] => HTTP/1.1 302 Moved Temporarily
[1] => Date: Sun, 14 Jan 2018 19:52:55 GMT
[2] => Content-Type: text/html; charset=utf-8
[3] => Content-Length: 0
[4] => Connection: close
[5] => Set-Cookie: __cfduid=d8fe7c22acc4f2223e8930e3516638cac15159595 75; expires=Mon, 14-Jan-19 19:52:55 GMT; path=/; domain=.javascript.ru; HttpOnly
[6] => Set-Cookie: vbsessionhash=442871cd85ad99e848562beabde621c1; path=/; domain=.javascript.ru; HttpOnly
[7] => Set-Cookie: vblastvisit=1515959555; expires=Mon, 14-Jan-2019 19:52:35 GMT; path=/; domain=.javascript.ru; secure
[8] => Set-Cookie: vblastactivity=0; expires=Mon, 14-Jan-2019 19:52:35 GMT; path=/; domain=.javascript.ru; secure
[9] => Cache-Control: private
[10] => Pragma: private
[11] => Location: http://javascript.ru/forum/server/72...-keywords.html
[12] => X-Content-Type-Options: nosniff
[13] => X-Frame-Options: sameorigin
[14] => Access-Control-Allow-Origin: http://javascript.ru
[15] => Access-Control-Allow-Credentials: true
[16] => Access-Control-Allow-Headers: User-Agent,Dnt,pragma,cache-control,authority
[17] => Server: cloudflare
[18] => CF-RAY: 3dd3236f1a174e48-DME
[19] => HTTP/1.1 200 OK
[20] => Date: Sun, 14 Jan 2018 19:52:55 GMT
[21] => Content-Type: text/html; charset=utf-8
[22] => Connection: close
[23] => Set-Cookie: __cfduid=d1d31a14e29eb01d07053d3911574acd115159595 75; expires=Mon, 14-Jan-19 19:52:55 GMT; path=/; domain=.javascript.ru; HttpOnly
[24] => Set-Cookie: vbsessionhash=400d34983d0a29c01826d97b3b6a1c0d; path=/; domain=.javascript.ru; HttpOnly
[25] => Set-Cookie: vblastvisit=1515959555; expires=Mon, 14-Jan-2019 19:52:35 GMT; path=/; domain=.javascript.ru
[26] => Set-Cookie: vblastactivity=0; expires=Mon, 14-Jan-2019 19:52:35 GMT; path=/; domain=.javascript.ru
[27] => Cache-Control: private
[28] => Pragma: private
[29] => X-Content-Type-Options: nosniff
[30] => X-Frame-Options: sameorigin
[31] => Access-Control-Allow-Origin: http://javascript.ru
[32] => Access-Control-Allow-Credentials: true
[33] => Access-Control-Allow-Headers: User-Agent,Dnt,pragma,cache-control,authority
[34] => Server: cloudflare
[35] => CF-RAY: 3dd3237290614e0c-DME

Дважды думаю понятно почему и пояснять не требуется. А вообще получать надо только нужное

get_headers($url, 1)['Content-Type'];

Если документ не перемещался, то будет значение заголовка, в противном случае массив.


Часовой пояс GMT +3, время: 00:59.