Windows Клиент - данные с веб страницы

Язык C#: программирование на C#, портирование кода C# на VB и VB на C#.

Модератор: Ramzes

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 01.02.2010 (Пн) 21:09

Приветствую!

Есть такая задача:
Написать клиента проверяющего список филиалов одной компании.

Структура веб сервера такова:
Есть страница со списком филиалов, далее вложенные страницы с описанием филиалов

Итак сначала получаем список:

Код: Выделить всё
        private void button1_Click(object sender, EventArgs e)
        {
            #if(DEBUG)
                Stopwatch sw = new Stopwatch();
                sw.Start();
            #endif

            string server = this.textBox1.Text.Trim();
            string Get = "GET /filialen.html HTTP/1.1\r\nHost: " + server +
                "\r\nUserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6\r\n" +
                "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
                "Accept-Encoding: gzip,deflate\r\n"+
                "Accept-Charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
                "Connection: Close\r\n\r\n";

            Encoding encoding = Encoding.GetEncoding(28591);
            Byte[] byteGet = encoding.GetBytes(Get);
            Byte[] byteRecv = new Byte[512];
            Socket socket = null;
           
            try
            {
                IPEndPoint hostEndPoint;
                IPAddress hostAddress = null;
                int hostPort = 80;

                IPHostEntry hostInfo = Dns.GetHostEntry(server);
                IPAddress[] ipAddresses = hostInfo.AddressList;

                for (int index = 0; index < ipAddresses.Length; index++)
                {
                    hostAddress = ipAddresses[index];
                    hostEndPoint = new IPEndPoint(hostAddress, hostPort);

                    socket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(hostEndPoint);

                    if (!socket.Connected)
                    {
                        socket = null;
                        continue;
                    }
                    else
                    {
                        socket.Send(byteGet, byteGet.Length, 0);
                        break;
                    }
                }

                StringBuilder sb = new StringBuilder(262144); 
                int byteCount = socket.Receive(byteRecv, byteRecv.Length, 0);
                sb.Append(encoding.GetString(byteRecv, 0, byteCount));
               
                while (byteCount > 0)
                {
                    byteCount = socket.Receive(byteRecv, byteRecv.Length, 0);
                    sb.Append(encoding.GetString(byteRecv, 0, byteCount));
                }

                #if(DEBUG)
                    sw.Stop();
                    this.Text += String.Format(" - Load Page: {0} ms, ", sw.ElapsedMilliseconds);
                    sw.Reset();
                    sw.Start();
                #endif   

                string buff = sb.ToString();
                sb.Remove(0, sb.Length);
 
                string fKey = "<div id=\"menuleft\">", lKey = "</div>";
               
                int fKeyPos = buff.IndexOf(fKey, 0);
                int lKeyPos = buff.IndexOf(lKey, fKeyPos);

                string xml = buff.Substring(fKeyPos, lKeyPos + lKey.Length - fKeyPos);

                MemoryStream stream = new MemoryStream(encoding.GetBytes(xml), false);
                stream.Seek(0, SeekOrigin.Begin);

                TextReader reader = new StreamReader(stream, encoding);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(reader);
                XmlNodeList shops = xmlDoc.SelectNodes("/div/ul/li/a");

                foreach (XmlNode shop in shops)
                {
                    sb.AppendFormat("/{0}; {1}\r\n",
                        shop.Attributes[0].Value, shop.Attributes[2].Value);
                }

                this.richTextBox1.Text = sb.ToString();

                #if(DEBUG)
                    sw.Stop();
                    this.Text += String.Format("Formating: {0} ms.", sw.ElapsedMilliseconds);
                #endif
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
            }
            finally
            {
                if (socket != null) socket.Close();
            }
        }


Мониторинг показал следующие результаты (DSL 16000 | 1.7 Mbit/sec):
Загрузка страницы в среднем - 325 ms.
Форматирование данных в среднем - 12 ms.

Вроде неплохо, но имеется еще (будет больше) 111 страниц с описание филиалов а значит
на загрузку их всех в синхронном режиме уйдет примерно 40 сек. Что конечно неприемлемо.
Хорошо сделаем асинхронную загрузку или много-поточный клиент - допустим выиграем еще 40%
и будем иметь около 24 сек. Тоже жопа.

(Все это конечно относительно т.к. зависит от многих факторов)

Вопрос 1: Как-бы увеличить производительность ?
Вопрос 2: Как-бы Вы, будь вы администратором сайта отреагировали на большое число запросов с одного ип ?
Вопрос 3: Как-бы Вы, будь вы администратором сайта отреагировали на наглую кражу вашего контента ?
Вопрос 4: Как-бы разубедить заказчика от этой идеи и не потерять бабки ?

Буду очень благодарен за дельные советы!
У вас нет доступа для просмотра вложений в этом сообщении.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Windows Клиент - данные с веб страницы

Сообщение MIT » 01.02.2010 (Пн) 22:34

