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

wadim 12.01.2018 21:29

Получение метатега keywords
 
Есть код php. New - редактировал: keywords уже не нужен, заменил на title:

$dom= new DOMDocument('1.0');
@$dom->loadHTMLFile($url);

$title= $dom->getElementsByTagName('title');
$value_title= $title->item(0)->nodeValue;

$value_title= mb_convert_encoding($value_title,'HTML-ENTITIES','UTF-8');


Кодировка не работает.

laimas 13.01.2018 02:13

И зачем это mb_convert_encoding($value_title,'HTML-ENTITIES','UTF-8')?

wadim 13.01.2018 08:49

В смысле зачем? Если спрашиваю - значит нужно. Я думаю что такое тема кодировка понятна. В $value_title абракадабра, мне нужно чтобы русские слова были читабельны. Хотя бы для просмотра это нужно, там стоит так же вопрос как сравнивать слова в разных кодировках.

laimas 13.01.2018 09:04

А что в UTF не читаются и зачем в HTML-сущности преобразовывать? Уж если не получается, то не мешало бы сначала выяснить кодировка у исходника.

wadim 13.01.2018 10:35

У исходника разная кодировка может быть, так как сайты и на windows 1251 и на UTF-8 могут быть. А что в UTF не читаются? - не понял вопроса. Я пытаюсь в UTF-8 перевести. Зачем в HTML-сущности преобразовывать? - это Вы про loadHTMLFile($url);? Ну так мне нужно, мож Вы другую архитектуру знаете? Напишите, буду благодарен.

laimas 13.01.2018 11:02

Цитата:

Сообщение от wadim
сайты и на windows 1251 и на UTF-8 могут быть

Ну так определите кодировку исходника и только потом если требуется такая операция, то iconv(). Второй параметр функции mb_convert_encoding() указывает кодировку, в которую требуется перекодировать, а не то, что вы думаете. А третий параметр как раз указывает кодировку исходника, может быть и массивом, а может быть и опущен.

Так во что вы пытаетесь перекодировать? Даже с учетом того, что вы ошибаетесь, найдите хотя бы один сайт, в котором есть ключевые слова требующие HTML-сущностей.

wadim 13.01.2018 12:55

Все понял что Вы сказали, но ни чего не помогло. Исходник в UTF-8, два варианта не помогли:

$value_title= iconv("UTF-8", "UTF-8", $value_title);

$value_title= mb_convert_encoding($value_title, 'UTF-8', 'UTF-8');

Тут вопрос возник зачем вообще преобразовывать UTF-8 в UTF-8, и так по русски должно выводится.

Попробовал так:
$value_title= iconv("UTF-8", "windows-1251", $value_title);

так как windows-1251 у меня часто срабатывало в других проектах. Вообще ни чего не выводит.

Ключевые слова пытаюсь перекодировать. Я не пытаюсь ключевые слова
перекодировать в HTML-сущности, наверно Вы имеете в виду это: @$dom->loadHTMLFile($url);
Но тут все правильно, этот код мне нужен.

laimas 13.01.2018 13:02

Цитата:

Сообщение от wadim
Я не пытаюсь ключевые слова перекодировать в HTML-сущности

mb_convert_encoding($value_title,'HTML-ENTITIES','UTF-8') - это значение $value_title из UTF-8 в HTML-ENTITIES. Читайте документацию.

Цитата:

Сообщение от wadim
Тут вопрос возник зачем вообще преобразовывать UTF-8 в UTF-8, и так по русски должно выводится.

Естественно возникает, это пустое и бесполезное занятие.

URL с чего вы пытаетесь получить приведите.

wadim 13.01.2018 13:26

URL любой может быть. Я взял с произвольного сайта документ и записал себе в файл:

<title> Стратегия игра </title>

Дальше прочел этот файл через URL.

laimas 13.01.2018 15:40

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

