Выбрать главу
ируется запрос, и переменной uristr присваивается пустое значение, указывающее на то, что данный URI уже использован. Далее отправляется запрос и получается ответ. После этого со держимое читается из потока ввода, возвращаемого методом GetResponseStream() и заключаемого в оболочку класса StreamReader. Для этой цели вызывается метод ReadToEnd(), возвращающий все содержимое в виде строки из потока ввода. Далее программа осуществляет поиск ссылки в полученном содержимом. Для этого вызывается статический метод FindLink(), определяемый в программе MiniCrawler. Этот метод вызывается со строкой содержимого и исходным положением, с которо го начинается поиск в полученном содержимом. Эти значения передаются методу FindLink() в виде параметров htmlstr и startloc соответственно. Обратите внима ние на то, что параметр startloc относится к типу ref. Сначала в методе FindLink() создается копия строки содержимого в нижнем регистре, а затем осуществляется по иск подстроки href="http, обозначающей ссылку. Если эта подстрока найдена, то URI копируется в строковую переменную uri, а значение параметра startloc об новляется и становится равным концу ссылки. Но поскольку параметр startloc от носится к типу ref, то это приводит к обновлению соответствующего аргумента ме тода Main(), активизируя поиск с того места, где он был прерван. В конечном итоге возвращается значение переменной uri. Эта переменная инициализирована пустым значением, и поэтому если ссылка не найдена, то возвращается пустая ссылка, обозна чающая неудачный исход поиска. Если ссылка, возвращаемая методом FindLink(), не является пустой, то она ото бражается в методе Main(), и далее программа запрашивает у пользователя очеред ные действия. Пользователю предоставляются одна из трех следующих возможностей: перейти по найденной ссылке, нажав клавишу <П>, искать следующую ссылку в имею щемся содержимом, нажав клавишу <И>, иди же выйти из программы, нажав клави шу <В>. Если пользователь нажмет клавишу <П>, то программа осуществит переход по найденной ссылке и получит новое содержимое по этой ссылке. После этого поиск очередной ссылки будет начат уже в новом содержимом. Этот процесс продолжается до тех пор, пока не будут исчерпаны все возможные ссылки. В качестве упражнения вы сами можете усовершенствовать программу MiniCrawler, дополнив ее, например, возможностью перехода по относительным ссылкам. Сделать это не так уж и трудно. Кроме того, вы можете полностью автоматизировать поиско вый робот, чтобы он сам переходил по найденной ссылке без вмешательства со стороны пользователя, начиная со ссылки, обнаруженной на самой первой странице получен ного содержимого, и продолжая переход по ссылкам на новых страницах. Как только будет достигнут тупик, поисковый робот должен вернуться на один уровень назад, най ти следующую ссылку и продолжить переход по ссылке. Для организации именно та кого алгоритма работы программы вам потребуется стек, в котором должны храниться идентификаторы URI и текущее состояние поиска в строке URI. С этой целью можно, в частности, воспользоваться коллекцией класса Stack. В качестве более сложной, но интересной задачи попробуйте организовать вывод ссылок в виде дерева. Применение класса WebClient В заключение этой главы уместно рассмотреть класс WebClient. Как упомина лось в самом ее начале, класс WebClient рекомендуется использовать вместо классов WebRequest и WebResponse в том случае, если в приложении требуется лишь выгру жать или загружать данные из Интернета. Преимущество класса WebClient заклю чается в том, что он автоматически выполняет многие операции, освобождая от их программирования вручную. В классе WebClient определяется единственный конструктор. public WebClient() Кроме того, в классе WebClient определяются свойства, сведенные в табл. 26.6, а также целый ряд методов, поддерживающих как синхронную, так и асинхронную пе редачу данных. Но поскольку рассмотрение асинхронной передачи данных выходит за рамки этой главы, то в табл. 26.7 приведены только те методы, которые поддерживают синхронную передачу данных. Все методы класса WebClient генерируют исключение WebException, если во время передачи данных возникает ошибка. Таблица 26.6. Свойства, определенные в классе WebClient Свойство Описание public string BaseAddress { get; set; } Получает или устанавливает базовый адрес требуемого URI. Если это свойство установлено, то адреса, задава емые в методах класса WebClient, должны опреде ляться относительно этого базового адреса public RequestCachePolicy CachePolicy { get; set; } Получает или устанавливает правила, определяющие, когда именно используется кэш public ICredentials Credentials { get; set; } Получает или устанавливает мандат, т.е. учетные дан ные пользователя. По умолчанию это Свойство имеет пустое значение public Encoding Encoding { get; set; } Получает или устанавливает схему кодирования симво лов при передаче строк Таблица 26.7. Методы синхронной передачи, определенные в классе WebClient Окончание табл. 26.6 Свойство Описание public WebHeaderCollection Headers{ get; set; } Получает или устанавливает коллекцию заголовков за проса public bool IsBusy{ get; } Принимает логическое значение true, если данные по-прежнему передаются по запросу, а иначе — логи ческое значение false public IWebProxy Proxy { get; set; } Получает или устанавливает прокси-сервер public NameValueCollection QueryString { get; set; } Получает или устанавливает строку запроса, состоя щую из пар “имя-значение”, которые могут быть при соединены к запросу. Строка запроса отделяется от URI символом ?. Если же таких пар несколько, то каждая из них отделяется символом @ public WebHeaderCollection ResponseHeaders{ get; } Получает коллекцию заголовков ответа public bool UseDefaultCredentials { get; set; } Получает или устанавливает значение, которое опреде ляет, используется ли для аутентификации устанавливае мый по умолчанию мандат. Если принимает логическое значение true, то используется мандат, устанавливае мый по умолчанию, т.е. учетные данные пользователя, в противном случае этот мандат не используется Метод Определение public byte[] DownloadData(string address) Загружает информацию по адресу URI, обозначае мому параметром address. Возвращает результат в виде массива байтов public byte[] DownloadData(Uri address) Загружает информацию по адресу URI, обозначае мому параметром address. Возвращает результат в виде массива байтов public void DownloadFile(string uri, string fileName) Загружает информацию по адресу URI, обозначае мому параметром fileName. Сохраняет результат в файле fileName public void DownloadFile(Uri address, string fileName) Загружает информацию по адресу URI, обозначае мому параметром address. Сохраняет результат в файле fileName public string DownloadString(string address) Загружает информацию по адресу URI, обозначае мому параметром address. Возвращает результат в виде символьной строки типа string public string DownloadString(Uri address) Загружает информацию по адресу URI, обозначае мому параметром address. Возвращает результат в виде символьной строки типа string public Stream OpenRead(string address) Возвращает поток ввода для чтения информации по адресу URI, обозначаемому параметром address. По окончании чтения информации этот поток необ ходимо закрыть Продолжение табл. 26.7 Метод Определение public Stream OpenRead(Uri address) Возвращает поток ввода для чтения информации по адресу URI, обозначаемому параметром address. По окончании чтения информации этот поток необ ходимо закрыть public Stream OpenWrite(string address) Возвращает поток вывода для записи информа ции по адресу URI, обозначаемому параметром address. По окончании записи информации этот поток необходимо закрыть public Stream OpenWrite(Uri address) Возвращает поток вывода для записи информа ции по адресу URI, обозначаемому параметром address. По окончании записи информации этот поток необходимо закрыть public Stream OpenWrite(string address, string method) Возвращает поток вывода для записи информа ции по адресу URI, обозначаемому параметром address. По окончании записи информации этот поток необходимо закрыть. В строке, передаваемой в качестве параметра method, указывается, как именно следует записывать информацию public Stream OpenWrite(Uri address, string method) Возвращает поток вывода для записи информа ции по адресу URI, обозначаемому параметром address. По окончании записи информации этот поток необходимо закрыть. В строке, передаваемой в качестве параметра method, указывается, как именно следует записывать информацию public byte[] UploadData(string address, byte[] data) Записывает информацию из массива data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ public byte[] UploadData(Uri address, byte[] data) Записывает информацию из массива data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ public byte[] UploadData(string address, string method, byte[] data) Записывает информацию из массива data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передавае мой в качестве параметра method, указывается, как именно следует записывать информацию public byte[] UploadData(Uri address, string method, byte[] data) Записывает информацию из массива data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передавае мой в качестве параметра method, указывается, как именно следует записывать информацию public byte[] UploadFile(string address, string fileName) Записывает информацию в файл fileName по адресу URI, обозначаемому параметром address. В итоге возвращается ответ public byte[] UploadFile(Uri address, string fileName) Записывает информацию в файл fileName по адресу URI, обозначаемому параметром address. В итоге возвращается ответ Окончание табл. 26.7 В приведенном ниже примере программы демонстрируется применение класса WebClient для загрузки данных в файл по указанному сетевому адресу. Метод Определение public byte[] UploadFile(string address, string method, string fileName) Записывает информацию в файл fileName по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передавае мой в качестве параметра method, указывается, как именно следует записывать информацию public byte[] UploadFile(Uri address, string method, string fileName) Записывает информацию в файл fileName по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передавае мой в качестве параметра method, указывается, как именно следует записывать информацию public string UploadString(string address, string data) Записывает строку data по адресу URI, обозначае мому параметром address. В итоге возвращается ответ public string UploadString(Uri address, string data) Записывает строку data по адресу URI, обозначае мому параметром address. В итоге возвращается ответ public string UploadString(string addreds, string method, string data) Записывает строку data по адресу URI, обозначае мому параметром address. В итоге возвращается ответ. В строке, передаваемой в качестве параме тра method, указывается, как именно следует за писывать информацию public string UploadString(Uri address, string method, string data) Записывает строку data по адресу URI, обозначае мому параметром address. В итоге возвращается ответ. В строке, передаваемой в качестве параме тра method, указывается, как именно следует за писывать информацию public byte[] UploadValues(string address, NameValueCollection data) Записывает значения из коллекции data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ public byte[] UploadValues(Uri address, NameValueCollection data) Записывает значения из коллекции data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ public byte[] UploadValues(string address, string method, NameValueCollection data) Записывает значения из коллекции data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передаваемой в ка честве параметра method, указывается, как имен но следует записывать информацию public byte[] UploadValues(Uri address, string method, NameValueCollection data) Записывает значения из коллекции data по адресу URI, обозначаемому параметром address. В итоге возвращается ответ. В строке, передаваемой в ка честве параметра method, указывается, как имен но следует записывать информацию // Использовать класс WebClient для загрузки данных // в файл по указанному сетевому адресу. using System; using System.Net; using System.IO; class WebClientDemo { static void Main() { WebClient user = new WebClient (); string uri = "http://www.McGraw-Hill.com"; string fname = "data.txt"; try { Console.WriteLine("Загрузка данных по адресу " + uri + " в файл " + fname); user.DownloadFile(uri, fname); } catch (WebException exc) { Console.WriteLine(exc); } Console.WriteLine("Загрузка завершена."); } } Эта программа загружает информацию по адресу www.McGrawHill.com и поме щает ее в файл data.txt. Обратите внимание на строки кода этой программы, в кото рых осуществляется загрузка информации. Изменив символьную строку uri, можно загрузить информацию по любому адресу URI, включая и конкретные файлы, доступ ные по указываемому URL Несмотря на то что классы WebRequest и WebResponse предоставляют больше возможностей для управления и доступа к более обширной информации, для многих приложений оказывается достаточно и средств класса WebClient. Этим классом осо бенно удобно пользоваться в тех случаях, когда требуется только загрузка информации из веб-ресурса. Так, с помощью средств класса WebClient можно получить из Интер нета обновленную документацию на приложение.