Получение информации из сети Интернет

Опубликовал: Вторник, Март 20, 2012 в категории HTML | Пока нет комментариев

Открыть для чтения можно не только локально сохраненный файл, но и файл, находящийся на другом сервере в Интернете. С помощью функций fopen(), file() и file_get_contents() файл можно получить как по прото- колу HTTP, так и по протоколу FTP. Для этого достаточно указать соответст- вующий протокол в URL-адресе, переданном в качестве параметра <Путь к файлу> этим функциям:

http://www.site.ru/file.txt ftp://www.site.ru/file.txt

Как вам уже известно, в логах сервера отображается программное обеспече- ние сделавшего запрос клиента. С помощью директивы user_agent в файле php.ini можно задать свое название. Для этого вместо строки

; user_agent="PHP"

нужно написать другую, например:

user_agent="MySpider/1.0"

При обработке больших файлов может потребоваться больше времени, чем задано по умолчанию (30 секунд). Увеличить время работы сценария можно с помощью директивы max_execution_time:

max_execution_time = 120

Кроме того, следует учитывать, что с помощью директивы allow_url_fopen можно запретить открытие внешних файлов. Для получения информации из сети Интернет значение директивы должно быть равно On:

allow_url_fopen = On

Получить документ с помощью функции fopen() можно следующим обра-

зом:

$host = ‘http://wwwadmin.ru/testrobots.php?var1=10&var2=15′;

$content = ”;

$header = "User-Agent: MySpider/1.0\r\n";

$header .= "Cookie: test=5\r\n";

$option = array(

‘http’ => array(‘method’ => ‘GET’, ‘header’=> $header)

);

$context = stream_context_create($option);

@$file = fopen($host, ‘r’, false, $context);

if ($file) {

while(!feof($file)) {

$content .= fgets($file, 1024);

}

fclose($file);

echo ‘<b>Содержимое страницы:</b><br><br>’;

echo ‘<pre>’ . htmlspecialchars($content) . ‘</pre>’;

}

else {

echo ’Не удалось открыть файл’;

}

Если необходимо получить документ в виде массива или строки, то можно воспользоваться функциями file() и file_get_contents():

$host = ‘http://wwwadmin.ru/testrobots.php?var1=10&var2=15′;

$header = "User-Agent: MySpider/1.0\r\n";

$header .= "Cookie: test=5\r\n";

$option = array(

‘http’ => array(‘method’ => ‘GET’, ‘header’=> $header)

);

$context = stream_context_create($option);

$file1 = implode(”, file($host, 0, $context));

if ($file1) {

echo ‘<b>Содержимое страницы (file()):</b><br><br>’;

echo ‘<pre>’ . htmlspecialchars($file1) . ‘</pre>’;

}

$file2 = file_get_contents($host, 0, $context);

if ($file2) {

echo ‘<b>Содержимое страницы (file_get_contents()):</b><br><br>’;

echo ‘<pre>’ . htmlspecialchars($file2) . ‘</pre>’;

}

Функция fsockopen() позволяет получить не только содержимое документа, но и все заголовки ответа сервера. Эта функция очень универсальна и позво- ляет открыть соединение не только с портом 80, но и с любым другим. На- пример, можно передать сообщение почтовому серверу на 25-й порт. Функ- ция имеет следующий формат:

fsockopen(<Хост>, <Порт>, [<Номер ошибки>], [<Сообщение об ошибке>], [<Таймаут>]);

Функция устанавливает сетевое соединение и возвращает его дескриптор. Если соединение не установлено, то функция возвращает false. Получить номер и сообщение об ошибке можно с помощью необязательных парамет- ров <Номер ошибки> и <Сообщение об ошибке>. В необязательном параметре

<Таймаут> можно указать максимальное время, в течение которого произво-

дится попытка соединения (в секундах). Если параметр не указан, то будет использовано значение из директивы default_socket_timeout файла php.ini:

default_socket_timeout = 60

После установки соединения необходимо передать заголовки запроса. Между собой заголовки должны разделяться с помощью комбинации символов \r\n. Заголовки должны отделяться от тела запроса с помощью комбинации