К примеру возьмем эту страницу, заголовок ее получим как ПолученР...., то есть utf-8 (детектирование кодировки покажет, что это utf) будет распознано как latin-1 (windows-1252). Вернем нормальную кодировку:

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTMLFile(\'https://javascript.ru/forum/misc/72167-poluchenie-metatega-keywords.html\');
$title = $dom->getElementsByTagName('title')->item(0)->textContent;
echo $title; //результат Получение метатега keywords - Javascript-форум
//восстановим
$title = mb_convert_encoding($title, 'windows-1252', 'utf-8');
echo $title; //результат Получение метатега keywords - Javascript-форум

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'];

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

wadim 15.01.2018 12:18

Все-таки я не понял, почему кодировка utf-8 не отображается правильно, ведь должна раз это utf-8. Почему utf-8 по разному смотрится?

Aetae 15.01.2018 12:20

Уверен ли ты что там именно utf8? Если уверен, то сами php файлы точно в utf8? А хедер, утверждающий что кодирока именно utf8 ты ставишь?

wadim 16.01.2018 16:52

Всю тему подсказывают как проверить что utf8, думаю точно utf8. На фиг хедер? Вопрос не о том чтобы как можно больше в файл установок напихать, а о том как вообще работает кодировка. Чуть выше я писал что именно меня интересует. Я ни знаю и ни кто не знает на этом форуме этот вопрос. Читайте внимательней вопросы.

laimas 16.01.2018 17:25

Цитата:

Сообщение от wadim
На фиг хедер?

Проанализируйте содержание того, что вы запрашиваете, поймете.

Цитата:

Сообщение от wadim
Вопрос не о том чтобы как можно больше в файл установок напихать, а о том как вообще работает кодировка.

Криво работает, насколько вы можете убедится. А значит надо разобраться почему. Я уже писал, что данная страница не имеет мета тега указывающего кодировку документа, а метод loadHTMLFile заголовки не анализирует. Хотите парится с DOMDocument, тогда так, как уже ранее писалось:

$html = file_get_contents(\'https://javascript.ru/forum/misc/72167-poluchenie-metatega-keywords.html\');

$dom = new DOMDocument();
libxml_use_internal_errors(true);

$dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $html);

$title = $dom->getElementsByTagName('title')->item(0)->textContent;

echo $title; //Получение метатега keywords - Javascript-форум


И чтобы это сделать, нужно знать, что данный документ в UTF, а для этого - имеется ли метатег, если нет, то анализировать заголовок.

wadim 17.01.2018 09:15

Проанализируйте содержание того, что вы запрашиваете, поймете. - это я понимаю, только что что подразумевали под хедер? Я думаю это:
<? header("Content-Type: text/html; charset=utf-8"); ?>
Так или иначе по моей логике последнее слово в за установкой кодировки остается за html документом. Я этот код убрал за ненадобностью:
<? header("Content-Type: text/html; charset=utf-8"); ?>
Хотя бывает что не работает на своем сайте кодировка, тогда выручает даже не этот код, а такой:
<? header("Content-Type: text/html; charset=windows-1251"); ?>
Вот и возникает вопрос что за хрень творится с кодировкой, а для этого надо знать не как это исправить, а по чему так происходит. И сейчашний вопрос о том же.
DOMDocument - почему Вы говорите что я парюсь с ним? Чем лучше file_get_contents? DOMDocument быстрей, если надо работать с содержимым страницы, а мне это и надо. Ваш код хорош, но он в два раза медленней, так как там загружаем и file_get_contents и loadHTML. Но можно пробовать и так.
...имеется ли метатег, если нет, то анализировать заголовок. - что за заголовок? title? Что анализировать то? Напишите пожалуйста то что Вы писали, но в полном варианте (код).

laimas 17.01.2018 10:10

Я не знаю что еще можно рассказать по данному вопросу.

1) <? header("Content-Type: text/html; charset=utf-8"); ?> - к контексту данной темы отношения не имеет, ибо вы получая контент стороннего сайта не можете заставить его передать заголовок. А заголовок не обязательно может передаваться РНР, это может делать и Apache. О коллизиях передачи кодировки посредством заголовка и мета тега читайте в сети, есть такое, пересказывать это здесь нет смысла.

2) "Я этот код убрал за ненадобностью ... тогда выручает даже не этот код, а такой" - это потому, что вы не анализируете данные, а действуете методом "научного тыка". Поэтому у вас и "возникает вопрос что за хрень творится с кодировкой". А надо не тыкать, а определить кодировку. Почему она криво определяется, это с вопрос к разработчику. Как это можно решить я показывал. Но решение то основано не на методе тыка, а вставлено ее определение именно такой, в какой и приходит документ.

3) Чем лучше file_get_contents? DOMDocument быстрей - file_get_contents не может быть ни лучше, ни хуже DOMDocument, это кардинально разные вещи, и говорить о скоростях бессмыслица. Вы уж проанализируйте код дабы понять почему file_get_contents.

4) Что анализировать то? - открываем отладчик браузера и запрашиваем страницу этой темы. Смотрим структуру этого документа и видим, что данная страница не имеет указания кодировки посредством <meta http-equiv="Content-Type" content="text/html; charset=utf-8">. А как узнать программно кодировку документа? Только анализируя соответствующий заголовок передаваемый сервером. Узнав ее формируем тег <meta http-equiv="Content-Type" что_узнали> и далее как показано.

Так понятно почему file_get_contents и loadHTML?


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