Парсинг с CsQuery: время ожидания операции истекло


В предыдущей статье я показал вам, как можно получать информацию с сайтов при помощи CsQuery. Вроде бы все прекрасно. Собрали с одной страницы адреса других страниц (организаций, товаров – смотря что мы там парсим); записали их в файл; прочитали его; создали цикл и ждем завершения. Однако, не все так просто, нередко возникают ошибки. В данной заметке мы разберем такую как «время ожидания операции истекло».

Простой код:

  string[] adresa = new string[3000];
            int chett = -1;
            using (StreamReader fs = new StreamReader(@"mingkh.txt"))
            {
                while (true)
                {
                    chett++;
                    string temp = fs.ReadLine();
                    if (temp == null) break;
                    else adresa[chett] = temp;
                }
            }

            for (int i = 0; i < chett; i++)
            {
                CQ dom = CQ.CreateFromUrl(adresa[i]);

                foreach (IDomObject obj in dom.Find("dd"))
                {
                    if (obj.TextContent != "")
                    {
                        textBox1.Text += obj.TextContent;
                    }
                }
            }
Запускаем его для одного-двух адресов, убеждаемся, что все в порядке; пробуем запустить для тысячи и через минуту видим вот такую ошибку:

Время ожидания операции истекло

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

Создавать свой класс WebClient, в котором уже задавать свой таймаут. К примеру, минут на 20:

 private class MyWebClient : WebClient
        {
            protected override WebRequest GetWebRequest(Uri uri)
            {
                WebRequest w = base.GetWebRequest(uri);
                w.Timeout = 20 * 60 * 1000;
                return w;
            }
        }
Используем же его так:
for (int i = 0; i < chett; i++)
            {
                using (MyWebClient client = new MyWebClient())
                {
                    client.Encoding = Encoding.UTF8;
                    string htmlCode = client.DownloadString(adresa[i]);
                    CQ dom = CQ.Create(htmlCode, Encoding.UTF8);
                    foreach (IDomObject obj in dom.Find("dd"))
                    {
                        textBox1.Text += obj.TextContent+ System.Environment.NewLine;
                    }
                }
            }
Обратите внимание, что если кодировка сайта-донора отличается от Windows-1251, то необходимо указывать её самостоятельно. В нашем случае это UTF8. Запускаем код и видим, что все прекрасно работает:



Стоит отметить, что при серьезном парсинге надо знать немало таких мелочей. Если будет время, то в дальнейших заметках я расскажу вам о других возможных ошибках и подводных камнях.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, CsQuery, си шарп, парсинг, парсинг сайтов




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Когда заработает поддомен?
Создание графика по точкам на Java
Вопросы и ответы на собеседовании PHP программиста