\r\n\r\n.

Открытым соединением можно манипулировать как обычным файлом с по- мощью функций fgets(), fwrite(), feof() и др. Закрыть соединение позво- ляет функция fclose().

Функция stream_set_blocking() позволяет установить режим блокировки соединения. Имеет следующий формат:

stream_set_blocking(<Дескриптор соединения>, <Режим блокировки>);

Если режим равен 1, то функции чтения будут ожидать полного завершения передачи данных. Если указать 0, то блокировка снимается.

В качестве примера получим документ методом GET и выведем отдельно за-

головки ответа сервера и содержимое документа (листинг 5.52).

Листинг 5.52. Чтение документа методом GET

<?php

$page = "/testrobots.php?var1=10&var2=15";

$port = "80";

$host = "wwwadmin.ru";

$header = "GET $page HTTP/1.1\r\n";

$header .= "Host: $host\r\n";

$header .= "User-Agent: MySpider/1.0\r\n";

$header .= "Accept: text/html, text/plain, application/xml\r\n";

$header .= "Accept-Language: ru, ru-RU\r\n";

$header .= "Accept-Charset: windows-1251\r\n";

$header .= "Accept-Encoding: identity\r\n";

$header .= "Connection: close\r\n";

$header .= "Cookie: test=5\r\n";

$header .= "\r\n";

@$fsock = fsockopen($host, $port, $err, $err_text, 30);

if ($fsock) { stream_set_blocking($fsock, 0); fwrite($fsock, $header);

$s = 5;

$content = "";

$headers = "";

$buffer = "";

while(!feof($fsock)) {

$buffer = fgets($fsock, 1024);

if ($buffer == "\r\n") { $s = 10; }

if ($s == 5) { $headers .= $buffer; }

else { $content .= $buffer; }

}

fclose($fsock);

}

else {

echo "Произошла ошибка " . $err . ": " . $err_text;

}

echo "<b>Заголовки ответа сервера:</b><br><br>";

echo "<pre>" . htmlspecialchars($headers) . "</pre>"; echo "<br><br><b>Содержимое страницы:</b><br><br>"; echo "<pre>" . htmlspecialchars($content) . "</pre>";

?>

Обратите внимание на строку

$host = "wwwadmin.ru";

Мы не указали протокол соединения, так как протокол http:// по умолча-

нию закреплен за 80-м портом.

Если необходимо получить только заголовки ответа сервера, то вместо мето-

да GET следует указать метод HEAD. Для этого строку

$header = "GET $page HTTP/1.1\r\n";

следует заменить на

$header = "HEAD $page HTTP/1.1\r\n";

Данные можно передать не только методами GET и HEAD, но и методом POST, имитируя таким образом передачу данных формы. Рассмотрим это на приме- ре (листинг 5.53).

Листинг 5.53. Имитация передачи данных методом POST

<?php

$page = "/testrobots.php";

$port = "80";

$host = "wwwadmin.ru";

$header = "POST $page HTTP/1.1\r\n";

$header .= "Host: $host\r\n";

$header .= "User-Agent: MySpider/1.0\r\n";

$header .= "Accept: text/html, text/plain, application/xml\r\n";

$header .= "Accept-Language: ru, ru-RU\r\n";

$header .= "Accept-Charset: windows-1251\r\n";

$header .= "Accept-Encoding: identity\r\n";

$header .= "Connection: close\r\n";

$header .= "Content-Type: application/x-www-form-urlencoded\r\n";

$header .= "Content-Length: 15\r\n";

$header .= "Cookie: test=5\r\n";

$header .= "\r\n";

@$fsock = fsockopen($host, $port, $err, $err_text, 30);

if ($fsock) { stream_set_blocking($fsock, 0); fwrite($fsock, $header); fwrite($fsock, "var1=10&var2=15");

$s = 5;

$content = "";

$headers = "";

$buffer = "";

while(!feof($fsock)) {

$buffer = fgets($fsock, 1024);

if ($buffer == "\r\n") { $s = 10; }

if ($s == 5) { $headers .= $buffer; }

else { $content .= $buffer; }

}

fclose($fsock);

}

