Как получить контент сайта на PHP
- Получение контента с помощью библиотеки SimpleHTMLDOM
- Получение контента с помощью cURL
- Продвинутый скрипт получения контента на PHP
Парсер контента на языке PHP – это важный инструмент для веб-разработчиков, которые работают с различными источниками данных. Он позволяет извлекать нужную информацию из HTML-страниц, XML-файлов и других форматов, а также обрабатывать ее в соответствии с заданными правилами.
Одним из основных преимуществ парсера контента является возможность автоматизировать процесс получения и обработки данных, что позволяет сократить время выполнения задач и уменьшить вероятность ошибок.
Для получения контента определённой страницы сайта есть простое решение с помощью собственной функции php - file_get_contents. Всё, что требуется это передать в функцию URL нужной страницы.
Получение контента с помощью библиотеки SimpleHTMLDOM
Для более качественной работы функции лучше воспользоваться подключаемой библиотекой SimpleHTMLDOM. В simplehtmldom есть методы для удаленной загрузки страниц. После подключения файла библиотеки, нам доступны 2 функции для обработки HTML строк:
str_get_html(str) и file_get_html(url)
Они делают одно и тоже, преобразуют HTML текст в DOM дерево, различаются лишь источники.
str_get_htm – на вход получает обычную строку, т.е. если вы получили HTML прибегнув к curl, или file_get_contents то вы просто передаете полученный текст этой функции.
$html = str_get_html('html код');
file_get_html – сама умеет загружать данные с удаленного URL или из локального файла
$html = file_get_html('http://www.yandex.ru/');
или
$html = file_get_html('data/test.htm');
К сожалению, file_get_html загружает страницы обычным file_get_contents. Это значит если хостер, выставил в php.ini allow_url_fopen = false (т.е. запретил удаленно открывать файлы), то загрузить что-то удаленно, не получится. Да и серьезные веб сайты таким способом парсить не стоит, лучше использовать CURL с поддержкой proxy и ssl.
$html = file_get_html('http://www.yandex.ru/');
в результате, в переменной $html будет объект типа simple_html_dom.
При больших объемах данных, в библиотеке происходит утечка памяти. Поэтому после окончания одного цикла надо ее чистить.
Делает это метод clear.
К примеру грузим 5 раз сайт www.yandex.ru с разными поисковыми запросами
include 'simple_html_dom.php';
$k = 5;
while($k>0){
$html = file_get_html('http://yandex.ru/yandsearch?text=hi'.$k.'&lr=11114'); // загружаем данные
// как-то их обрабатываем
$html->clear(); // подчищаем за собой
unset($html);
$k--;
}Ниже приведен ещё один пример использования библиотеки Simple HTML DOM Parser для парсинга HTML-страницы и извлечения заголовков новостей:
// Подключаем библиотеку
require_once('simple_html_dom.php');
// Получаем содержимое страницы
$html = file_get_html('http://example.com/news.html');
// Ищем все заголовки новостей
foreach($html->find('h2.news-title') as $title) {
// Выводим текст заголовка
echo $title->plaintext;
}В этом примере мы используем библиотеку Simple HTML DOM Parser, которая предоставляет простой и удобный API для работы с HTML-документами. Сначала мы получаем содержимое страницы с помощью функции file_get_html(), затем находим все элементы с тегом h2 и классом news-title с помощью метода find(). Наконец, мы выводим текст каждого заголовка с помощью свойства plaintext.
Получение контента с помощью cURL
Неоспоримыми преимуществами в функционале пользуется библиотека или можно сказать модуль PHP - cURL. Для полноценного контролируемого получения контента здесь есть множество разных доплнений. Это и практически полноценный эмулятор браузерного обращения к сайту, работа скрипта через proxy с приватной идентификацией и многое другое. Ниже показана функция получения контента с помощью cURL.
function curl($url, $postdata='', $cookie='', $proxy=''){
$uagent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16";
$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвращает веб-страницу
curl_setopt($ch, CURLOPT_HEADER, 0); // возвращает заголовки
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // переходит по редиректам
curl_setopt($ch, CURLOPT_ENCODING, ""); // обрабатывает все кодировки
curl_setopt($ch, CURLOPT_USERAGENT, $uagent); // useragent
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // таймаут ответа
//curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // останавливаться после 10-ого редиректа
if($proxy !=''){$mass_proxy= explode(':', $proxy, 4);
curl_setopt($ch, CURLOPT_PROXY, $mass_proxy[0].':'.$mass_proxy[1]);}
if($mass_proxy[2]!="" and $mass_proxy[3]!=""){
curl_setopt($ch, CURLOPT_PROXYUSERPWD,$mass_proxy[2].':'.$mass_proxy[3]);}// если необходимо предоставить имя пользователя и пароль 'user:pass'
if(!empty($postdata))
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
}
if(!empty($cookie))
{
//curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT'].'/2.txt');
//curl_setopt($ch, CURLOPT_COOKIEFILE,$_SERVER['DOCUMENT_ROOT'].'/2.txt');
}
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header['content'];
}Продвинутый скрипт получения контента на PHP
Ещё один способ получения контента встроенными функциями php я нашёл на просторах интернета. Пока не использовал, но привожу здесь для полноты картины, так как это решение тоже заслуживает достойного внимания. Далее, как в ©Источнике:
Полезными качествами, в данном контексте, будут возможность получения множества атрибутов запрашиваемого контента, а также возможность получения заголовка ответа сервера и времени выполнения запроса. Данная функция использует встроенные в PHP функции для работы с сокетами, которые предназначены для соединения клиента с сервером.
<?php
function abi_get_url_object($url, $user_agent=null)
{
define('ABI_URL_STATUS_UNSUPPORTED', 100);
define('ABI_URL_STATUS_OK', 200);
define('ABI_URL_STATUS_REDIRECT_301', 301);
define('ABI_URL_STATUS_REDIRECT_302', 302);
define('ABI_URL_STATUS_NOT_FOUND', 404);
define('MAX_REDIRECTS_NUM', 4);
$TIME_START = explode(' ', microtime());
$TRY_ID = 0;
$URL_RESULT = false;
do
{
//--- parse URL ---
$URL_PARTS = @parse_url($url);
if( !is_array($URL_PARTS))
{
break;
};
$URL_SCHEME = ( isset($URL_PARTS['scheme']))?$URL_PARTS['scheme']:'http';
$URL_HOST = ( isset($URL_PARTS['host']))?$URL_PARTS['host']:'';
$URL_PATH = ( isset($URL_PARTS['path']))?$URL_PARTS['path']:'/';
$URL_PORT = ( isset($URL_PARTS['port']))?intval($URL_PARTS['port']):80;
if( isset($URL_PARTS['query']) && $URL_PARTS['query']!='' )
{
$URL_PATH .= '?'.$URL_PARTS['query'];
};
$URL_PORT_REQUEST = ( $URL_PORT == 80 )?'':":$URL_PORT";
//--- build GET request ---
$USER_AGENT = ( $user_agent == null )?'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)':strval($user_agent);
$GET_REQUEST = "GET $URL_PATH HTTP/1.0
"
."Host: $URL_HOST$URL_PORT_REQUEST
"
."Accept: text/plain
"
."Accept-Encoding: identity
"
."User-Agent: $USER_AGENT
";
//--- open socket ---
$SOCKET_TIME_OUT = 30;
$SOCKET = @fsockopen($URL_HOST, $URL_PORT, $ERROR_NO, $ERROR_STR, $SOCKET_TIME_OUT);
if( $SOCKET )
{
if( fputs($SOCKET, $GET_REQUEST))
{
socket_set_timeout($SOCKET, $SOCKET_TIME_OUT);
//--- read header ---
$header = '';
$SOCKET_STATUS = socket_get_status($SOCKET);
while( !feof($SOCKET) && !$SOCKET_STATUS['timed_out'] )
{
$temp = fgets($SOCKET, 128);
if( trim($temp) == '' ) break;
$header .= $temp;
$SOCKET_STATUS = socket_get_status($SOCKET);
};
//--- get server code ---
if( preg_match('~HTTP/(d+.d+)s+(d+)s+(.*)s*
~si', $header, $res))
$SERVER_CODE = $res[2];
else
break;
if( $SERVER_CODE == ABI_URL_STATUS_OK )
{
//--- read content ---
$content = '';
$SOCKET_STATUS = socket_get_status($SOCKET);
while( !feof($SOCKET) && !$SOCKET_STATUS['timed_out'] )
{
$content .= fgets($SOCKET, 1024*8);
$SOCKET_STATUS = socket_get_status($SOCKET);
};
//--- time results ---
$TIME_END = explode(' ', microtime());
$TIME_TOTAL = ($TIME_END[0]+$TIME_END[1])-($TIME_START[0]+$TIME_START[1]);
//--- output ---
$URL_RESULT['header'] = $header;
$URL_RESULT['content'] = $content;
$URL_RESULT['time'] = $TIME_TOTAL;
$URL_RESULT['description'] = '';
$URL_RESULT['keywords'] = '';
//--- title ---
$URL_RESULT['title'] =( preg_match('~<title>(.*)</title>~U', $content, $res))?strval($res[1]):'';
//--- meta tags ---
if( preg_match_all('~<metas+names*=s*["']?([^"']+)["']?s+contents*=["']?([^"']+)["']?[^>]+>~', $content, $res, PREG_SET_ORDER) > 0 )
{
foreach($res as $meta)
$URL_RESULT[strtolower($meta[1])] = $meta[2];
};
}
elseif( $SERVER_CODE == ABI_URL_STATUS_REDIRECT_301 || $SERVER_CODE == ABI_URL_STATUS_REDIRECT_302 )
{
if( preg_match('~location:s*(.*?)
~si', $header, $res))
{
$REDIRECT_URL = rtrim($res[1]);
$URL_PARTS = @parse_url($REDIRECT_URL);
if( isset($URL_PARTS['scheme'])&& isset($URL_PARTS['host']))
$url = $REDIRECT_URL;
else
$url = $URL_SCHEME.'://'.$URL_HOST.'/'.ltrim($REDIRECT_URL, '/');
}
else
{
break;
};
};
};// GET request is OK
fclose($SOCKET);
}// socket open is OK
else
{
break;
};
$TRY_ID++;
}
while( $TRY_ID <= MAX_REDIRECTS_NUM && $URL_RESULT === false );
return $URL_RESULT;
};
?>Итак, входящими параметрами являются: $url — строка, содержащая URL http-протокола, $user_agent — строка с любым юзер-агентом (если пропустить параметр или установить его в null — user_agent будет как в IE). Константа MAX_REDIRECTS_NUM устанавливает количество разрешенных редиректов (поддерживаются 301 и 302 редиректы).
Теперь перейдем к примерам практического использования этой функции:
<?php
$url = 'http://www.yahoo.com';
$user_agent = 'MySuperBot 1.02';
$URL_OBJ = abi_get_url_object($url, $user_agent);
if( $URL_OBJ )
{
$CONTENT = $URL_OBJ['content'];
$HEADER = $URL_OBJ['header'];
$TITLE = $URL_OBJ['title'];
$DESCRIPTION = $URL_OBJ['description'];
$KEYWORDS = $URL_OBJ['keywords'];
$TIME_REQUEST = $URL_OBJ['time'];
}
else
print 'Запрашиваемая страница недоступна.';
?>Как видно из вышеприведенного примера, мы можем получить всю информацию по запрошенному URL. Кроме того, можно получить значения любого мета-тега. Для этого можно воспользоваться следующим кодом:
<?php
preg_match ("/charset=(.*?)"/is", $CONTENT, $char);
$charset=$char[1];
?>Заключение:
Парсер контента на языке PHP – это важный инструмент для получения и обработки данных из различных источников. Благодаря мощным библиотекам и инструментам, разработчики могут легко и удобно извлекать нужную информацию из HTML-страниц, XML-файлов и других форматов.
Дата публикации:

