|
 1.6 Кб |
|
| Доброй ночи.
Нужно спарсить данные с нескольких сайтов.
Написал функцию, вроде всё работает, но есть проблема с кодировкой получаемых данных.
Два сайта используют кодировку "utf-8" и один использует "windows-1251".
После того, как данные получены вывожу в браузер, естественно данные с сайта с кодировкой "windows-1251" превращаются в "крокозяблы".
Пробовал при помощи curl_getinfo() получить значение заголовка "Content-Type", чтобы определить в какой кодировке выводить данные, но только с одного сайта получается полностью получить значение в виде "text/html; charset=utf-8", остальные возвращают просто "text/html;"
Подскажите, как решить данную проблему?
Скрипт прикрепил к сообщению | |
|
|
|
|
|
|
|
для: Slo_Nik
(25.04.2013 в 03:01)
| | Все русские буквы в кодировке UTF-8, на сколько я помню, состоят из русской Р+какой-либо символ, или из русской С+какой-либо символ. Значит если произвести в тексте поиск любых других букв кроме Р и С и они будут найдены, значит это Win1251.
<?php
if(preg_match('#[а-пт-яё]#i',$s)){
// win-1251
}else{
// utf-8
}
|
| |
|
|
|
|
|
|
|
для: Sfinks
(25.04.2013 в 09:31)
| | Круто ) | |
|
|
|
|
|
|
|
для: confirm
(25.04.2013 в 09:58)
| | А я эту mb_detect_encoding() долго пытался вспомнить, но так и не вспомнил =) | |
|
|
|
|
|
|
|
для: Slo_Nik
(25.04.2013 в 03:01)
| | А зачем проверять заголовки, вы же получаете контент, значит проверяйте mb_detect_encoding(string), и если возвращает utf, то действие, или наоборот, не возвращает, то действие. | |
|
|
|
|
|
|
|
для: confirm
(25.04.2013 в 09:57)
| | Прежде чем создавать здесь тему, я поискал в google.
Есть рекомендации о применении указанной Вами функции, но так же говориться, что эта функция работает неверно.
Вот ссылки
http://habrahabr.ru/post/107945/
http://webonrails.ru/post/1070/
это не все, просто остальные я не нашёл в истории браузера, а заново искать лень)))
Может я просто заморачиваюсь...
Идея моей функции такая(прикреплённый файл)
Есть многомерный массив, $data_agent, с данными сайта, адрес сайта и pattern для регулярки
В цикле я выполняю запросы к сайтам, получаю информацию и записываю в базу. На основе этой информации мне надо будет создать новые парсеры на эти же сайты.
Чтобы правильно записать в базу мне надо знать в какой кодировке данные получены от сайта.
Пробовал получить из curl_getinfo(), но в двух случаях из трёх получаю только тип text/html, а вот самой кодировки нет. От чего это зависит, может что-то делаю не так?
Может проще "подсмотреть" в какой кодировке страница и добавить ещё один элемент в массив для каждого сайта, где будет содержаться название нужной кодировки? | |
|
|
|
|
|
|
|
для: Slo_Nik
(25.04.2013 в 19:50)
| | Вам не нужна кодировка, вам важно знать в utf8 она или нет, и с данной задачей mb_detect_encoding() справляется без проблем. Вы же только с 1251 и utf работаете. | |
|
|
|
|
|
|
|
для: confirm
(25.04.2013 в 21:12)
| | Пока да, только эти две кодировки.
Количество сайтов увеличится потом, но думаю, что других кодировок не будет.
И всё таки повторюсь.
Может проще будет заранее прописать кодировку для сайта в массиве данных? | |
|
|
|
|
|
|
|
для: Slo_Nik
(25.04.2013 в 21:26)
| | Пропишите, я ведь не запрещаю :)
Смысл, чтобы перед парсингом воочию удостовериться, прописать...? Единственный смыл в прописке, так это чтобы второй раз не запускать проверку, если уже она есть в базе, но зачем проверять "глазами", если есть инструмент.
ВЫ можете еще получить и проверить мета данные. | |
|
|
|
|
|
|
|
для: confirm
(25.04.2013 в 21:55)
| | как проверяются мета данные? | |
|
|
|
|
|
|
|
для: Slo_Nik
(25.04.2013 в 22:34)
| | get_meta_tags(file_get_contents(url)) | |
|
|
|
|
|
|
|
для: confirm
(26.04.2013 в 03:38)
| | get_meta_tags() не подходит потому, что возвращает значение тех meta тегов у которых есть атрибут name.
И с mb_detect_encoding() тоже фигня получается.
Для всех трёх сайтов показала utf-8, но ведь одни сайт точно в windows-1251... | |
|
|
|
|
|
|
|
для: Slo_Nik
(27.04.2013 в 01:39)
| | URL сайта на котором не корректно детектируется напишите. | |
|
|
|
|
|
|
|
для: confirm
(27.04.2013 в 02:36)
| | http://www.votpusk.ru/firmlist.asp | |
|
|
|
|
|
|
|
для: Slo_Nik
(27.04.2013 в 02:57)
| |
<?
echo mb_detect_encoding(file_get_contents('http://www.votpusk.ru/firmlist.asp', false, null, 0, 1000),'utf-8', true) ? 'UTF' : 'NO';
|
А у меня он никак не утверждает, что в UTF.
mb_detect_encoding() в данном применении точно закосячит, если в коде где либо не в начале будет BOM. | |
|
|
|
|
|
|
|
для: confirm
(27.04.2013 в 03:12)
| | Благодарю за подсказку.
Чуть изменил Ваш пример, обошёлся без file_get_contents();
<?php
$con_type = mb_detect_encoding(substr($str, 0, 500), 'UTF-8', true) ? 'UTF-8' : 'Windows-1251' ;
?>
|
Только ещё один вопрос.
Если указать длину возвращаемой подстроки меньше 500, например 400, то кодировку уже не определяет, всем трём сайтам указывает одинаковую.
Почему это так зависит от длины строки? | |
|
|
|
|
|
|
|
для: Slo_Nik
(27.04.2013 в 22:46)
| | Ну да, я привожу пример работы с удаленными данными, потому и file_get_contents, а вы значит обошлись, хотя загружаете иным способом. )
Я в примере брал часть только затем, чтобы не грузить все, вдруг там размер километровый. Вы же для парсера вынуждены забирать все, так что смысла в substr($str, 0, 500 нет). Да и проверять кодировку сразу тоже нет необходимости - получили контент вас интересующий, а потом уже определись с его кодировкой.
Не может определиться со строкой меньшей длины наверное же потому, что на этом участке нет мультибайтных символов, ведь английским что utf, что нет, все одно один байт занимают. | |
|
|
|
|
|
|
|
для: confirm
(28.04.2013 в 02:52)
| | На счёт substr() конечно, не подумал как следует.
Вот с моментом определения кодировки я подумал, что будет лучше сразу её записать элементом массива. Потом, когда подготавливать к записи в базу, посмотреть этот элемент и уже решать, применять iconv() или нет, без определения кодировке в цикле. | |
|
|
|
|
|
|
|
для: Slo_Nik
(28.04.2013 в 09:32)
| | Вот этого я не знаю Если вы сперва забираете со всех сайтов, готовите эти данные, сохраняя их в массиве, а только потом записываете их в базу, то есть смысл в этом же массиве хранить и признак конвертирования. Хотя с другой стороны, парсер это ведь "не прочитать" body (хотя есть и классы которые разбирают документ на DOM-элементы), а пользуетесь регулярными выражениями, и какой тогда смыл для в этих выражениях учитывать кодировку, проще указать модификатор для utf, если вы пишите в базу в этой кодировке.
Беспокоится, что будут английские и при сохранении в базу нет смысла их конвертировать, тоже нет смысла - хотя английским символам и нужно по одному байту, в базе все равно резервируется больше одного байта на символ. То есть, если это забота об экономии места, то она напрасная.
В общем вам виднее, что и как делать, вы же делаете, не я, я не в курсе забот ваших. ) | |
|
|
|