else {

echo "Произошла ошибка " . $err . ": " . $err_text;

}

echo "<b>Заголовки ответа сервера:</b><br><br>";

echo "<pre>" . htmlspecialchars($headers) . "</pre>"; echo "<br><br><b>Содержимое страницы:</b><br><br>"; echo "<pre>" . htmlspecialchars($content) . "</pre>";

?>

В этом примере мы заменили метод передачи данных с GET на POST и добави-

ли два заголовка:

$header .= "Content-Type: application/x-www-form-urlencoded\r\n";

$header .= "Content-Length: 15\r\n";

Первый заголовок имитирует передачу данных формы, а второй указывает длину данных, переданных методом POST. Сами данные мы передаем после всех заголовков:

fwrite($fsock, "var1=10&var2=15");

Использование библиотеки CURL

Вместо перечисленных функций для получения информации из сети Интер- нет можно воспользоваться библиотекой CURL (Client URL Library). Чтобы использовать библиотеку CURL, необходимо в файле php.ini убрать символ комментария (;) перед строкой

;extension=php_curl.dll

В библиотеку CURL входят следующие функции:

? curl_init([<URL-адрес>]) создает новый сеанс и возвращает идентифи-

катор;

? curl_close(<Идентификатор>) завершает сеанс;

? curl_setopt(<Идентификатор>, <Параметр>, <Значение>) устанавлива-

ет параметры сеанса.

<Параметр> может равняться одной из следующих констант, определяю-

щих смысл параметра <Значение>:

• CURLOPT_URL — URL-адрес;

• CURLOPT_PORT — номер порта;

• CURLOPT_USERAGENT — значение HTTP-заголовка User-Agent;

• CURLOPT_RETURNTRANSFER — если параметр не равен 0, то функция curl_exec() будет возвращать результат, а не выводить его сразу в Web-браузер;

• CURLOPT_TIMEOUT — максимальное время выполнения операции (в секундах);

• CURLOPT_HEADER — если параметр не равен 0, то результат будет включать не только содержимое документа, но и заголовки ответа сервера;

• CURLOPT_NOBODY — если параметр не равен 0, то результат будет включать только заголовки ответа сервера;

• CURLOPT_POST — если параметр не равен 0, то запрос будет оправлен методом POST. Кроме того, будет добавлен HTTP-заголовок Content-

Type со значением application/x-www-form-urlencoded. Этот заго-

ловок обычно используется при передаче данных формы;

• CURLOPT_POSTFIELDS — строка, содержащая данные для передачи ме-

тодом POST;

• CURLOPT_REFERER — значение HTTP-заголовка Referer;

• CURLOPT_COOKIE — значение HTTP-заголовка Cookie;

• CURLOPT_FOLLOWLOCATION — если параметр не равен 0, то перенаправ-

ления будут обрабатываться автоматически;

• CURLOPT_HTTPHEADER — массив с дополнительными HTTP-заголов-

ками;

• CURLOPT_FILE — дескриптор файла, в который будет выведен резуль-

тат операции;

• CURLOPT_WRITEHEADER — дескриптор файла, в который будут выведе-

ны полученные заголовки;

• CURLOPT_STDERR — дескриптор файла, в который будут выводиться сообщения об ошибках;

? curl_exec(<Идентификатор>) выполняет запрос;

? curl_getinfo(<Идентификатор>, [<Параметр>]) возвращает информа- цию о последней операции. Если <Параметр> не указан, то функция воз- вращает ассоциативный массив. Если <Параметр> равен CURLINFO_HTTP_CODE, то функция возвращает последний полученный код HTTP. Если <Параметр> равен CURLINFO_CONTENT_TYPE, то функция воз- вращает содержимое полученного заголовка Content-Type или значение NULL, если заголовка нет в ответе сервера;

? curl_errno(<Идентификатор>) возвращает код последней ошибки;

? curl_error(<Идентификатор>) позволяет получить строку с описанием последней ошибки.

Пример запроса методом GET с получением содержимого документа и всех заголовков ответа сервера приведен в листинге 5.54.

