Получить все ссылки с 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