«, «

Поисковый бот php скрипт

. то есть, программу-«паучка», поисковый бот, который ходит по страницам и собирает информацию с них.

По сути, нам просто нужно некий заданный URL-адрес рекурсивно проанализировать на заданную глубину ссылок и получить оттуда контент.

Мы будем просто вываливать разметку в браузер, точней, в отдельные поля для каждого URL-адреса, вместо этого в реальном приложении вы будете выполнять с кодом найденных страниц какой-то дополнительный разбор.

Если хочется обойтись одной функцией, для начала она может выглядеть так:

 $seen[$url] = true; //проиндексировано! $dom = new DOMDocument('1.0'); //Удобнее всего - через объект DOMDocument @$dom->loadHTMLFile($url); $anchors = $dom->getElementsByTagName('a'); //Получить все ссылки foreach ($anchors as $element) < //И перебрать их $href = $element->getAttribute('href'); //Получить из атрибут href if (strpos($href, 'http')!==0) < //Разбираем полные URL $path = '/' . ltrim($href, '/'); if (extension_loaded('http')) < $href = http_build_url($url, array('path' =>$path)); > else < $parts = parse_url($url); $href = $parts['scheme'] . '://'; if (isset($parts['user']) && isset($parts['pass'])) < $href .= $parts['user'] . ':' . $parts['pass'] . '@'; >$href .= $parts['host']; if (isset($parts['port'])) < $href .= ':' . $parts['port']; >$href .= $path; > > crawlURL($href, $depth - 1); > $html = @$dom->saveHTML(); $html = htmlspecialchars($html, ENT_QUOTES | ENT_SUBSTITUTE, 'Windows-1251'); //. if (!empty($html)) echo '
'.PHP_EOL.$url.' '; > crawlURL('http://nickolay.info', 2); ?>

В последней строке — вызов функции для головной страницы моего домашнего сайта. Обратите также внимание на строчку с комментарием //. в конце листинга. Начиная с PHP 5.4 существенно правильное указание кодировки и опций для функции htmlspecialchars, иначе можно получить на выходе пустую строку.

Если найденный контент никуда выводить не нужно, то действие с htmlspecialchars лишнее.

Ну и всегда бывает удобнее написать отдельный класс, приведу код несложного класса-краулера crawler.php

depth = $depth; > public function setHost($host) < $this->host = $host; > public function getResults() < return $this->results; > public function setSameHost($same_host) < $this->same_host = $same_host; > public function setUrl($url) < $this->url = $url; $this->setHost ($this->getHostFromUrl($url)); > public function __construct($url = null, $depth = null, $same_host = false) < //Аргументы конструктора: URL, глубина сканирования, сканировать ли только этот хост if (!empty($url)) $this->setUrl($url); if (isset($depth) && !is_null($depth)) $this->setDepth($depth); $this->setSameHost($same_host); > public function crawl() < //Основной вызываемый метод if (empty($this->url)) throw new \Exception('URL not set!'); $this->_crawl ($this->url, $this->depth); return $this->results; > private function _crawl($url, $depth) < //Приватная функция сканирования static $seen = array(); if (empty($url)) return; if (!$url = $this->buildUrl($this->url, $url)) return; if ($depth === 0 || isset($seen[$url])) return; $seen[$url] = true; $dom = new \DOMDocument('1.0'); @$dom->loadHTMLFile($url); $this->results[] = array ( //Массив результатов сканирования 'url' => $url, 'content' => @$dom->saveHTML() ); $anchors = $dom->getElementsByTagName('a'); foreach ($anchors as $element) < if (!$href = $this->buildUrl($url, $element->getAttribute('href'))) continue; $this->_crawl($href, $depth - 1); > return $url; > private function buildUrl($url, $href) < //Построение URL $url = trim($url); $href = trim($href); if (strpos($href, 'http')!==0) < //Не сканируем яваскрипт и внутренние якоря: if (strpos($href, 'javascript:')===0 || strpos($href, '#')===0) return false; //Остальное смотрим: $path = '/' . ltrim($href, '/'); if (extension_loaded('http')) $new_href = http_build_url($url, array('path' =>$path), HTTP_URL_REPLACE, $parts); else < $parts = parse_url($url); $new_href = $this->buildUrlFromParts($parts); $new_href .= $path; > //Относительные адреса, типа ./page.php if (strpos($href, './') && !empty($parts['path'])===0) < //Путь не заканчивантся слешем if (!preg_match('@/$@', $parts['path'])) < $path_parts = explode('/', $parts['path']); array_pop ($path_parts); $parts['path'] = implode('/', $path_parts) . '/'; >$new_href = $this->buildUrlFromParts($parts) . $parts['path'] . ltrim($href, './'); > $href = $new_href; > if ($this->same_host && $this->host != $this->getHostFromUrl($href)) return false; return $href; > private function buildUrlFromParts($parts) < $new_href = $parts['scheme'] . '://'; if (isset($parts['user']) && isset($parts['pass'])) $new_href .= $parts['user'] . ':' . $parts['pass'] . '@'; $new_href .= $parts['host']; if (isset($parts['port'])) $new_href .= ':' . $parts['port']; return $new_href; >private function getHostFromUrl($url) < $parts = parse_url($url); preg_match ("@([^/.]+)\.([^.](?:\.[^.])?)$@", $parts['host'], $host); return array_shift($host); > > ?>