Листинг 5.54. Получение документа методом GET с использованием библиотеки CURL

<?php

$url = "http://wwwadmin.ru/testrobots.php?var1=1&var2=5&var3=45";

@$curl=curl_init();

if (!curl_errno($curl)) { curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, "MySpider/1.0"); curl_setopt($curl, CURLOPT_HEADER, 1);

$headers = array(

"Accept: text/html, text/plain, application/xml", "Accept-Language: ru, ru-RU",

"Accept-Charset: windows-1251", "Accept-Encoding: identity", "Connection: close",

"Cookie: test=5"

);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$content = curl_exec($curl);

if (!curl_errno($curl)) {

echo "<b>Код возврата:</b> ";

echo curl_getinfo($curl, CURLINFO_HTTP_CODE);

echo "<br><b>Заголовок Content-Type:</b> ";

echo curl_getinfo($curl, CURLINFO_CONTENT_TYPE);

echo "<br><br>";

echo "<b>Содержимое страницы:</b><br><br>";

echo "<pre>" . htmlspecialchars($content) . "</pre>";

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

curl_close($curl);

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

?>

В ряде случаев достаточно получить только заголовки ответа сервера (лис-

тинг 5.55).

Листинг 5.55. Получение заголовков ответа с использованием библиотеки CURL

<?php

$url = "http://wwwadmin.ru/testrobots.php?var1=1&var2=5&var3=45";

@$curl=curl_init();

if (!curl_errno($curl)) { curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, "MySpider/1.0"); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_NOBODY, 1);

$headers = array(

"Accept: text/html, text/plain, application/xml", "Accept-Language: ru, ru-RU",

"Accept-Charset: windows-1251", "Accept-Encoding: identity", "Connection: close",

"Cookie: test=5"

);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$content = curl_exec($curl);

if (!curl_errno($curl)) {

echo "<b>Код возврата:</b> ";

echo curl_getinfo($curl, CURLINFO_HTTP_CODE);

echo "<br><b>Заголовок Content-Type:</b> ";

echo curl_getinfo($curl, CURLINFO_CONTENT_TYPE);

echo "<br><br>";

echo "<b>Заголовки ответа сервера:</b><br><br>";

echo "<pre>" . htmlspecialchars($content) . "</pre>";

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

curl_close($curl);

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

?>

Приведем также пример запроса методом POST, в котором мы не получа- ем заголовки ответа сервера, а только выводим содержимое страницы (лис- тинг 5.56).

Листинг 5.56. Передача данных методом POST с использованием библиотеки CURL

<?php

$url = "http://wwwadmin.ru/testrobots.php";

@$curl=curl_init();

if (!curl_errno($curl)) { curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, "MySpider/1.0"); curl_setopt($curl, CURLOPT_HEADER, 0);

$headers = array(

"Accept: text/html, text/plain, application/xml", "Accept-Language: ru, ru-RU",

"Accept-Charset: windows-1251", "Accept-Encoding: identity", "Connection: close",

"Cookie: test=5"

);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_POSTFIELDS, "var1=1&var2=5&var3=45");

$content = curl_exec($curl);

if (!curl_errno($curl)) {

echo "<b>Код возврата:</b> ";

echo curl_getinfo($curl, CURLINFO_HTTP_CODE);

echo "<br><b>Заголовок Content-Type:</b> ";

echo curl_getinfo($curl, CURLINFO_CONTENT_TYPE);

echo "<br><br>";

echo "<b>Содержимое страницы:</b><br><br>";

echo "<pre>" . htmlspecialchars($content) . "</pre>";

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

curl_close($curl);

}

else {

echo "Произошла ошибка " . curl_errno($curl) . ": ";

echo curl_error($curl);

}

?>

Источник: Прохоренок Н. А. HTML, JavaScript, PHP и MySQL. Джентльменский набор Web-мастера. — 3-е изд., перераб. и доп. — СПб.: БХВ-Петербург, 2010. — 912 с.: ил. + Видеокурс (на CD-ROM) — (Профессиональное программирование)

Похожие посты:

Комментировать

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>