Как лесно да вземаме съдържание от сайтове

Публикувано в PHP програмиране на 11.08.2010

Здравейте, приятели! Предполагам, че на доста от вас ви се е налагало да работите със SQL. Предполагам също така, че доста пъти ви се е случвало да ви потрябва някакъв текст или друго съдържание от различни сайтове. Айде сега си представете, че ако искате да вземете определено нещо от един сайт, можете да го направите със SQL. Днес ще предложа на вашето внимание една много приятна php библиотека с кодовото название htmlSQL.

Какво представлява htmlSQL?

htmlSQL е една много простичка PHP библиотека, която ни позволява да достъпваме елементи с тяхните атрибути и пр. по много лесен начин. Нека да ви дам един малък пример:

Какво виждаме тук? Искаме от някакво си съдържание (предполага се, че вече сме го заредили отнякъде) да вземем САМО АТРИБУТИТЕ href и title от ВСИЧКИ тагове А, които обаче ИМАТ class list. За тези от вас, които още се чудят тоя за какво им говори, ще дам този пример, като HTML код за да стане по-ясно.

<a href="#" class="mignev">Marian Ignev</a>

<a href="#" class="list">Fridaycode</a> <!-- Трябва да ни вземе това -->

<a href="#" class="mignev">Marian Ignev</a>

<a href="#" class="list">Google</a> <!-- Трябва да ни вземе това -->

<a href="#" class="mignev">Marian Ignev</a>

<a href="#" class="list">Gmail</a> <!-- Трябва да ни вземе това -->

Както споменах по-горе, когато напишем нашата така да се каже htmlSQL заявка, тя ще ни даде следния резултат:

Array
(
    [href] => #
    [class] => list
    [tagname] => a
    1 => Fridaycode
)
Array
(
    [href] => #
    [class] => list
    [tagname] => a
    1 => Google
)
Array
(
    [href] => #
    [class] => list
    [tagname] => a
    1 => Gmail
)

Толкова лесно стават нещата, че за момент започваш да за забравяш за preg_match… и прочие.
htmlSQL е написан от един добър германец на име Jonas David John. Той споделя, че докато един ден си пиел кафето му дошла идеята, че ще е яко ако можем да достъпваме HTML елементите посредством SQL… и го направил.

htmlSQL използва още един много приятен клас със себе си и той се казва Snoopy.

Какво представлява Snoopy?

Snoopy е една мого приятна PHP библиотека, която симулира уеб браузър. С нея може лесно да си автоматизирате много задачи свързвани с взимане на съдържание, постване на форми и прочие. За да може да добиете малко повече представа какво прави Snoopy ще ви дам направо Features list-а.

  • Лесно вземане на съдържание на уеб страници
  • Лесно вземане на текст от уеб страници, като ореже всички html тагове (strip html tags)
  • Лесно вземане на линковете от уеб страници
  • Поддържа proxy хостове
  • Поддържа базова user/pass автентикация
  • Поддържа настройки като user_agent, referer, cookies и header content (доста полезнички)
  • Поддържа Browser redirects и контролира дълбочината на пренасочванията
  • Лесно изпращане на форма и обработване на върнатия резултат
  • Поддръжка на HTML Frames (добавено v0.92)

Малко Query примери за работа с htmlSQL


SELECT * FROM h1
^ селектира всички <h1> тагове

SELECT * FROM a
^ селектира всички линкове

SELECT * FROM td
^ селектира всички <td>-та

SELECT href as url, text FROM a
^ връща ни href като url и text като text от всички линкове

SELECT * FROM a WHERE preg_match("/^http:\/\//", $href)
^ намира всички външни линкове (това не винаги е така, защото по някога можете да си хардкорвате линковете и т.н.)

SELECT * FROM a WHERE preg_match("/^\/snippets/i", $href) and preg_match("/^array_/i", $text)
^ намира всички линкове на които хреф-а им започва със /snippets и с текст започващ с "array_"

SELECT * FROM *
^ селектира всички елементи и всичките им тагове

SELECT id, name, password FROM user WHERE $status == "active"
^ селектира всички <user> тагове където status="active" ( за XML файлове )

SELECT * FROM * WHERE $id == "header"
^ връща всички тагове където id="header"

SELECT * FROM a WHERE substr($href,0,1) != "/"
^ връща всички линкове на които href-а им започва с / (стандартно такива са вътрешни линкове на сайта href="/index.php" и т.н.)

SELECT * FROM * WHERE $class == "nav_item"
^ намира всички елементи където class="nav_item"

SELECT * FROM a WHERE ($href == "foo.htm" and $title == "foo") or ($title == "bar")
^ комплексно Query

Примерни скриптове, можете да намерите в zip-чето, което съм качил. Също така ще ви покажа един реален пример.

Как да вземем лесно последните новини от DarikNews благодарение на htmlSQL!

Ето ви едно простичко примерче как това чудо работи в реална ситуация. Няма да пиша излишни неща тук, защото в сорскода съм си пописал доста коментари.

ДЕМО

DOWNLOAD

Нека започваме:

dariknews_parser.php

<?php

    $web_url = 'http://dariknews.bg/';

    include_once("snoopy.class.php");
    include_once("htmlsql.class.php");

	$wsql = new htmlsql();

    if ( ! $wsql->connect( 'url', $web_url ) )
	{
        print 'Error while connecting: ' . $wsql->error;
        exit;
    }

    $wsql->isolate_content( '<root>', '</root>' );

    if ( ! $wsql->query( 'SELECT * FROM a WHERE preg_match("/view_article.php/", $href)' ) )
	{
        print "Query error: " . $wsql->error;
        exit;
    }

	//print_r( $wsql );

	$news = array();

    foreach ( $wsql->fetch_array() as $row )
	{

        //print_r($row);

		$news_id = end( explode( '=', $row['href'] ) );
		$news_name = $row['text'];
		$news_query_string = $row['href'];
		$news_real_link = $web_url . $news_query_string;

        $news_content = new htmlsql();

        $news_content->connect( 'url', $news_real_link );

        if ( ! $news_content->query( 'SELECT * FROM * WHERE $id == "textsize"' ) )
		{
            print "Query error: " . $news_content->error;
            exit;
        }

		//print_r( $news_content->fetch_array() );
        //exit;

		$news_text = $news_content->fetch_array();

		//
		$news[] = array( 'id' => $news_id, 'name' => $news_name, 'link' => $news_real_link, 'text' => $news_text[0]['text'] );

    }

	//print_r( $news );
?>

index.php

<?php include('dariknews_parser.php'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>CSS Horizontally and Vertically Center Element by RIP</title>
	<link rel="stylesheet" href="css/style.css" type="text/css" />
	<link rel="stylesheet" href="css/demo_css.css" type="text/css" />
</head>
<body>

	<a href="http://fridaycode.net/" class="logo">Fridaycode.net</a>
	<h1>Демо: Парсване на съдържание!</h1>

	<?php

	function cp1251_to_utf8($s)
	{
		$c209 = chr(209); $c208 = chr(208); $c129 = chr(129);
	    for($i=0; $i<strlen($s); $i++)    {
	        $c=ord($s[$i]);
	        if ($c>=192 and $c<=239) $t.=$c208.chr($c-48);
	        elseif ($c>239) $t.=$c209.chr($c-112);
	        elseif ($c==184) $t.=$c209.$c209;
	        elseif ($c==168)    $t.=$c208.$c129;
	        else $t.=$s[$i];
	    }
	    return $t;
	}

	foreach ( $news as $row )
	{
		$html = '<div class="news">';
		$html .= '<h3>'. cp1251_to_utf8( $row['name'] ) .'</h3>';
		$html .= '<p class="link">' . $row['link'] .'</p>';
		$html .= '<div class="content">'. cp1251_to_utf8( $row['text'] ) .'</div>';
		$html .= '</div>';

		echo $html;
	}
	?>
</body>
</html>

С този пример съм показал един от начините да си свършите работата. Понякога нещата са по-дребнички и няма смисъл за нещо дребничко и елементарно да зареждате цял клас. Примерът, който съм дал не е с голяма трудност, но исках да е по-лесно за смилане.

Ето това беше. Не e нищо страшно. Предполагам, че може да има неща, които не съм споменал или нещо не съм обяснил, както трябва. Ако имате някакви въпроси предложения идеи критики или цветущи думи по майчина линия :), може да напишете едно коментарче!

Благодаря ви за отделеното време и още веднъж се надявам да съм бил полезен.

Етикети: , , , , , , , , , , , ,


16 коментара по “Как лесно да вземаме съдържание от сайтове”

  1. Marian Ignev казва:

    Здравейте приятели,
    искренно съм благодарен на всички вас, които сте харесали материали и ми писахте да го публикувам с блога си след като вече не пиша за Friday Code.

    Искам само да ви дам един допълнителен линк понеже в материала горе никаде не съм описвал за него, един читател ме беше помолил да му дам пример как може да взема всичките keywords от tyxo брояча си … и ето го линка: http://m.ignev.net/blog/demos/php/easy-way-to-parse-content-from-web-sites/tyxo.php

    Разбира се скрипта го има и в zip-чето което е опоменато горе.

    Още веднъж ви благодаря за милите думи :)

    Живи и здрави.

    Поздрави,
    Мариан

  2. agur казва:

    Няма зипче, иначе звучи мн интересно

  3. Аз го свалям без проблеми. Кажи ми какъв е проблема при теб?

  4. vlado казва:

    Друг начин е да използваш: http://simplehtmldom.sourceforge.net/
    Незнам самоче кое е по бързо

  5. Marian Ignev казва:

    10x :)) Излгежда готино. :))

  6. Ариел казва:

    Здравейте!Имам малък проблем.Моля за помощ.Искам да запиша два документа от Adobe Reader,но не искат да се запишат в папката ми с документи.Вчера подобни на тях се записаха,но днес не искат.Документите могат да се запишат,но не се записват в pdf формат,а се записват така:printform.php
    Можете ли да ми помогнете?Благодаря предварително!:) :) :)

  7. Чесно казано аз лично не мога да ти разбера въпроса :)

  8. Ариел казва:

    Извинете,оправих се.Проблемът беше в програмата ми.Сега е ОК. :)

  9. Браво. Съжалявам, че не можах да помогна.

  10. Boris казва:

    Демото не работи, свалих кода при мен стартирах го, пак същото…

  11. Хм … при мен излежда работи … този линк ли отваряш?

    http://m.ignev.net/blog/demos/php/easy-way-to-parse-content-from-web-sites/

  12. Boris казва:

    Да… изглежда обаче за наистина дълъг период от време сайта на дарик Навярно не се е отварял- и при мен сега е ок, но преди това общо 10 минути както при теб така и локално го пробвах- не вадеше грешка просто бяло, без да е парснат html… както и да е благодаря много за кода дава страхотни идеи за автоматизация и извличане на ресурси :)

  13. Супер … радвам се, че работи всичко коректно и се радвам, че съм успял да помогна :)

  14. Alex казва:

    Малко по-подробно може ли упътване?
    Да речем страницата на Жар, секцията компютри- http://www.jarcomputers.com/computers

    Как мога да копирам описанията, снимките, цените ?

    10х

  15. Здравей,
    ще се опитам да ти дам идеи как можеш сам да си свършиш работа с цел да се позанимаваш :)

    Първо с картинките. Първото нещо което виждам е, че нямат някакъв клас по който мога да ги хвана лесно. Виждам, че имат някакув алт таг, но за съжаление забелязвам, че и останалите картинки в сайта го имат, което отново не ни върши работа, но точно в този момент забелязвам, че има някои неща които ни помагат за тези картинки. В URL-а на картинката има „_87x87.“ също така има и align=“left“ таг, което ни помага да кажем. „Дай ми всички img-та които съдържат в урл-а си _87x87. и имат align=’left’ „. Примерно :)

    За описанието, съвета ми е да си вземеш спановете с клас „name“.

    Зената вземаш strong елементите за които ти match-ва „price“. След това имаш малко работа да изчистиш излишаната информация и си готов.

    Надявам се да съм помогнал.

    Поздрави,
    Мариан

  16. [...] Как лесно да вземаме съдържание от сайтове « Блогът на …. Натисни тукEmailPrintFacebookRedditDiggPinterestTwitterLinkedInTumblrОщеStumbleUponLike this:LikeBe the first to like this post. [...]

Вашият коментар