Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: curl, получить полностью content-type сервера
 
 автор: Slo_Nik   (25.04.2013 в 03:01)   письмо автору
1.6 Кб
 
 

Доброй ночи.
Нужно спарсить данные с нескольких сайтов.
Написал функцию, вроде всё работает, но есть проблема с кодировкой получаемых данных.
Два сайта используют кодировку "utf-8" и один использует "windows-1251".
После того, как данные получены вывожу в браузер, естественно данные с сайта с кодировкой "windows-1251" превращаются в "крокозяблы".
Пробовал при помощи curl_getinfo() получить значение заголовка "Content-Type", чтобы определить в какой кодировке выводить данные, но только с одного сайта получается полностью получить значение в виде "text/html; charset=utf-8", остальные возвращают просто "text/html;"
Подскажите, как решить данную проблему?
Скрипт прикрепил к сообщению

  Ответить  
 
 автор: Sfinks   (25.04.2013 в 09:31)   письмо автору
 
   для: Slo_Nik   (25.04.2013 в 03:01)
 

Все русские буквы в кодировке UTF-8, на сколько я помню, состоят из русской Р+какой-либо символ, или из русской С+какой-либо символ. Значит если произвести в тексте поиск любых других букв кроме Р и С и они будут найдены, значит это Win1251.
<?php
  
if(preg_match('#[а-пт-яё]#i',$s)){
    
// win-1251
  
}else{
    
// utf-8
  
}

  Ответить  
 
 автор: confirm   (25.04.2013 в 09:58)   письмо автору
 
   для: Sfinks   (25.04.2013 в 09:31)
 

Круто )

  Ответить  
 
 автор: Sfinks   (25.04.2013 в 11:35)   письмо автору
 
   для: confirm   (25.04.2013 в 09:58)
 

А я эту mb_detect_encoding() долго пытался вспомнить, но так и не вспомнил =)

  Ответить  
 
 автор: confirm   (25.04.2013 в 09:57)   письмо автору
 
   для: Slo_Nik   (25.04.2013 в 03:01)
 

А зачем проверять заголовки, вы же получаете контент, значит проверяйте mb_detect_encoding(string), и если возвращает utf, то действие, или наоборот, не возвращает, то действие.

  Ответить  
 
 автор: Slo_Nik   (25.04.2013 в 19:50)   письмо автору
 
   для: confirm   (25.04.2013 в 09:57)
 

Прежде чем создавать здесь тему, я поискал в google.
Есть рекомендации о применении указанной Вами функции, но так же говориться, что эта функция работает неверно.
Вот ссылки
http://habrahabr.ru/post/107945/
http://webonrails.ru/post/1070/
это не все, просто остальные я не нашёл в истории браузера, а заново искать лень)))

Может я просто заморачиваюсь...

Идея моей функции такая(прикреплённый файл)

Есть многомерный массив, $data_agent, с данными сайта, адрес сайта и pattern для регулярки

В цикле я выполняю запросы к сайтам, получаю информацию и записываю в базу. На основе этой информации мне надо будет создать новые парсеры на эти же сайты.

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

Пробовал получить из curl_getinfo(), но в двух случаях из трёх получаю только тип text/html, а вот самой кодировки нет. От чего это зависит, может что-то делаю не так?

Может проще "подсмотреть" в какой кодировке страница и добавить ещё один элемент в массив для каждого сайта, где будет содержаться название нужной кодировки?

  Ответить  
 
 автор: confirm   (25.04.2013 в 21:12)   письмо автору
 
   для: Slo_Nik   (25.04.2013 в 19:50)
 

Вам не нужна кодировка, вам важно знать в utf8 она или нет, и с данной задачей mb_detect_encoding() справляется без проблем. Вы же только с 1251 и utf работаете.

  Ответить  
 
 автор: Slo_Nik   (25.04.2013 в 21:26)   письмо автору
 
   для: confirm   (25.04.2013 в 21:12)
 

Пока да, только эти две кодировки.
Количество сайтов увеличится потом, но думаю, что других кодировок не будет.

И всё таки повторюсь.
Может проще будет заранее прописать кодировку для сайта в массиве данных?

  Ответить  
 
 автор: confirm   (25.04.2013 в 21:55)   письмо автору
 
   для: Slo_Nik   (25.04.2013 в 21:26)
 

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

ВЫ можете еще получить и проверить мета данные.

  Ответить  
 
 автор: Slo_Nik   (25.04.2013 в 22:34)   письмо автору
 
   для: confirm   (25.04.2013 в 21:55)
 

