|
Статьи
Импортирование информации с помощью PHP
Если вы уже некоторое время занимаетесь WEB-программированием, то наверняка перед Вами хотя бы раз вставала задача заимствования информации с других WEB-узлов, например, для сбора статистики вашего сайта с сервера статистики с последующей её отправкой электронной почтой или импорт курса валют с обработкой специально под ваш дизайн. PHP представляет нам много возможностей для импортирования информации. Зачастую хватает самых простых, вроде приведенных ниже, строк.
<?php
/*
Функция file() считывает информацию из файла или URL и возвращает его построчно
ввиде массива: одна строка - один элемент массива. Полученный массив преобразуется
в строку функцией implode().
*/
echo implode('', file('http://some.site.ru/infopage.html'));
?>
или
<?php
// Открываем URL в режиме чтения "r"
$fp = fopen( "http://some.site.ru/infopage.html", "r" );
//Если соединение успешно открыто
if( $fp ) {
// Считывать строки из удалённого файла до тех пор, пока не достигнут конец файла.
while( !feof( $fp ) ) {
echo fgets( $fp, 1024 );
}
//Закрываем соединение
fclose( $fp );
}
?>
Однако, бывают случаи когда простого заимствования оказывается мало. Допустим, нам нужно взять информацию с сайта требующего авторизации. В этом случае, нам сначала требуется узнать какие поля и на какой адрес передаются формой авторизации. Это несложно. Заходим на страницу авторизации и в браузере нажимаем "Просмотр в виде HTML" или "Просмотреть исходный текст". Перед нами HTML-код страницы. В ней находим форму авторизации. В теге <form> смотрим параметры action и method . Соответственно, в action содержится адрес скрипта авторизации, а method - метод передачи данных (GET или POST). Затем выбираем имена полей, которые непосредственно передают данные для авторизации. Например:
<form action="http://some.site.ru/auth.php" method="post">
Логин: <input type="text" name="login" /><br/>
Пароль: <input type="password" name="password" /><br/>
<input type="submit" name="submit" value="Войти" />
</form>
Здесь мы видим, что форма передаёт три параметра ( login , password с введёнными логином и паролем к аккаунту, а также поле submit , значением которого является слово "Войти") на адрес http://some.site.ru/auth.php методом POST. Этих знаний уже вполне хватает для написания скрипта импорта.
<?php
//Сначала требуется упаковать все передаваемые данные
$data = array( "login"=>"vasya", "password"=>"PaSsWoRd", "submit"=>"Войти" );
while( list($name, $value) = each($data) ) {
$temp[] = urlencode($name)."=".urlencode($value);
}
$PostData = implode("&", $temp);
//Организация запроса к сайту
$ch = curl_init("http://some.site.ru/auth.php");
curl_setopt( $ch, CURLOPT_HEADER, 0 ); // Не выводить заголовки
curl_setopt( $ch, CURLOPT_NOBODY, 0 ); // Выводить получаемый Content
curl_setopt( $ch, CURLOPT_USERAGENT, "User-Agent: Opera/7.54 (Windows 98; U) [ru]" ); //Браузер
curl_setopt( $ch, CURLOPT_REFERER, "http://some.site.ru" ); //Адрес формы авторизации
// Если используется метод GET, следующие две строки не нужны, а данные
// передаются в функции curl_init() вместе с адресом страницы, например:
// $ch = curl_init("http://some.site.ru/auth.php?login=vasya&password=PaSsWoRd&submit=%C2%EE%E9%F2%E8");
curl_setopt( $ch, CURLOPT_POST, 1 ); //Использовать метод POST
curl_setopt( $ch, CURLOPT_POSTFIELDS, $PostData ); //Отправить данные
curl_exec( $ch );
curl_close( $ch );
?>
Сразу следует обратить внимание, в данном примере мы использовали библиотеку CURL, которая делает передачу данных достаточно простой. Тем не менее, наличие установленной библиотеки зависит от хостера. Именно поэтому рассмотрим скрипт выполняющий аналогичные функции.
<?php
$data = array( "login"=>"vasya", "password"=>"PaSsWoRd", "submit"=>"Войти" );
while( list($name, $value) = each($data) ) {
$temp[] = urlencode($name)."=".urlencode($value);
}
$PostData = implode("&", $temp);
$fp = fsockopen("some.site.ru",80,$errno,$errstr,30);
if( $fp ) {
fputs( $fp,"POST /auth.php HTTP/1.0\r\n" );
fputs( $fp,"Referer: http://some.site.ru\r\n" );
// Если используется метод GET, следующие две строки не нужны, также не нужна строка
// "fputs($fp,$PostData);", а данные передаются вместе с адресом страницы, например:
// fputs($fp,"GET /auth.php?login=vasya&password=PaSsWoRd&submit=%C2%EE%E9%F2%E8 HTTP/1.0\r\n");
fputs( $fp, "Content-Type: application/x-www-form-urlencoded\r\n" );
fputs( $fp, "Content-Length: ".strlen($PostData )."\r\n" );
fputs( $fp,"Host: some.site.ru\r\n" );
fputs( $fp,"User-Agent: Opera/7.54 (Windows 98; U) [ru]\r\n\r\n" );
fputs( $fp,$PostData );
while( !feof( $fp ) ) {
echo fgets($fp,1024);
}
fclose($fp);
}
?>
Во всех выше приведенных примерах мы выводим результат импорта сразу в браузер, однако, на практике этот результат требуется записать в переменную для последующей обработки. И если в первом скрипте достаточно заменить "echo " на "$varname=", то к остальным примерам такое решение едва ли подойдёт, даже если оно и кажется вам очевидным. Дело в том, конструкция вроде
<?php
$varname = '';
while( !feof( $fp ) ) {
$varname .= fgets( $fp, 1024 );
}
?>
являет собой ничто иное, как многократную дозапись в переменную, а это в свою очередь замедляет работу скрипта. Тем более, что в случае с CURL такая возможность не доступна вообще. Решением является использование функций управления выводом: в начале скрипта вы пишите
ob_start();
а в конце
$varname = ob_get_contents();
ob_end_clean();
А если сайт-экспортёр использует HTTP-аутентификацию? Вы строите обычный GET-запрос к нужной странице добавив один заголовок:
fputs( $fp, "Authorization: Basic ".base64_encode("vasya:PaSsWoRd")."\r\n" );
Соответственно для CURL
curl_setopt( $ch, CURLOPT_USERPWD, base64_encode("vasya:PaSsWoRd") );
Если требуется использовать при обращении прокси-сервер, для скрипта использующего CURL вам следует добавить следующую строку:
curl_setopt( $ch, CURLOPT_PROXY, '0.0.0.0:80' );
где соответственно "0.0.0.0" - это IP-адрес прокси-сервера, а "80" - порт. Для варианта с сокетом вы в функции fsockopen() указываете параметры подключения к прокси-серверу (адрес и порт), а всё остальное оставляете без изменений. Наконец, получив страницу в переменную, вам наверняка потребуется её обработать. Для этого можно порекомендовать почитать раздел мануала "Функции регулярных выражений (Perl-совместимые)", этот инструмент отлично подходит для решения подобных задач.
Автор: Бажанов Артём
|
|