рег.выражения (кодировка)

Snoopik
На сайте с 20.02.2009
Offline
29
690

Опять всем привет.

Появился вопрос.

При парсере тайтлов с сайтов, проблемы с кодировкой.

А тоесть, вот скрипт:


$url = file_get_contents ( 'http://yandex.ru/' );

function title($url){

$url=iconv("UTF-8", "CP1251", $url);

if(preg_match("!<title>(.*?)</title>!si",$url,$ok))
$str=$ok[1];

return trim($str);
}

$title = title($url);

echo $title;

Здесь он парсит с яндекса и всё нормально.

Ну а если парсить с сайта где кодировка не utf-8 ничего не выдаст.

Проблема заключается в том, как сделать, чтобы в обоих случаях.

Если убрать iconv , то все, что не utf-8 отображается, а utf-8 наоборот нет.

Подскажите,что делать.

Нашёл решение:


$url = utf8_convert($url, "w");

function utf8_convert($str, $type)
{
static $conv = '';
if (!is_array($conv))
{
$conv = array();
for ($x=128; $x <= 143; $x++)
{
$conv['utf'][] = chr(209) . chr($x);
$conv['win'][] = chr($x + 112);
}
for ($x=144; $x<= 191; $x++)
{
$conv['utf'][] = chr(208) . chr($x);
$conv['win'][] = chr($x + 48);
}
$conv['utf'][] = chr(208) . chr(129);
$conv['win'][] = chr(168);
$conv['utf'][] = chr(209) . chr(145);
$conv['win'][] = chr(184);
}
if ($type == 'w')
{
return str_replace($conv['utf'], $conv['win'], $str);
}
elseif ($type == 'u')
{
return str_replace($conv['win'], $conv['utf'], $str);
}
else
{
return $str;
}
}
public class SearchEngines
wdsg
На сайте с 09.02.2009
Offline
31
#1

Snoopik, работайте с UTF-8. Определяйте кодировку сайта и конвертируйте из определённой кодировки в UTF-8. А уже потом всё остальное.

Проектирование и разработка сложных IT-систем. Вожусь с проблемными задачами.
[Удален]
#2
Snoopik:
Опять всем привет.
Появился вопрос.
При парсере тайтлов с сайтов, проблемы с кодировкой.
А тоесть, вот скрипт:

$url = file_get_contents ( 'http://yandex.ru/' );

function title($url){

$url=iconv("UTF-8", "CP1251", $url);

if(preg_match("!<title>(.*?)</title>!si",$url,$ok))
$str=$ok[1];

return trim($str);
}

$title = title($url);

echo $title;

Здесь он парсит с яндекса и всё нормально.
Ну а если парсить с сайта где кодировка не utf-8 ничего не выдаст.
Проблема заключается в том, как сделать, чтобы в обоих случаях.
Если убрать iconv , то все, что не utf-8 отображается, а utf-8 наоборот нет.
Подскажите,что делать.

iconv надо делать к тому что выходит после preg_match, а не до. Английские символы и знаки препинания во всех кодировках имеют одинаковые коды, и при таких регулярках плевать на кодировку исходной страницы.

А уж что получили приводите к одной кодировке, лучше к утф8. Лучше использовать не iconv а mb_convert_encoding, но у него с некоторыми кириллическими кодировками трабл. Я давно где то в инете нашел либу x_charset_lib.php, кто автор не знаю, но она короче умеет сама распознавать кодировку кириллического текста и конвертить в указаннаю. работает безотказно.

[Удален]
#3

<?php

if ( 'cli'!==php_sapi_name() ||
__FILE__!==$_SERVER['argv'][0])
{
print 'For Command Line Use Only';
exit();
}


function getTitleFromUrl($url, &$executionTime)
{
$start = microtime(true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
$headerContentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);

if ( !empty($html) )
{
$title = array();
preg_match('/<title>(.*)<\/title>/i', $html, $title);
if ( !empty($title[1]) )
{
$encoding = '';
if ( empty($encoding) )
{// если сервер не вернул тип документа, то попытаемся найти его в html-е документа
// print 'Trying to get encoding from html<br/>';
$htmlMeta = array();
preg_match('/<meta([^<.]*http\-equiv=["\'`]?content\-type["\'`]?.*?)\/?>/i', $html, $htmlMeta);
if ( !empty($htmlMeta[1]) )
{// если удалось найти тег, описывающий тип документа
// print 'Seems to found meta tag: [<b>'.$htmlMeta[1].'</b>]<br/>';
$htmlContentType = array();
preg_match('/content=["\'`]([^"^\'^`.]*)["\'`]/i', $htmlMeta[1], $htmlContentType);
if ( !empty($htmlContentType[1]) )
{// если тип документа удалось определить
// print 'Seems to found content-type: [<b>'.$htmlContentType[1].'</b>]<br/>';
$htmlEncoding = array();
preg_match('/charset=(.*)/i', $htmlContentType[1], $htmlEncoding);
if ( !empty($htmlEncoding[1]) )
{// если тип документа содержит кодировку
$encoding = strtoupper(trim($htmlEncoding[1]));
// print 'Seems to found encoding in html: [<b>'.$encoding.'</b>]<br/>';
}
}
}
}
if ( empty($encoding) )
{
if ( !empty($headerContentType) )
{// если сервер вернул заголовок с типом документа
// print 'Trying to get encoding from header. Content-type: [<b>'.$headerContentType.'</b>]<br/>';
$headerEncoding = array();
preg_match('/charset=(.*)/i', $headerContentType, $headerEncoding);
if ( !empty($headerEncoding[1]) )
{// если тип документа содержит кодировку
$encoding = strtoupper($headerEncoding[1]);
// print 'Seems to found encoding in header: [<b>'.$encoding.'</b>]<br/>';
}
}
}

$title = $title[1];
if ( $encoding != ''
&& $encoding != 'UTF-8' )
$title = @iconv($encoding, 'UTF-8', $title);
$executionTime = microtime(true) - $start;
return $title;
}
}
return false;
}

$time = 0;
$title = getTitleFromUrl('http://yandex.ru/', $time);

?>

функция берет тайтл и переводит в утф-8. немного подпилить под себя - и будет работать

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий