пятница, 17 декабря 2010 г.

Парсинг кириллических доменов через Curl

Появилась задача распарсить содержание сайта с кириллическим доменом.
Попробовал вставить ссылку в стандартную обёртку для 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, пропадают в таком названии.
Взято отсюда: http://www.emag.iis.ru/arc/infosoc/emag.nsf/BPA/69dd2e0bf42863e8c325758a003fd78d

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

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

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

<?php

include_once('idna_convert.class.php');

$url = 'http://кириллическийдомен.рф';

$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);

$response = curl_exec($resource);

curl_close($resource);
?>
Код максимально упрощён для понимания сути решения.

1 комментарий:

  1. Работает, только не забываем качать конвертер)

    ОтветитьУдалить