SOAP (ASMX). Сюда же можно приделать авторизацию.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 01.02.2010 (Пн) 22:43

MIT писал(а):SOAP (ASMX). Сюда же можно приделать авторизацию.

Можно по подробнее - как это будет сочетаться с толстым клиентом :?:

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Windows Клиент - данные с веб страницы

Сообщение MIT » 01.02.2010 (Пн) 23:34

Толстый клиент?.. Это заказчик с пузом, или что?

Делаем сервис, через него передаем DataSet со всеми данными. Можно упихнуть всё в один запрос (хотя это и не лучший выход — размер может не маленький получиться, но можно будет организовать Данные->BinaryFormatter->MemoryStream->ZipCompression->Base64->посылаем клиенту — здорово экономим на размере ответа сервера). Это по поводу экономии времени.

По поводу запросов - он всего один будет (ну или значительно меньше чем изначально)
Кража? Если уже украдено, то подадим материал в отдел К (если украдено что-то серьезное), если еще не украдено — сделаем авторизацию на том же сервере.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 0:16

MIT писал(а):Толстый клиент?.. Это заказчик с пузом, или что?

+1 :lol:

Не, так обычно говорят по отношению к приложению, например по отношению к браузеру можно сказать - IE - тонкий клиент :)

MIT писал(а):Делаем сервис, через него передаем...

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

Но ход мысли положительный, кстати возможно в скором времени - как раз в этом направлении предстоит разработка крупного проекта, так что если интересно, напишу в личку - все пока тока в зародыше (проблемы с финансирование, но может получиться).

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Windows Клиент - данные с веб страницы

Сообщение MIT » 02.02.2010 (Вт) 1:11

