Страница 496 из 502
Программе MiniCrawler присущ ряд ограничений. Во-первых, в ней обнаруживаются только абсолютные ссылки, указываемые по гипертекстовой команде href="http. Относительные ссылки при этом не обнаруживаются. Во-вторых, возврат к предыдущей ссылке в программе не предусматривается. И в-третьих, в ней отображаются только ссылки, но не окружающее их содержимое. Несмотря на все указанные ограничения данного скелетного варианта поискового робота, он вполне работоспособен и может быть без особых хлопот усовершенствован для решения других задач. На самом деле добавление новых возможностей в программу MiniCrawler — это удобный случай освоить на практике сетевые классы и узнать больше о сетевом подключении к Интернету. Ниже приведен полностью исходный код программы MiniCrawler.
<b>/* MiniCrawler: скелетный вариант поискового робота.</b>
<b>Применение: для запуска поискового робота укажите URI в командной строке. Например, для того чтобы начать поиск с адреса www.McGraw-Hill.com, введите следующую команду:</b>
<b>MiniCrawler http://McGraw-Hill.com</b>
<b>*/</b>
<b>using System;</b>
<b>using System.Net;</b>
<b>using System.IO;</b>
<b>class MiniCrawler {</b>
<b> // Найти ссылку в строке содержимого,</b>
<b> static string FindLink(string htmlstr,</b>
<b> ref int startloc) {</b>
<b> int i;</b>
<b> int start, end;</b>
<b> string uri = null;</b>
<b> i = htmlstr.IndexOf("href="http", startloc,</b>
<b> StringComparison.OrdinalIgnoreCase);</b>
<b> if (i != -1) {</b>
<b> start = htmlstr.IndexOf('"', i) + 1;</b>
<b> end = htmlstr.IndexOf('"', start);</b>
<b> uri = htmlstr.Substring(start, end - start);</b>
<b> startloc = end;</b>
<b> }</b>
<b> return uri;</b>
<b> }</b>
<b> static void Main(string[] args) {</b>
<b> string link = null; string str; string answer;</b>
<b> int curloc; // содержит текущее положение в ответе</b>
<b> if (args.Length != 1) {</b>
<b> Console.WriteLine("Применение: MiniCrawler <uri>");</b>
<b> return;</b>
<b> }</b>
<b> string uristr = args[0]; // содержит текущий URI </b>
<b> HttpWebResponse resp = null;</b>
<b> try {</b>
<b> do {</b>
<b> Console.WriteLine("Переход по ссылке " + uristr);</b>
<b> // Создать объект запроса типа WebRequest по указанному URI.</b>
<b> HttpWebRequest req = (HttpWebRequest)</b>
<b> WebRequest.Create(uristr);</b>
<b> uristr = null; // запретить дальнейшее использование этого URI</b>
<b> // Отправить сформированный запрос и получить на него ответ,</b>
<b> resp = (HttpWebResponse)req.GetResponse();</b>
<b> Stream istrm = resp.GetResponseStream();</b>
<b> // Заключить поток ввода в оболочку класса StreamReader.</b>
<b> StreamReader rdr = new StreamReader(istrm);</b>
<b> // Прочитать всю страницу,</b>
<b> str = rdr.ReadToEnd();</b>
<b> curloc = 0;</b>
<b> do {</b>
<b> // Найти следующий URI для перехода по ссылке,</b>
<b> link = FindLink(str, ref curloc);</b>
<b> if (link != null) {</b>
<b> Console.WriteLine("Найдена ссылка: " + link);</b>
<b> Console.Write("Перейти по ссылке, Искать дальше, Выйти?");</b>
<b> answer = Console.ReadLine();</b>
<b> if (string.Equals(answer, "П", StringComparison.OrdinalIgnoreCase)) {</b>
<b> uristr = string.Copy(link); break;</b>
<b> }</b>
<b> else if (string.Equals(answer, "B", StringComparison.OrdinalIgnoreCase)) {</b>
<b> break;</b>
<b> }</b>
<b> else if (string.Equals(answer, "И", StringComparison.OrdinalIgnoreCase)) {</b>
<b> Console.WriteLine("Поиск следующей ссылки.");</b>
<b> }</b>