(.*)

Как получить контент сайта на 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 или из локального файла

К сожалению, 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 !='')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 функции для работы с сокетами, которые предназначены для соединения клиента с сервером.

; $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('~~U', $content, $res))?strval($res[1]):''; //--- meta tags --- if( preg_match_all('~]+>~', $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 ; ?>

Итак, входящими параметрами являются: $url — строка, содержащая URL http-протокола, $user_agent — строка с любым юзер-агентом (если пропустить параметр или установить его в null — user_agent будет как в IE). Константа MAX_REDIRECTS_NUM устанавливает количество разрешенных редиректов (поддерживаются 301 и 302 редиректы).

Теперь перейдем к примерам практического использования этой функции:

 else print 'Запрашиваемая страница недоступна.'; ?>

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

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

Дата публикации: 2019-04-26

Источник

DOMDocument::loadHTML

The function parses the HTML contained in the string source . Unlike loading XML, HTML does not have to be well-formed to load. This function may also be called statically to load and create a DOMDocument object. The static invocation may be used when no DOMDocument properties need to be set prior to loading.

Parameters

Since Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

Return Values

Returns true on success or false on failure. If called statically, returns a DOMDocument or false on failure.

Errors/Exceptions

If an empty string is passed as the source , a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml’s error handling functions.

Prior to PHP 8.0.0 this method could be called statically, but would issue an E_DEPRECATED error. As of PHP 8.0.0 calling this method statically throws an Error exception

While malformed HTML should load successfully, this function may generate E_WARNING errors when it encounters bad markup. libxml’s error handling functions may be used to handle these errors.

Examples

Example #1 Creating a Document

See Also

  • DOMDocument::loadHTMLFile() — Load HTML from a file
  • DOMDocument::saveHTML() — Dumps the internal document into a string using HTML formatting
  • DOMDocument::saveHTMLFile() — Dumps the internal document into a file using HTML formatting

User Contributed Notes 19 notes

You can also load HTML as UTF-8 using this simple hack:

$doc = new DOMDocument ();
$doc -> loadHTML ( » . $html );

// dirty fix
foreach ( $doc -> childNodes as $item )
if ( $item -> nodeType == XML_PI_NODE )
$doc -> removeChild ( $item ); // remove hack
$doc -> encoding = ‘UTF-8’ ; // insert proper

DOMDocument is very good at dealing with imperfect markup, but it throws warnings all over the place when it does.

This isn’t well documented here. The solution to this is to implement a separate aparatus for dealing with just these errors.

Set libxml_use_internal_errors(true) before calling loadHTML. This will prevent errors from bubbling up to your default error handler. And you can then get at them (if you desire) using other libxml error functions.

When using loadHTML() to process UTF-8 pages, you may meet the problem that the output of dom functions are not like the input. For example, if you want to get «Cạnh tranh», you will receive «Cạnh tranh». I suggest we use mb_convert_encoding before load UTF-8 page :
$pageDom = new DomDocument ();
$searchPage = mb_convert_encoding ( $htmlUTF8Page , ‘HTML-ENTITIES’ , «UTF-8» );
@ $pageDom -> loadHTML ( $searchPage );

Pay attention when loading html that has a different charset than iso-8859-1. Since this method does not actively try to figure out what the html you are trying to load is encoded in (like most browsers do), you have to specify it in the html head. If, for instance, your html is in utf-8, make sure you have a meta tag in the html’s head section:

If you do not specify the charset like this, all high-ascii bytes will be html-encoded. It is not enough to set the dom document you are loading the html in to UTF-8.

Warning: This does not function well with HTML5 elements such as SVG. Most of the advice on the Web is to turn off errors in order to have it work with HTML5.

If we are loading html5 tags such as

, there is following error:

DOMDocument::loadHTML(): Tag section invalid in Entity

We can disable standard libxml errors (and enable user error handling) using libxml_use_internal_errors(true); before loadHTML();

This is quite useful in phpunit custom assertions as given in following example (if using phpunit test cases):

// Create a DOMDocument
$dom = new DOMDocument();

// fix html5/svg errors
libxml_use_internal_errors(true);

// Load html
$dom->loadHTML(» «);
$htmlNodes = $dom->getElementsByTagName(‘section’);

if ($htmlNodes->length == 0) $this->assertFalse(TRUE);
> else $this->assertTrue(TRUE);
>

Remember: If you use an HTML5 doctype and a meta element like so

your HTML code will get interpreted as ISO-8859-something and non-ASCII chars will get converted into HTML entities. However the HTML4-like version will work (as has been pointed out 10 years ago by «bigtree at 29a»):

It should be noted that when any text is provided within the body tag
outside of a containing element, the DOMDocument will encapsulate that
text into a paragraph tag (

).

For those of you who want to get an external URL’s class element, I have 2 usefull functions. In this example we get the ‘


elements back (search result headers) from google search:

1. Check the URL (if it is reachable, existing)
# URL Check
function url_check ( $url ) <
$headers = @ get_headers ( $url );
return is_array ( $headers ) ? preg_match ( ‘/^HTTP\\/\\d+\\.\\d+\\s+2\\d\\d\\s+.*$/’ , $headers [ 0 ]) : false ;
>;
?>

2. Clean the element you want to get (remove all tags, tabs, new-lines etc.)
# Function to clean a string
function clean ( $text ) $clean = html_entity_decode ( trim ( str_replace ( ‘;’ , ‘-‘ , preg_replace ( ‘/\s+/S’ , » » , strip_tags ( $text ))))); // remove everything
return $clean ;
echo ‘\n’ ; // throw a new line
>
?>

After doing that, we can output the search result headers with following method:
$searchstring = ‘djceejay’ ;
$url = ‘http://www.google.de/webhp#q=’ . $searchstring ;
if( url_check ( $url )) $doc = new DomDocument ;
$doc -> validateOnParse = true ;
$doc -> loadHtml ( file_get_contents ( $url ));
$output = clean ( $doc -> getElementByClass ( ‘r’ )-> textContent );
echo $output . ‘
‘ ;
>else echo ‘URL not reachable!’ ; // Throw message when URL not be called
>
?>

Be aware that this function doesn’t actually understand HTML — it fixes tag-soup input using the general rules of SGML, so it creates well-formed markup, but has no idea which element contexts are allowed.

For example, with input like this where the first element isn’t closed:

loadHTML will change it to this, which is well-formed but invalid:

Источник

Читайте также:  Send value with header php
Оцените статью