CP1252 в UTF-8, как преобразовать кодировку

i-will-not-assume-untrusted-data-is-valid-utf-8_0

Взял недавно заказ на сбор информации из открытых источников, в просторечии, парсинг сайта. Использовал phpQuery как базу для написания граббера. Клиенту нужен был результат конечный, сам граббер не нужен. Сайтов было несколько, и в общей сложности собрал базу на 20 тысяч записей. Но речь не об этом. При грабе одного из сайтов столкнулся с небольшой проблемой.

Кириллическая кодировка выводилась в виде ??????????? / ???

на странице был прописан charset windows-1251

забирал контент донора через

$ch = curl_init($url);
$agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)";
@curl_setopt ( $ch , CURLOPT_USERAGENT , $agent );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($ch);
curl_close($ch);

потом $page скармливал phpQuery

$results = phpQuery::newDocument($page )

но phpQuery почему-то для скормленного ей контента ставила utf-8 (она себя так ведет если не может определить кодировку донора, т.е. ставит по умолчанию UTF-8 )

mb_internal_encoding() выдал что используется ISO-8859-1, это же подтвердил и анализ заголовков, с целевого донора

Date	Fri, 25 Sep 2009 19:54:06 GMT
Server	Microsoft-IIS/6.0
X-Powered-By	ASP.NET
X-AspNet-Version	2.0.50727
Location	************
Cache-Control	private
Accept-Charset	ISO-8859-1,utf-8;q=0.7,*;q=0.7
Content-Length	0

а ISO-8859-1 это не cp1251 а cp1252

Решение. Как преобразовать кодировку CP1252 в UTF-8 (в UTF-8 пишется в базу и скрипт сам в UTF-8 сохранен)

iconv('windows-1252','utf-8//IGNORE','текст');  непомогло

возвращало ??«???????°?®?±????& #195;? / ?‹???·

преобразование через mb_convert_encoding(‘текст’,mb_internal_encoding(), ‘UTF-8?); тоже не дало результат

Решение оказалось вот каким

$title= mb_convert_encoding($title,mb_detect_encoding($title , "CP1252"), 'UTF8');
$title= mb_convert_encoding($title,'UTF8', "CP1251");

если просто из CP1252 в UTF8 преобразовать то на выходе всеравно каракули (вопросительные знаки), приходится из UTF-8 в CP1251 преобразовывать и все ок

ps:вполне возможно что в вашем случае этот вариант не подойдет, рассмотрен частный случай, сервер с которого я парсил инфу своеобразно отдавал ее.
В странице была одна кодировка прописана тегом как CP1251, но на деле была CP1252, если смотреть заголовки.

UTF дергаю так как на моем хосте все своеобразно настроено )

в итоге смотрите по обстоятельствам

Тэги: , , , ,

Мы за небольшую сумму предлагаем вам у нашей фирмы купить цветы и заказать красивые букеты
  • 18 комментариев на “CP1252 в UTF-8, как преобразовать кодировку”

    1. ХАКЕР:

      «спасибо за инфу»

    2. S10:

      У меня наоборот, iconv win1521->utf8 помогло. Кодю тоже в юникоде, принимаемая инфа была в cp1251.

    3. saintist:

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

      ps: да тупо , но просто и быстро, решение нацеленное на результат

    4. S10:

      Да у Темы своей декодер с блэкджеком и шлюхами имеется :)

    5. saintist:

      палимся, палимся :)

    6. kitsune:

      Выручили :) спасибо!

    7. Mowshon:

      saintist, Вы говорите о http://www.artlebedev.ru/tools/decoder/?

    8. saintist:

      да

    9. Vetal:

      Хм… немного офтоп, но всё же…
      Как я смотрю, тут все юзают phpQuery.
      У меня вопрос — как заставить эту сволочь жрать меньше памяти???
      Есть файлы ~300 тыс. надо их разобрать.
      при прогоне ~300-500 файлов сжирается 500Мб памяти, а то и больше.
      И как я заметил, чем больше жрет памяти php, тем медленнее он работает.
      В скриптах использую unset(), но результата никакого.
      Написал другой парсер, по тем же фалам на рег. выражениях — память не жрется вообще никак. Как при запуске была в районе 35Mb так и осталась, и ужё почти все эти файлы пробежала.

      Так всё таки, как заставить phpQuery не жрать столько?

    10. saintist:

      палю тему:) я разбиваю на этапы процесс парсинга, в общих чертах так, сначала собираю базу url откуда сбор делать, т.е. берем сайт site.com и все его страницы запихиваю куда-нибуть в виде списка, потом беру по несколько штук за раз и собираю оттуда все что нужно, на слабеньком хостинге по 5 штук страниц с рефрешем в 2 секунды 500к страниц собираем примерно за суток 12-14, при этом не выходим из лимитов по нагрузке, единственный способ при котором пхпквери не ужирается в умат памятью

    11. saintist:

      phpQuery жрет немеряно, из-за этого иногда приходится от нее отказываться, если время поджимает

    12. Кристина:

      А мне вот нужно тоже как-то кодировку поменять на своем блоге. Но я не знаю, как сделать. Причем в некоторых местах русский хорошо определяется, а в некоторых пытаюсь изменить английский на русский, а в итогк получается «?????»

    13. saintist:

      кодировку файла можно поменять на нужную, файла который выдает контент, или в корень сайта положить htacces файл с правилом для отдачи контента в нужной кодировке

    14. Andrey:

      читайте доки, господа парсеры:
      phpQuery::unloadDocuments();

    15. saintist:

      1. Смотрим дату статьи
      2. Доки давно прочитаны
      3. Проблема относится не только к phpQuery

    16. Andrey:

      статья про кодировку, а в комментах ноют про память — вот я и написал решение

    17. saintist:

      я понял, спасибо

      хороший коммент, начинающим очень поможет,

    18. gumplenovic:

      Поделитесь пожалуйста каким поисковиком пользуетесь вы для поиска разнообразных русскоязычных ресурсов яндексом, гуглом или рамблером?
      И подскажите пожалуйста где наиболее точно можно поссмотреть прогноз погоды хотябы на несколько дней. Я смотрю погоду на яндексе, но мне кажется что он приверает. По крайней мере при ежедневном проссмтре погоды она постоянно меняется на яндексе.

    Оставить комментарий