и пример вызова класса, скажем, из файла index.php , находящегося в той же папке

crawl(); foreach ($results as $item) < $html = htmlspecialchars($item['content'], ENT_QUOTES | ENT_SUBSTITUTE, 'Windows-1251'); //. echo PHP_EOL.'
'.$item['url'].' '; > ?>

В классе удобно то, что можно ограничить сканирование только текущим хостом (третий параметр вызова конструктора).

При запуске скрипта нужно учесть, что он может потребовать немалого процессорного времени, особенно исполняясь в один поток. Есть в сети и гораздо более мощные проекты по теме.

Читайте также:  Строковый метод find python

09.09.2017, 10:59 [4105 просмотров]

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

License

Durendal/webBot

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

A web scraper written in PHP

webBot.php aims to simplify the use of cURL with php. At the moment it only handles GET and POST HTTP requests but I may add more to it as time and interest permits. It should work with HTTP and SOCKS proxies, the default behaviour is to use HTTP, to enable SOCKS proxies you must either declare it as the second parameter when instantiating the bot as in the first example below, or you must set it as the second parameter using the setProxy() method.

BTC: 3QjZrbqe8EGV9E6mTr2J5rkuqHVTGdXRH2 

An example of using it with tor:

require_once 'src/HTTPBot.php'; use Durendal\webBot as webBot; $bot = new webBot\HTTPBot("127.0.0.1:9050", "SOCKS"); $page = $bot->requestGET("http://zqktlwi4fecvo6ri.onion/wiki/index.php/Main_Page"); file_put_contents("index.html", $page); // index.html contains the html of the page 

if you then ran setProxy() with no parameters it would clear the proxy settings and the same request would fail:

$bot->setProxy(); $page = $bot->requestGET("http://zqktlwi4fecvo6ri.onion/wiki/index.php/Main_Page"); file_put_contents("index.html", $page); // index.html is an empty file 

Headers can be completely customized, although the defaults are enough to make basic requests. These values can also be overridden, added to, or deleted at any time.

if($bot->checkHeader("Keep-alive")) $bot->delHeader("Keep-alive"); $bot->addHeader("Keep-alive: 300"); if($bot->checkHeader("User-Agent")) $bot->delHeader("User-Agent"); $bot->addHeader("User-Agent: " . $bot->randomAgent()); 

POST parameters should be sent as an array through generatePOSTData() which will ensure they are urlencoded and properly formatted:

$pdata = array("username" => "Durendal", "password" => "abc&123", "submit" => "true"); $result = $bot->requestPOST("http://www.example.com/login.php", $bot->generatePOSTData($pdata)); if(stristr($result, "Login Successful")) print "Successfully logged in\n"; else print "Failed to log in\n"; 

This class also comes packaged with a number of parsing routines written by Mike Schrenk for his book Webbots, Spiders and Screenscrapers that I have found extremely useful in the past.

require_once 'src/HTTPBot.php'; use Durendal\webBot as webBot; $bot = new webBot\HTTPBot(); $subreddit = ($argc > 1) ? $argv[1] : 'talesfromtechsupport'; $page = $bot->requestGET("http://www.reddit.com/r/$subreddit/.rss"); $posts = $bot->parseArray($page, "", ""); $titles = array(); $links = array(); for($i = 0; $i < count($posts); $i++) < $titles[$i] = $bot->returnBetween($posts[$i], "", 1); $links[$i] = $bot->returnBetween($posts[$i], "", "", 1); print "Title #$i: ".$titles[$i]."\n"; print "Link #$i: ".$links[$i]."\n"; > 

This script takes an optional parameter of a subreddit name the default is ‘talesfromtechsupport’ It will scrape the RSS feed and post the front page of posts. This should illustrate the basic principles of using the bot. All parsing methods were adapted from original code written by Mike Schrenk in his book ‘Webbots spiders and Screenscrapers’

Читайте также:  Java string examples array strings

This class is able to leverage the curl_multi_* functions to make multiple requests at once in batch mode. You can use a proxy with this function the same as you would with any other request, however at this time there is no way to specify a different proxy for each request. This may change in the future if I get the time. Send an array of arrays as the sole parameter, each array should have at least one element: the URL. If the request is a POST request place a second value inside the array that is an array of POST parameters. You can mix and match POST and GET requests, it will determine which is which at execution time.