как проверяются мета данные?

  Ответить  
 
 автор: confirm   (26.04.2013 в 03:38)   письмо автору
 
   для: Slo_Nik   (25.04.2013 в 22:34)
 

get_meta_tags(file_get_contents(url))

  Ответить  
 
 автор: Slo_Nik   (27.04.2013 в 01:39)   письмо автору
 
   для: confirm   (26.04.2013 в 03:38)
 

get_meta_tags() не подходит потому, что возвращает значение тех meta тегов у которых есть атрибут name.

И с mb_detect_encoding() тоже фигня получается.
Для всех трёх сайтов показала utf-8, но ведь одни сайт точно в windows-1251...

  Ответить  
 
 автор: confirm   (27.04.2013 в 02:36)   письмо автору
 
   для: Slo_Nik   (27.04.2013 в 01:39)
 

URL сайта на котором не корректно детектируется напишите.

  Ответить  
 
 автор: Slo_Nik   (27.04.2013 в 02:57)   письмо автору
 
   для: confirm   (27.04.2013 в 02:36)
 

http://www.votpusk.ru/firmlist.asp

  Ответить  
 
 автор: confirm   (27.04.2013 в 03:12)   письмо автору
 
   для: Slo_Nik   (27.04.2013 в 02:57)
 

<?
echo mb_detect_encoding(file_get_contents('http://www.votpusk.ru/firmlist.asp'falsenull01000),'utf-8'true) ? 'UTF' 'NO';

А у меня он никак не утверждает, что в UTF.
mb_detect_encoding() в данном применении точно закосячит, если в коде где либо не в начале будет BOM.

  Ответить  
 
 автор: Slo_Nik   (27.04.2013 в 22:46)   письмо автору
 
   для: confirm   (27.04.2013 в 03:12)
 

Благодарю за подсказку.
Чуть изменил Ваш пример, обошёлся без file_get_contents();


<?php 
$con_type 
mb_detect_encoding(substr($str0500), 'UTF-8'true) ? 'UTF-8' 'Windows-1251' ;
?>


Только ещё один вопрос.
Если указать длину возвращаемой подстроки меньше 500, например 400, то кодировку уже не определяет, всем трём сайтам указывает одинаковую.
Почему это так зависит от длины строки?

  Ответить  
 
 автор: confirm   (28.04.2013 в 02:52)   письмо автору
 
   для: Slo_Nik   (27.04.2013 в 22:46)
 

Ну да, я привожу пример работы с удаленными данными, потому и file_get_contents, а вы значит обошлись, хотя загружаете иным способом. )
Я в примере брал часть только затем, чтобы не грузить все, вдруг там размер километровый. Вы же для парсера вынуждены забирать все, так что смысла в substr($str, 0, 500 нет). Да и проверять кодировку сразу тоже нет необходимости - получили контент вас интересующий, а потом уже определись с его кодировкой.
Не может определиться со строкой меньшей длины наверное же потому, что на этом участке нет мультибайтных символов, ведь английским что utf, что нет, все одно один байт занимают.

  Ответить  
 
 автор: Slo_Nik   (28.04.2013 в 09:32)   письмо автору
 
   для: confirm   (28.04.2013 в 02:52)
 

На счёт substr() конечно, не подумал как следует.
Вот с моментом определения кодировки я подумал, что будет лучше сразу её записать элементом массива. Потом, когда подготавливать к записи в базу, посмотреть этот элемент и уже решать, применять iconv() или нет, без определения кодировке в цикле.

  Ответить  
 
 автор: confirm   (28.04.2013 в 11:42)   письмо автору
 
   для: Slo_Nik   (28.04.2013 в 09:32)
 

Вот этого я не знаю Если вы сперва забираете со всех сайтов, готовите эти данные, сохраняя их в массиве, а только потом записываете их в базу, то есть смысл в этом же массиве хранить и признак конвертирования. Хотя с другой стороны, парсер это ведь "не прочитать" body (хотя есть и классы которые разбирают документ на DOM-элементы), а пользуетесь регулярными выражениями, и какой тогда смыл для в этих выражениях учитывать кодировку, проще указать модификатор для utf, если вы пишите в базу в этой кодировке.
Беспокоится, что будут английские и при сохранении в базу нет смысла их конвертировать, тоже нет смысла - хотя английским символам и нужно по одному байту, в базе все равно резервируется больше одного байта на символ. То есть, если это забота об экономии места, то она напрасная.

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

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования