Получить все ссылки с html файла
preg_match_all('/(<a[^>]*)href=(\"?)([^\s\">]+?)(\"?)([^>]*>)/ismU',$text,$res);
В $res[3] будут нужные вам ссылки.
preg_match_all('/(<a[^>]*)href=(\"?)([^\s\">]+?)(\"?)([^>]*>)/ismU',$text,$res);
Все, кто занимается продвижением или делает это не специально, интересуется позициями своего сайта/сайтов. Хоть и каждый для этого дела использует разные программы/скрипты, я предлагаю же создать что-то под себя почти с нуля. Сегодня мы будем снимать позиции с популярной в России поисковой системы Яндекс. Яндекс разработчикам предлагает очень удобный интерфейс для взаимодействия. Благодаря которому мы с легкостью можем встроить на свой сайт поиск или что-нибудь полезное еще. Но сегодня мы ограничимся лишь снятием для конкретного сайта и ключевого слова позиции. В начале нам зарегистрировать свой IP-адрес, потому как Яндекс накладывает ограничение на количество запросов с одного IP-адреса, но их с лихвой хватит для нескольких сайтов. Нетерпеливым предлагаю сразу скачать исходник со всеми скриптами и картинкой, отображающейся когда идет запрос, но еще не получен результат. И тут применяется AJAX технология, реализовать которую нам помог так любимый мной jQuery.
Для начала сам файл, который и будет принимать наши запросы с позицией и сайтом, формировать XML и отправлять Яндексу.
Файл post.php
<?php header ("Content-Type: text/html;charset=utf-8"); $host = isset($_REQUEST['host']) ? $_REQUEST['host'] : ''; $query = isset($_REQUEST['query']) ? $_REQUEST['query'] : ''; $query_esc = htmlspecialchars($query); $host_esc = htmlspecialchars($host); $host = preg_replace("[^http://|www\.]", '', $host); $page = 0; $found = 0; $pages = 50; $error = false; $exit = 0; while (!$exit && $page < $pages && $host) { // XML запрос $doc = <<<DOC <?xml version='1.0' encoding='utf-8'?> <request> <query>$query_esc</query> <page>$page</page> <maxpassages>0</maxpassages> <groupings> <groupby attr='d' mode='deep' groups-on-page='10' docs-in-group='1' curcateg='-1'/> </groupings> </request> DOC; $context = stream_context_create(array( 'http' => array( 'method'=>"POST", 'header'=>"Content-type: application/xml\r\n" . "Content-length: " . strlen($doc), 'content'=>$doc ) )); $response = file_get_contents('http://xmlsearch.yandex.ru/xmlsearch', true, $context); if ( $response ) { $xmldoc = new SimpleXMLElement($response); $xmlresponce = $xmldoc->response; if ($xmlresponce->error) { print "Возникла следующая ошибка: " . $xmlresponce->error . "<br/>\n"; $exit = 1; $error = true; break; } $pos = 1; $nodes = $xmldoc->xpath('/yandexsearch/response/results/grouping/group/doc/url'); foreach ($nodes as $node) { if ( preg_match("/^http:\/\/(www\.)?$host/i", $node) ) { $found = $pos + $page * 10; $exit = 1; break; } $pos++; } $page++; } else { print "внутренняя ошибка сервера\n"; $exit = 1; } } if (!$error) { // если что-то найдено, то выводим результат if ($found) { print $found; } elseif ($host) { print "<p>сайт находится далее, чем на ". $pages*10 ." месте в выдаче"; } } ?>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> $('document').ready(function() { $('img.busy').hide(); $("button#push").click(function() { $('div#output div').text(''); var host = $('input#host').val(); var query = $('input#query').val(); var queryString = '/post.php?query=' + query + "&host=" + host; $('img.busy').bind("ajaxSend", function() { $(this).show(); }).bind("ajaxComplete", function() { $(this).hide(); }); $.get(queryString, function(data) { $('div#output div').text(data); }); }); }); </script> </head> <body> <table width="40%" border="0" align="center" cellpadding="3" cellspacing="3"> <tr> <td>хост</td> <td><input id="host" type="text"></td> <td><center><div id="output"><img src="img/ajax.gif" class="busy"/><div></div></div></center></td> </tr> <tr> <td>запрос</td> <td><input id="query" type="text"></td> <td><center><button id="push">запросить</button></center></td> </tr> </table> </body> </html>
Часто в "robots.txt" мы видим запись
Sitemap: http://sait.ru/Sitemap.xml.
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://f9r.ru/</loc> <priority>1</priority> <changefreq>hourly</changefreq> </url> <url> <loc>http://f9r.ru/index.html</loc> <priority>0.5</priority> <changefreq>weekly</changefreq> </url> <url> <loc>http://f9r.ru/all.php?act=forum&how=web</loc> <priority>0.1</priority> <changefreq>monthly</changefreq> </url> </urlset>
<urlset> Здесь основная инфа </urlset>
<url> Здесь инфа об URLах </url>
<loc>ИМЯ URLа</loc> <priority>Приоритет URLа</priority> <changefreq>Как часто сканировать URL</changefreq>
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} ˆ/Sitemap\.xml$ [NC] RewriteRule ˆ.* /sitemap.php?type=xml [L]
<?php # Определим $_User_host, подробнее о функии ip() здесь... $_User_ip = ip(); $_User_host = @gethostbyaddr ($_User_ip); // узнаем host робота # $_BName и $_Brobot определим, подробнее о функции здесь... $_ARR = detect_browser ($_User_agent); $_BName = $_ARR[0]; // если робот, то вывод будет $_BName = Robot $_Brobot = $_ARR[3]; // имя робота # если зашел робот if ( $_BName == 'Robot' ){ # Плохой броузер, который представляется Google Yandex Yahoo Rambler Msnbot Aport Mail.Ru if ( $_User_ip != $_User_host and ( $_Brobot == 'Googlebot' or $_Brobot == 'Yandex' or $_Brobot == 'Rambler' or $_Brobot == 'Yahoo' or $_Brobot == 'Msnbot' or $_Brobot == 'Aport' or $_Brobot == 'Mail.Ru') ){ # проверяем не врет ли нам робот, сверяя его имя с имененм хоста if ( ( $_Brobot == 'Googlebot' and ! preg_match ('~googlebot\.com~', $_User_host) ) or ( $_Brobot == 'Yandex' and ! preg_match ('~yandex(\.ru|\.net)~', $_User_host) ) or ( $_Brobot == 'Rambler' and ! preg_match ('~rambler~', $_User_host) ) or ( $_Brobot == 'Yahoo' and ! preg_match ('~yahoo\.net~', $_User_host) ) or ( $_Brobot == 'Aport' and ! preg_match ('~wmd\.rol\.ru~', $_User_host) ) or ( $_Brobot == 'Mail.Ru' and ! preg_match ('~mail\.ru~', $_User_host) ) or ( $_Brobot == 'Msnbot' and ! preg_match ('~search\.(live|msn)\.com~', $_User_host) ) ) # если врет выводим error 401 { print 'error 401'; } # если НЕ врет выводим sitemap.php else { # печатаем начало "Sitemap.xml" $content = '<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> '; # считываем файл 'data/site_map.dat' - в этом файле построчно лежат # все наши Urlы плюс через "::" их значимость от 1 до 10 (приоритет) $general = file ( 'data/site_map.dat' ); $lines = count ($general); # прогоняем все это в цикле for ($i=0; $i<$lines; $i++){ list ($url, $level) = explode ("::",$general[$i]); # чему равен приоретет if ($level == 0) { $changefreq = 'hourly'; } elseif ($level < 3) { $changefreq = 'weekly'; } else { $changefreq = 'monthly'; } if ($url=='') { $priority = 1; } else { $priority = 1 - $level/10; } # выводим url, заменяя в нем "&" на "&" $url = str_replace ('&', '&', $url); # добавляем к $content $content .= " <url> <loc>http://f9r.ru/".$url."</loc> <priority>".$priority."</priority> <changefreq>".$changefreq."</changefreq> </url>\n"; } # когда цикл закончился, добавляем к $content конечный тег $content .= "</urlset>\n"; # печатем $content echo $content; } } } # если файл пытается скачать броузер отдаем ему ошибку else { print 'error 410'; } ?>
RSS (really simple syndication) был разработан фирмой netscape и представляет собой расширение xml созданное специально для оформления новостных лент.
На сегодняшний день формат пережил уже 2-ю редакцию и является общепринятым стандартом для разметки новостей.
Вот пример простого rss документа:
<?xml version="1.0" encoding="windows-1251"?> <!doctype rss public "-//netscape communications//dtd rss 0.91//en" "http://my.netscape.com/publish/formats/rss-0.91.dtd <rss version="0.91"> <channel> <title>none</title> <description>заполнение пустоты</description> <link>http://riscom.com/~none</link> </channel> <image> <title>none</title> <url>http://riscom.com/~none/favicon.gif</url> <link>http://riscom.com/~none</link> <width>16</width> <height>16</height> </image> <item> <title>rss - вкусные новости </title> <link>http://riscom.com/~none/</link> <description>Что такое rss и с чем его едят</description> </item> </rss>
<?php function startelement($parser, $name, $attrs) { global $tag, $rss; if ($name == 'rss') $rss = '^rss'; elseif ($name == 'rdf:rdf') $rss = '^rdf:rdf'; $tag .= '^' . $name; } function endelement($parser, $name) { global $tag; global $itemcount, $items; if ($name == 'item') { $itemcount++; if (!isset($items[$itemcount])) $items[$itemcount] = array('title' => '', 'link' => '', 'desc' => '', 'pubdate' => ''); } $tag = substr($tag, 0, strrpos($tag, '^')); } function characterdata($parser, $data) { global $tag, $chantitle, $chanlink, $chandesc, $rss, $imgtitle, $imglink, $imgurl; global $items, $itemcount; $rsschannel = ''; if ($data) { if ($tag == $rss . '^channel^title') { $chantitle .= $data; } elseif ($tag == $rss . '^channel^link') { $chanlink .= $data; } elseif ($tag == $rss . '^channel^description') { $chandesc .= $data; } if ($rss == '^rss') $rsschannel = '^channel'; if ($tag == $rss . $rsschannel . '^item^title') { $items[$itemcount]['title'] .= $data; } elseif ($tag == $rss . $rsschannel . '^item^link') { $items[$itemcount]['link'] .= $data; } elseif ($tag == $rss . $rsschannel . '^item^description') { $items[$itemcount]['desc'] .= $data; } elseif ($tag == $rss . $rsschannel . '^item^pubdate') { $items[$itemcount]['pubdate'] .= $data; } elseif ($tag == $rss . $rsschannel . '^image^title') { $imgtitle .= $data; } elseif ($tag == $rss . $rsschannel . '^image^link') { $imglink .= $data; } elseif ($tag == $rss . $rsschannel . '^image^url') { $imgurl .= $data; } } } function parserss($url) { global $tag, $chantitle, $chanlink, $chandesc, $rss, $items, $itemcount, $imgtitle, $imglink, $imgurl; $chantitle = ''; $chanlink = ''; $chandesc = ''; $imgtitle = ''; $imglink = ''; $imgurl = ''; $tag = ''; $rss = ''; global $items, $itemcount; $itemcount = 0; $items = array(0 => array('title' => '', 'link' => '', 'desc' => '', 'pubdate' => '')); $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "startelement", "endelement"); xml_set_character_data_handler($xml_parser, "characterdata"); @$fp = fopen($url, "r"); $data = ""; while (true) { @$datas = fread($fp, 4096); if (strlen($datas) == 0) { break; } $data .= $datas; } @fclose($fp); if ($data != '') { $xmlresult = xml_parse($xml_parser, $data); $xmlerror = xml_error_string(xml_get_error_code($xml_parser)); $xmlcrtline = xml_get_current_line_number($xml_parser); if ($xmlresult) displaydata(); else print("error parsing this feed !<br />error: $xmlerror , at line: $xmlcrtline"); } else { print("error while retriving feed $url"); } xml_parser_free($xml_parser); } function displaydata() { global $chantitle, $chanlink, $chandesc, $rss, $items, $itemcount, $imgtitle, $imglink, $imgurl; global $items, $itemcount; ?> <html><head><title><?= $chantitle ?></title></head> <body> <div> <a href="<?= $chanlink ?>"><img src="<?= $imgurl ?>" alt="<?= $imgtitle ?>" border="0" /></a> <h1><?= $chantitle ?></h1> <h3><?= $chandesc ?></h3> </div> <hr /> <?php for($i = 0;$i < count($items)-1;$i++) { echo "<h4>".$items[$i]['title']."</h4>"; echo "<h5>".$items[$i]['pubdate']."</h5>"; echo "<a href='".$items[$i]['link']."'>".$items[$i]['desc']."</a>"; } ?> </body></html> <?php } $url="http://xmlhack.ru/index.rdf"; parserss($url); ?>
Первоначально я предполагал сделать выпуск "Народной самодеятельности" со сборником ошибок, допущеных в основном мною :). Кое-что я собирал из статей о традиционных ошибках и т.п. Но жизнь оказывается куда интересней! Пишу про очередную самодеятельность прямо по горячим следам.
Итак, некоторый человек, назовем его Вася, спрашивает Общественность форума про MySQL.
В.: Не совсем понятно как создать связь между таблицами, чтобы в поле первой автоматически вставлялись данные второй (есно выборочно и есно по ИД).
Варивант типа SELECT db.user, db.delete_priv, user.user, user.delete_priv FROM db,user WHERE db.user = user.user не совсем подходит, так как связью это можно назвать с большой натяжкой...
O.: Честно говоря, не понимаю, почему эта связь тебе не подходит? Чем эта связь натянута?
В.: Ну не нравится мне связь, основанная на синтаксисе запросов... хотелось бы чего-нибудь более существенного, иначе я вообще не вижу смысла в ключах и индексах.
O.: Более существенное - ты имеешь в виду графический интерфейс как в MS Access?
К сожалению, сам Access работает точно так же — достаточно нажать кнопочку "SQL", и вы увидите эти связи "с большой натяжкой".
В.: Просто мне проще программно все это делать, благо таблицы небольшие... Раз в самом MySQL это не работает.
O.: Через вложенные циклы, рекурсии? Скажи зачем тогда тебе вообще база данных и таблицы?
В.: Никаких вложенных циклов и рекурсий — читаю н-ое колмчество массивов и с ними уже работаю.... А делать связь на основе селекта — не совсем то что мне нужно...
O.: Правильно... храни все в файликах, тогда вообще вопросов не будет.
В общем, считаю своим долгом разложить по полочкам связи таблиц.
Кстати, насчёт связей - вот мнение признанного авторитета - Voodoo ;) : более существенное - это поддержка reference www.mysql.com/documentation/mysql/commented/manual.php?section=CREATE_TABLE
create table.....
reference_definition: REFERENCES tbl_name [(index_col_name,...)]
[MATCH FULL | MATCH PARTIAL]
[ON DELETE reference_option]
[ON UPDATE reference_option]
$res1 = mysql_query("SELECT id, name FROM rubs"); while ($row = mysql_fetch_row($res1)) $rub[$row[0]] = $row[1];
$res2 = mysql_query("SELECT id, url, name, rub FROM sites WHERE какое-то-там-условие"); while ($row = mysql_fetch_array($res2)) { echo "<a href=", $row["url"], ">", $row["name"], "</a>"; echo "(рубрика <a href=rub.phtml?id=", $row["id"], ">"; echo $rub[$row["rub"]], "</a><br>"; };
$res = mysql_query("SELECT sites.id, url, sites.name as sitename, rubs.name as rubsname, rubs.id as rub_id FROM sites, rubs WHERE sites.rub=rubs.id и-какое-то-там-условие"); while ($row = mysql_fetch_array($res2)) { echo "<a href=", $row["url"], ">", $row["sitename"], "</a>"; echo "(рубрика <a href=rub.phtml?id=", $row["rub_id"], ">"; echo $row["rubsname"], "</a><br>"; };
SELECT <fields> FROM table1 INNER JOIN table2 ON table1.field1=table2.field
SELECT <fields> FROM table1, table2 WHERE table1.field1=table2.field2
SELECT <fields> FROM table1 INNER JOIN table2 USING (field1)
SELECT <fields> FROM table1 LEFT JOIN table2 ON table1.field1=table2.field2
SELECT <fields> FROM table1 LEFT JOIN table2 USING (field1)
SELECT rubs.id, name, COUNT(sites.id) AS sites FROM rubs LEFT JOIN sites ON rubs.id=sites.rub GROUP BY rubs.id