require_once 'src/HTTPBot.php'; use Durendal\webBot as webBot; $bot = new webBot\HTTPBot("127.0.0.1:9050", "SOCKS"); $creds = array("username" => "Durendal", "password" => "abc&123", "submit" => "true"); $sites = array(array("http://www.google.com"), array("http://www.bing.com"), array("http://www.cnn.com"), array("http://zqktlwi4fecvo6ri.onion"), array("http://www.example.com/login.php", $creds)); $results = $bot->curlMultiRequest($sites); foreach($results as $key => $page) < $key = str_replace(array("http://", "https://"), "", $key); print "Len: " . strlen($page) . "\n"; file_put_contents("$key.html", $page); >

You can optionally build a queue of URLs to scrape that acts as a FILO (First in last out) queue. This can work for individual or curl_multi_ requests, if its an individial request it will pop off the top URL and process it. If you run curl_multi it will process the entirety of the queue. In the future I may implement the option of selecting the number of urls to process. If there are items on the queue and you run requestGET(), requestPOST(), or requestHTTP() with an explicit url the queue will remain unaffected and the request will process normally.

// Disable Proxy $bot->setProxy(); $bot->pushURL("http://www.reddit.com/r/circlejerk/.rss"); $bot->pushURL("http://www.reddit.com/r/bitcoin/.rss"); $bot->pushURL("http://www.reddit.com/r/jobs4bitcoins/.rss"); // Pop the top URL from the stack and execute a request $page = $bot->requestGET(); $posts = $bot->parseArray($page, "", ""); $titles = array(); $links = array(); for($i = 0; $i < count($posts); $i++) < $ii = $i+1; $titles[$i] = $bot->returnBetween($posts[$i], "", 1); $links[$i] = $bot->returnBetween($posts[$i], "", "", 1); print "Title #$ii: ".$titles[$i]."\n"; print "Link #$ii: ".$links[$i]."\n"; > // Check the stack size print "URL Stack Size: " . $bot->urlCount() . "\n"; // Empty out the $bot->urls stack $results = $bot->curlMultiRequest(); foreach($results as $key => $page) < // Make $key a little bit nicer for a filename $key = substr(str_replace(array("http://", "https://", ".rss", "www.reddit.com/r/"), "", $key), 0, -1); print $key . " Len: " . strlen($page) . "\n"; file_put_contents("$key.html", $page); >
Viviparous Yani John Kozan 

For providing suggestions to help make webBot better 🙂

Читайте также:  Centos enable php extensions

Источник

Простая поисковая система на PHP

поисковая система на php

В этой статье вы прочитаете как делается поисковая система на PHP, код будет крайне просто и не большой, поэтому даже новичок поймёт.

Также стоит сказать, что мы уже делали подобную программу, но там был поиск чётких данных и больше подойдёт для админ панели, чтобы находить пользователей, чем для обычного поиска, например товаров, можете посмотреть её по это ссылки.

HTML:

Перед тем как начать разработку, нужно сделать в HTML форму, вот такую.

Тут просто HTML, не чего особенного нет, но если вам что то не понятно, то прочитайте учебник по HTML.

Подключение Базы данных:

Первым делом нужно подключить нам базу данных, для этого пишем вот этот код.

Как тут видите идёт обычное подключение, в начала мы объявляем переменные, в которых храним настройки базы данных для подключения к ней.

Дальше создаём объект классы mysqli , который используется для работы с БД, проверяем подключение, если есть ошибка, то выведем надпись с ней.

Основной код:

После того как подключили БД, переходим к запросу, вот код.

В начале мы получаем запрос из формы и ложем его в переменную $inputSearch , дальше создаём SQL запрос, и тут самое интересное, то что мы ищем по имени, но не просто, а по ближайшему совпадению, это делается благодаря знаку процента, он обозначает сколько угодно соответствий, а команда LIKE сравнивает эту строку, а точнее регулярное выражение, со всеми именами.

Потом делаем запрос к БД, и сохраняем результата в переменную $result . Дальше, перед тем как выводить данные, сделаем две функции, первая не много структурирует данные, а вторая уже выводит.

В этой функции мы немного настраиваем вывод не обязательных данных, по сути мы проверяем, если та или иная информация, и что бы не выводилось пустая строка, мы наменяем на строку «Нет данных».

Давайте разберём этот код, в качестве параметра она принимает результат запроса к БД, сперва идёт проверка, есть ли вообще строки, если их нет, то выводим надпись «Не кто не найден», если же есть, то строим цикл, в нём проходимся по всем строкам, там же и используем функцию doesItExist() .

Дальше вызываем эту функцию где-нибудь в HTML коде. там где вам надо, я же вызову её после тега form, и вот что получилось, если мы в поиск ведём просто букву «Д».

скрипт поисковой системы php

Вывод:

В этой статье вы прочитали как делается простая поисковая система на PHP, тут было только самое основное, но я уверен вы сможете её дополнить, также можете скачать скрипт этой программы, что бы самим всё проверить.

Источник

Оцените статью