Ага, значит сервер не твой...
Можно попрость сервер сжимать файлы перед отправкой (gzip,deflate) и надеятся на то, что сервер это сделает. Ну и потом распаковывать. Профит очевиден — неплохая экономия на трафике, а следовательно и на времени.
И плюс в несколько потоков. Можно даже через прокси, а то некоторые серверы могут принять тебя за DDoS`ера и забанить на несколько секунд (минут/часов/вечностей).

Или сделать web-приложение, которое сделает тоже самое что и ты, но на сервере в интернете, а ты уже скачаешь готовую информацию.

Вариантов, в общем-то, не разгуляться.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 1:38

И как понять что - применяется сжатие :?:
Request.GET писал(а):"Accept-Encoding: gzip,deflate"

Server.Response писал(а):HTTP/1.1 200 OK
Date: Mon, 01 Feb 2010 22:34:39 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8k PHP/5.2.12
X-Powered-By: PHP/5.2.12
Set-Cookie: fe_typo_user=c61bd04eb072b5a21cfc56f78a3a3d84; path=/
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Windows Клиент - данные с веб страницы

Сообщение MIT » 02.02.2010 (Вт) 1:47

Тута написано. Коротко — заголовок Content-Encoding при ответе. Если такой заголовок не указан, значит переданныая информация не сжата.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Windows Клиент - данные с веб страницы

Сообщение iGrok » 02.02.2010 (Вт) 1:54

1)
А с какой стати, собственно, полминуты на обработку сотни веб-страниц - неприемлемо?
Производительность ты толком не улучшишь. У тебя основные тормоза - загрузка страниц.
Можно "поработать" с http, задействовав кэширование, и параметризированные запросы (If Modified Since).

2) Забанил бы нафиг. Собственно, на любом из моих серверов ты на третьей же странице улетел бы в бан по IP на пару часов. Такая вот своеобразная анти-ддос защита.

3) Адекватным ядерным возмездием. ©нипомню =)
В зависимости от ценности контента. Крадут сейчас все и у всех. Возмездие применяют только некоторые.

4) А, собственно, нафига ему это?
label:
cli
jmp label

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 2:00

MIT писал(а):Если такой заголовок не указан, значит переданныая информация не сжата.

Понятно.
MIT писал(а):И плюс в несколько потоков.

Как по твоему - если я буду по 50 сокетов открывать - какой прирост производительности можно ожидать :?:
прокси и веб приложение - точно отпадают.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Windows Клиент - данные с веб страницы

Сообщение MIT » 02.02.2010 (Вт) 2:03

Dmitriy2003 писал(а):Как по твоему - если я буду по 50 сокетов открывать - какой прирост производительности можно ожидать?
Ну я не гадалка, но пятидесятикратного увеличения ты не добьёшся точно. Раза в два, может в три или пять — тут эксперимент нужен, я не знаю. Зависит от сервера, от канала связи, от времени обработки результатов по одному запросу.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 2:05

iGrok писал(а):Забанил бы нафиг. Собственно, на любом из моих серверов ты на третьей же странице улетел бы в бан по IP на пару часов. Такая вот своеобразная анти-ддос защита.

Я думаю об этом постоянно, как обойти эту проблему.
iGrok писал(а):А, собственно, нафига ему это?

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

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 2:08

MIT писал(а):тут эксперимент нужен,

Да-уж, на днях проверю - если раньше не забанят :)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Windows Клиент - данные с веб страницы

Сообщение iGrok » 02.02.2010 (Вт) 2:56

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

Если таких сайтов тонны, и всё это делается для создания базы, то почему так критично время обработки?
Почему нельзя запустить обработку сайта на полчаса, и идти пить чай, а потом спокойно работать с созданной и сохранённой базой?
А при обновлении, пользоваться тем самым If-Modified-Since(если прокатит на конкретном сайте, может и не прокатить), и грузить только часть информации?
label:
cli
jmp label

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 3:35

iGrok писал(а):Если таких сайтов тонны, и всё это делается для создания базы, то почему так критично время обработки?

Данные конечно будут храниться в бд. Однако GUI - предусматривает - интерактивный обмен данными пользователя с приложением - представим ситуацию, менеджер по маркетингу - который прекрасно раскручивает клиентов но увы далек от всяких компьютерных штучек - хочет получить информацию о филиалах QUELLE - было около 3000 по Германии (на разных правовых отношениях пока quelle не разорилась) так вот, как-же быть в этой ситуации - представить ему устаревшие данные из бд и потихоньку в фоне обновлять ? или заставить ждать завершения обновления ?

Я конечно же за создание "бот-нета" - к тому-же имеется высоко производительная система на базе одного из университетов германии, где можно было-бы разместить сервис собирающий информацию и предоставляющий ее нам по запросу в "хорошем" формате (тот-же asmx и SOAP) - но это будет стоить много больше - поэтому в настоящий момент было-бы адекватнее доказать что запрошенная клиентом модель совсем не эффективна, это позволило-бы переопределить стратеги и пересмотреть финансирование ... :)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Windows Клиент - данные с веб страницы

Сообщение iGrok » 02.02.2010 (Вт) 3:54

Ммм..
Как быть:
1) Учитывая скорость обновления подобных данных (не каждый день создаются и исчезают филиалы), можно сделать плановое обновление раз в (день/неделю/и т.п.), при выводе предлагать менеджеру выбор - актуальные данные и ждать, или не особо актуальные, но прямо сейчас, а при обновлении какой-либо из просматриваемых в данный момент записей - оповещать.

2) Довести эту информацию (о приблизительном времени обновления) до заказчика. Если не понимает.. Ну что ж тут..
label:
cli
jmp label

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 02.02.2010 (Вт) 4:07

iGrok писал(а):1) Учитывая скорость обновления подобных данных (не каждый день создаются и исчезают филиалы), можно сделать плановое обновление раз в (день/неделю/и т.п.), при выводе предлагать менеджеру выбор - актуальные данные и ждать, или не особо актуальные, но прямо сейчас, а при обновлении какой-либо из просматриваемых в данный момент записей - оповещать.

Такая стратегия, применительно к задаче - мне кажется вполне разумной :)
iGrok писал(а):2) Довести эту информацию (о приблизительном времени обновления) до заказчика. Если не понимает.. Ну что ж тут..

Иногда - это действительно просто невозможно...

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 03.02.2010 (Ср) 4:02

Ну вот провел тест - потребовалось - 10901 мс - при 50 открытых сокетах в пуле потоков на моей полосе пропускания что-бы обработать 111 страниц, так что - можно сказать в некоторых ситуациях не так уж и плохо. :)
Dmitriy2003 писал(а):Хорошо сделаем асинхронную загрузку или много-поточный клиент - допустим выиграем еще 40%
и будем иметь около 24 сек. Тоже жопа.

так что это мое изречение отправляется на свалку :drunken:

NET Coder
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 06.02.2008 (Ср) 0:18

Re: Windows Клиент - данные с веб страницы

Сообщение NET Coder » 05.02.2010 (Пт) 17:14

HttpWebRequest и HttpWebResponce из System.Web
Если слегка погуглить - тоже много дельного всплывёт.... :D

Удачи.

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Re: Windows Клиент - данные с веб страницы

Сообщение Dmitriy2003 » 06.02.2010 (Сб) 9:43

NET Coder писал(а):Удачи.

Оо, она мне непременно понадомиться если искать
NET Coder писал(а):HttpWebRequest и HttpWebResponce
тут
NET Coder писал(а):из System.Web

Спасибо Уважаемый :)

NET Coder
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 06.02.2008 (Ср) 0:18

Re: Windows Клиент - данные с веб страницы

Сообщение NET Coder » 07.02.2010 (Вс) 14:27

Упс! System.Net - вот так правильней.

Как заюзать - смотрите тут .
Вторая врезка на первой странице. :D
Потом при желании можно анализировать ответ Сервера. В том числе и с помощью регулярных выражений.
Можно будет дальше подумать. :D


Вернуться в C#

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

    TopList  
cron