Архивы для категории ‘Примеры’.

Где я?

Очень часто в процессе парсинга информации наши скрипты циклически проходят набор каких-либо урлов.

Если парсинг идет с одного источника с изменением, например, некоторых GET или POST параметров, то в любую единицу времени вы можете точно определить месторасположение своего скрипта. Но бывают случаи когда массив урлов собирается, например, с поисковика. И все было бы хорошо, если бы человек не придумал такую штуку как редирект и если бы ваш заказчик не требовал заносить УРЛ конечной страницы в базу данных.

А можете ли вы однозначно утверждать, что урл, который вы достали из выдачи Гугла однозначно равен урлу, на который зашел ваш скрипт и на котором он производил поиск информации? Если вы говорите “ДА”, то вы сильно ошибаетесь. Можете попробовать поэкспериментировать с такими запросами к Google как “Viagra” - половина сайтов будут либо дорвеями, либо прочими видами редиректеров.

И, поверьте, это всего лишь одна из ситуаций, когда в процессе парсинга/граббинга надо точно определять урл страницы, на которой находится ваш скрипт.

В качестве других типичных примеров можно привести сборы урлов из каталогов компаниий или каталогов галерей картинок. Как часто вы видите подобные урлы: http://www.site.com/redirect.php?id=700? Понятное дело, что подобное записывать в поле URL в своей базе просто стыдно :), потому что через пару часов вы уже не сможете гарантировать, что вышеуказанная ссылка будет ссылаться на тот сайт, на котором вы произвели поиск информации.

Я столкнулся с подобной проблемой при работе над одним проектом по сбору картинок с галерей изображений. Редиректеры вытворяли что-то нереальное: одна и таже ссылка на редиректере вела на разные сайты. И даже не надо было ждать пару часов - это происходило ежесекундно!

И это бы ничего, ведь даже file() умеет следовать редиректам. Но ведь заказчик потребовал в базе в отдельное поле писать конечный URL…

Решить данную проблему можно достаточно просто и вариантов ее решение есть несколько.

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

Вот типичный пример использования данной функции в одном из моих классов:

function GetLastURL() {
	return curl_getinfo($this->curl_handler, CURLINFO_EFFECTIVE_URL);
}

В результате использования данной незатейливой функции вы получите последний урл, куда был перенаправлен ваш скрипт.

А что же делать, если вы не пользуетесь функционалом curl’a, а используете, например, file_get_contents()? Тогда прийдется немного поиграться в функцией stream_get_meta_data(). Вот типичное решение, которое я использовал в одном из своих проектов, где по ТЗ нельзя было использовать CURL:

$content = file_get_contents($url);
$fp = fopen($url,'r');
$meta_data = stream_get_meta_data($fp);
foreach($meta_data['wrapper_data'] as $response) {
	if (substr(strtolower($response), 0, 10) == 'location: ') {
		$last_url = substr($response, 10);
	}
}
fclose($fp);

Из данного кода я убрал все проверки и прочие функции, которые не имеют непосредственного отношения к обсуждаемой теме.

Как мы видим второе решение намного более громоздкое по количеству написанного кода, да и ограничений у него побольше будет. Но тем не менее каждый из вышеуказанных вариантов имеет право на жизнь.

Пользуйтесь ими на здоровье в своих парсерах, грабберах и анализаторах и не никогда не теряйтесь! ;)

Оптимизируем работу с регулярными выражениями. 2 простые функции.

Главным оружием любого профессионального парсера являются регулярные выражение (особенно перловые PCRE). И я, если честно, вообще не представляю как без них можно делать просто и быстро свою работу.

Одним словом просто прелесть. И эту прелесть мы каждый день используем.

Сечас я приведу 2 классических варианта использования регулярных выражений:

if (preg_match("/$price_find/Ui",$content,$m)) {
        unset($m[0]);
	$price=mysql_escape_string(trim($m[1]));
} else {
        $price='';
}
 
if (preg_match_all("/$blocks_find/Ui",$content,$m)) {
	unset($m[0]);
        $blocks=$m[1];
} else {
        $blocks=array();
}

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

function pregm($what, $where, $return=1, $keys='Ui') {
	$search="/$what/$keys";
	if (preg_match($search,$where,$matches)) {
		unset($matches[0]);
		if ($return==1) {
			return $matches[1];
		} else {
			return $matches;
		}
	} else {
		return false;
	}
}
 
function pregma($what, $where, $return=1, $keys='Ui') {
	$search="/$what/$keys";
	if (preg_match_all($search,$where,$matches)) {
		unset($matches[0]);
		if ($return==1) {
			return $matches[1];
		} else {
			return $matches;
		}
	} else {
		return false;
	}
}

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

$price=mysql_escape_string(trim(pregm($price_find,$content));
$blocks=pregma($blocks_find,$content);

Вот так все просто. Мы сократили объем кода в несколько раз и сделали его более прозрачным и простым.

Конечно же если регулярные выражения вы используете два раза в год, то прибегать к данной библиотеке нет смысла, но если регулярки - ваша повседневная работа, то вам надо максимально использовать вышеупомянутый код и даже развить его под свои нужны. Так я, например, в случаях, когда надо найти большое количество параметров, использую массивы. Вот пример:

$param=array(
'Название',
'Цена',
'Размер',
'Автор'
//...
);
 
$find=array();
 
// Получаем контент и делаем прочие преобразования
 
foreach ($param as $key=>$item) {
	$find_it=$item."\:(.*)$";					
        $find[$key]=strip_tags(pregm($find_it,$block));
}

Получится, что в массиве $find у нас будут все найденные параметры. Потом можно просто сделать implode("','",$find), добавить пару кавычек и практически целиком залить эту строку в базу. Получается очень быстро и удобно.

Суть этой заметки. Регулярные выражения - мощный инструмент, а свои надстройки над ними - еще более мощный и удобный инструмент!

Лучшая проверка - в бою.

На днях закончил проверку новой системы GrabVIA для сбора изображений, аудио- и видеоконтента.

В течении двух суток данной системой было собрано 194 766 изображение суммарным размером около 5 ГБ.

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

Пример

Для создания позитивного имиджа услугам парсинга я буду приводить примеры сайтов, где он используется в благих целях.

Компания In.Site.
В своем портфолио они приводят работу для ГринКомБанк:

- Архивация страниц отчетности и возможность просматривать их.
- Парсинг новостей с сайта bankir.ru
- Калькулятор доходности вкладов

Это очень показательный пример. Особенно для сайтов банков. Практически все сайты крупных банков парсят курсы обмена с Центрального Банка своей страны.

Поэтому сейчас для упрощения сбора информации на сайтах Центральных Банков запускают всевозможнейшие веб-сервисы.

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