@9StarRu

Как исправить кодировку сайта в ответ на cURL запрос?

Пожалуйста, помогите победить кодировку.

Проблема следующая, в ответ на curl приходит сайт в котором в meta прописана кодировка windows-1251 из-за этого на сайте отображаются иероглифы.
Данную проблему решил с помощью:

$isWinCharset = mb_check_encoding($postResult, "windows-1251");
if ($isWinCharset) {
    $postResult = iconv("windows-1251", "UTF-8", $postResult);
}


Теперь если в meta стоит кодировка windows-1251 сайт отображается корректно.
Если в meta стоит кодировка utf-8 сайт отображается корректно.
Обрадовался.
Но вдруг нашел пару сайтов, которые слетели после добавления:

$isWinCharset = mb_check_encoding($postResult, "windows-1251");
if ($isWinCharset) {
    $postResult = iconv("windows-1251", "UTF-8", $postResult);
}

в meta указана кодировка UTF-8 а сайт в результате в иероглифах, пример такого сайта: e-qa.ru/autoprodazha
Таких сайтов не много но они есть и очень раздражают, большинство сайтов где в meta UTF-8 работают корректно. Видимо кодировка самого файла у данного сайта e-qa.ru/autoprodazha отличается от указанной в meta из-за этого происходит конфликт.

Помогите разобраться и устранить иероглифы на всех сайтах, кучу методов перепробовал и все взаимоисключающие :(
  • Вопрос задан
  • 4462 просмотра
Решения вопроса 1
@remzalp
Программер чего попало на чем попало
Собственно Вам удаленный сайт уже и так всё говорит, почему бы не учесть то, что он говорит?

1. Заглядываем в заголовки HTTP ответа, видим:
Content-Type:text/html; charset=UTF-8
2. Заглядываем в контент страницы, видим:
<meta charset="UTF-8" />
3. Есть еще один метод подсказать кодировку:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Решение - смотрим, чего нам говорят, подставляем в качестве параметра для iconv, но не забываем дефолтное значение на всякий случай.
Вариант решения - если сайтов в ограниченное количество, храните где-то предпочитаемую кодировку.
Фрагмент на python, реализующий автоматическое декодирование на основании заголовка ответа:
encoding='utf-8' # кодировка по умолчанию
tmp = r.headers.get('Content-Type').split('=') #режем по =, что справа - кодировка
if len(tmp)>1: #если кодировка в заголовке есть - будет 2 элемента
    encoding=tmp[-1] # тогда берём последний
page = r.content.decode(encoding)


Итоговый ответ:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $engine_url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
....
//дополнить этим:
curl_setopt($ch, CURLOPT_HEADER, 1);

$tmpResult = curl_exec($ch);

$header_size = curl_getinfo($ch,CURLINFO_HEADER_SIZE);
curl_close($ch);

$tmpHeaders = substr($tmpResult, 0, $header_size);
$postResult = substr($tmpResult, $header_size);

$headers = array();
foreach(explode("\n",$tmpHeaders) as $header)
{
	$tmp = explode(":",trim($header),2);
	if (count($tmp)>1)
	{
		$headers[strtolower($tmp[0])] = trim(strtolower($tmp[1]));
	}
}

$encoding="utf-8"; //default
if (isset($headers['content-type']))
{
	$tmp = explode("=", $headers['content-type']);
	if (count($tmp)>1) $encoding = $tmp[1];
}
if ($encoding != "utf-8") $postResult = iconv($encoding, "UTF-8", $postResult);


Всё. Получаем расширенный ответ, который содержит заголовки. Вырезаем из него заголовки и режем их в массив, плюс достаём тело ответа.
Парсим заголовки http, вытаскиваем content-type и из него вытаскиваем кодировку
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы