Curl русские символы php

Записки PHP-шника

Появилась задача распарсить содержание сайта с кириллическим доменом.
Попробовал вставить ссылку в стандартную обёртку для Curl в PHP. Оказалось, что Curl не работает с такими ссылками. Чего и следовало ожидать 🙂

Покопавшись в Интернете, нашёл следующую информацию:

Для интернационализированных доменных имен решение, предлагаемое ICANN, основано на использовании преобразования Puny Code, которое трансформирует набор кодовых символов Unicode (как правило, UTF-8) в цепь символов ASCII уникальным и обратимым способом. Например, в названии доменного имени «académie-française.org» буквы с апострофами не являются кодами ASCII. Puny Code преобразует данное доменное имя в «xn—acadmie-franaise-npb1a.org», а, например, http://русский.idn.icann.org превращает в http://xn—h1acbxfam.idn.icann.org. При этом знаки, не являющиеся кодами ASCII, пропадают в таком названии.

Из сказанного выше следует,что до кириллических доменов можно достучаться ещё и по альтернативному адресу закодированному в Puny Code. Как показывает тестирование, как браузер, так и Curl отлично понимают адреса закодированные через Puny Code. То есть в принципе есть возможность распарсить кириллический домен, нужно только знать его закодированный адрес.

Для перекодирования доменного имени можно воспользоваться готовым решением., которое представлено тут http://www.phpclasses.org/browse/file/5845.html

Приведу решение на PHP для перекодирования доменного имени и получения содержимого страницы через Curl.

$converter = new idna_convert();
$domain = parse_url($url, PHP_URL_HOST);
$encoded_domain = $converter->encode($domain);
$url = str_replace($domain, $encoded_domain, $url);

$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_TIMEOUT, 30);
curl_setopt($resource, CURLOPT_MAXREDIRS, 10);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, true);

Читайте также:  Javascript if else if break

Источник

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

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

$isWinCharset = mb_check_encoding($postResult, "windows-1251"); if ($isWinCharset)

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

$isWinCharset = mb_check_encoding($postResult, "windows-1251"); if ($isWinCharset)

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

Помогите разобраться и устранить иероглифы на всех сайтах, кучу методов перепробовал и все взаимоисключающие 🙁

Собственно Вам удаленный сайт уже и так всё говорит, почему бы не учесть то, что он говорит?

1. Заглядываем в заголовки HTTP ответа, видим:
Content-Type:text/html; charset=UTF-8
2. Заглядываем в контент страницы, видим:

3. Есть еще один метод подсказать кодировку:

Решение — смотрим, чего нам говорят, подставляем в качестве параметра для 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)
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 и из него вытаскиваем кодировку

Источник

Перекодировка текста UTF-8 и WINDOWS-1251

Проблема кодировок часто возникает при написании парсеров, чтении данных из xml и CSV файлов. Ниже представлены способы эту проблему решить.

windows-1251 в UTF-8

$text = iconv('windows-1251//IGNORE', 'UTF-8//IGNORE', $text); echo $text;
$text = mb_convert_encoding($text, 'UTF-8', 'windows-1251'); echo $text;

UTF-8 в windows-1251

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text); echo $text;
$text = mb_convert_encoding($text, 'windows-1251', 'utf-8'); echo $text;

Когда ни что не помогает

$text = iconv('utf-8//IGNORE', 'cp1252//IGNORE', $text); $text = iconv('cp1251//IGNORE', 'utf-8//IGNORE', $text); echo $text;

Иногда доходит до бреда, но работает:

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text); $text = iconv('windows-1251//IGNORE', 'utf-8//IGNORE', $text); echo $text;

File_get_contents / CURL

Бывают случаи когда file_get_contents() или CURL возвращают иероглифы (Алмазные борÑ) – причина тут не в кодировке, а в отсутствии BOM-метки.

$text = file_get_contents('https://example.com'); $text = "\xEF\xBB\xBF" . $text; echo $text;

Ещё бывают случаи, когда file_get_contents() возвращает текст в виде:

Это сжатый текст в GZIP, т.к. функция не отправляет правильные заголовки. Решение проблемы через CURL:

function getcontents($url) < $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); $output = curl_exec($ch); curl_close($ch); return $output; >echo getcontents('https://example.com');

Источник

Как скачать файл с кириллицей в URL?

Добрый вечер! Пишу небольшой парсер новостей. Возникла проблема со скачиванием файлов с кириллическими символами в url.

http://blobproxy-cdn.skoda-auto.com/wwk2-sitecollectionimages/news/march/škoda_на_ралли_акрополис_(2)__201403302311.jpg http://blobproxy-cdn.skoda-auto.com/wwk2-sitecollectionimages/news/march/в_млада-болеславе_произведено_11_000_000_автомобилей_škoda_201403302311.jpg
$url = urlencode('http://blobproxy-cdn.skoda-auto.com/wwk2-sitecollectionimages/news/march/в_млада-болеславе_произведено_11_000_000_автомобилей_škoda_201403302311.jpg'); $url = str_replace(array('%3A','%2F'), array(':','/'), $url); $data = file_get_contents($url);

Привет! ) Да — это решение! Спасибо большое. Я тоже думал эти символы поменять, но до дела не дошло)))

FlameStorm

http://some.domain.org//Uploads/images/408/А,Б%20секция%203%20этаж%204%20квcrop.jpg

т.е. смесь бульдога с носорогом — и слэши лишние, и нелатиница, и пробел в форме %20 .

Помогло следующее решение, по мотивам Andr’U Sender :

if (preg_match('#^([\w\d]+://)([^/]+)(.*)$#iu', $filenameSrc, $m)) < $filenameSrc = $m[1] . idn_to_ascii($m[2], IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) . $m[3]; >$filenameSrc = urldecode($filenameSrc); $filenameSrc = rawurlencode($filenameSrc); $filenameSrc = str_replace(array('%3A','%2F'), array(':', '/'), $filenameSrc);

Замечу, что если пытаться использовать urlencode , а не rawurlencode , то тот кодирует пробелы в «+» плюсы и ссылка открываться не желала в таком виде. А с %20 как делает rawurlencode — прокатило.

Надеюсь кому-то спасёт немного волос 🙂

Источник

Форум PHP программистов ► PHP практикум ► GD, XML, CURL, PEAR & PECL

Профиль
Группа: Пользователь
Сообщений: 9
Пользователь №: 37550
На форуме:
Карма:

При заполнении Google формы с помощью CURL не передаются русские символы. Например при выполнении кода ниже в поле category будут записаны только «_test» вместо «тест_test». Пробовал перекодировать через iconv, не помогло. Есть идеи?

php 
$name = "name1";
$category = "тест_test";
$category=iconv("cp1251","utf-8",$category);
$image = "image1";
$description = "description1";
// Создаем подключение
if( $curl = curl_init() )

// Задаем ссылку
curl_setopt($curl,CURLOPT_URL,'https://docs.google.com/forms/d/15U0zCAAblPxTZLa8vMoHSXRwJLUjpmd3AwmhvRSDy_s/formResponse');

// Нужно помнить кукисы!
curl_setopt($curl, CURLOPT_COOKIESESSION, TRUE);
curl_setopt($curl, CURLOPT_COOKIEFILE, "cookiefile");

// Скачанные данные не выводить поток
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);

// Активируем GZIP сжатие трафика
curl_setopt($curl,CURLOPT_ENCODING,'gzip,deflate');

// напишем в юзер-агент неправду
curl_setopt($curl,CURLOPT_USERAGENT,'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');

// Нужно вывести http заголовки в массив
curl_setopt($curl,CURLOPT_HEADER,true);

// Если все ок, в $html вернется html код главной страницы
if( $html = curl_exec($curl) )

// Указываем куда отправлять запрос
curl_setopt($curl,CURLOPT_URL,'https://docs.google.com/forms/d/15U0zCAAblPxTZLa8vMoHSXRwJLUjpmd3AwmhvRSDy_s/formResponse');

// Указываем подключению, что слать нужно не GET (по умолчанию), а POST запросы
curl_setopt($curl,CURLOPT_POST,TRUE);

// Указываем, что именно отправлять в POST данных, на этой стадии происходит ввод логина/пароля
curl_setopt($curl,CURLOPT_POSTFIELDS,"entry.1243554843=$name&entry.1359298278=$category&entry.228695742=$image&entry.1784795327=$description&submit=ok");

// Скачиваем
$out = curl_exec($curl);

// Показываем скачанные данные
echo $out;

>
// Закрываем соединение
curl_close($curl);
>

?>

Источник

Оцените статью