Рейтинг блогосферы - пост 4 (про ссылки)

Примечательно, что с каким бы программистом я не начинал обсуждать алгоритм составления ТОПа, в итоге каждый говорил, что вот он сейчас пойдет создаст сайт, выложит там новый ТОП и станет популярным. Это с одной стороны хорошо, так как показывает, что программисты - люди дела и любители играть в разные алгоритмы, а также мечтают стать знаменитыми. Но с другой стороны показывает, что они не понимают
1) Как работать в команде,
2) Что так как все работают с одним векторным пространством и одинаковыми сырыми данными, то в итоге рейтинг у всех будет совпадать в значительной степени.(~20%)
3) Самая сложность не в первоначальной сортировке, а в последующих фильтрах, которые должны отсеять спамерские посты. А спамерские посты чаще всего имеют ссылки как входящие, на сам пост, так и исходящие - на рекламу - которые нужно уметь определять и фильтровать. Вот об этом алгоритме работы нового ТОПа и поговорим.

После 4х летнего изучения топов я с полной уверенностью могу сказать, что нет смысла составлять списки бана, то есть лишать определенныз определенных блогеров шанса попасть в ТОП. Ибо это равносильно тому, чтобы посадить своего модератора, так как спамер может создавать новые блоги каждый день. В связи с этим логичным видится
1) фильтр по ссылкам, которые содержаться в посте - то есть все ссылки должны проходить проверку через сервис opendns, чтобы исключить ссылки на фишинговые сайты в топе или на сайты с вирусами. Минус - медленная работа по отбору записей, поэтому я пока ограничился самосоставленным списком с плохими ресурсами. И если в после есть ссылка на плохой ресурс, то пост не попадет в топ. Также я расматриваю вариант, когда на наличие плохих ссылок будет анализироваться вся главная страница блога и страница профиля, так как вероятно их откроет человек захотевший узнать побольше об авторе ТОПа и этим тоже пользуются спамеры.
2) ссылки на популярные сервисы сокращения ссылок (bit.ly) можно пока не фильтровать, так как эти сервисы сами заинтересованы в фильтрации ссылок на фишинговые и вирусные сайты.
3) Ранее я упомянул фильтр на локальный экстримум - он заключается в том, что проверяется, что за локальный период времени ссылок именно на этот пост блогера было больше всего или комментариев было больше всего. Это прежде всего позволяет отфильтровать тех у кого есть трансляции и у кого стабильно по несколько ссылок между своими трансляциями. Также отфильтрует тех, у кого стабильно много комментариев, например из-за спама в комментариях.
4) Анализируя спамерскую активность я пришел к выводу в необходимости фильтра "LinksIntegrity" - задача которого проверить все ссылки на расматриваемый пост, отбросить одинаковые, отбросить те, которые сделаны из сообществ и отбросить все ссылки с микроблогов. Повышенная активность в микроблогах и то, что там почти каждый пост содержит ссылки - говорит о том, что нельзя микроблоги причислять к полноценным блогам. Кроме того в микроблогах сейчас каждый упоминание типа "@user" - считается ссылкой и это сильно перекосило рейтинг блогеров и вызывает недоумение в определенных кругах. Итак, после отбора ссылок, проверяется, что оставшееся число ссылок достаточно для того, чтобы интегральная характеристика поста оставалась среди 20% постов с наибольшим значением.


Метки:   Категории:Blogs | Analytics | topbot | Code


Go Code

Свежая наклейка на ноуте с надписью "Go Code" заставила меня поразмышлять о новом языке программирования, который предлагает Google. Во-первых, уже полно языков программирования и трудно придумать что-то, чтобы всех заставило разом перейти на него. Во-вторых, пошла шутка, что "В ответ Yahoo запустил язык программирования YO! А мы теперь ждем языка YA!". Но если подумать, то можно вспомнить, что сейчас идет бета тестирование GoogleWave, которое в следующем году станет доступно всем, а также появится маркет, на подобии AppStore, где девелоперы смогут продавать, написанные ими снипеты для GoogleWave. Это программы, с помощью которых пользователи смогут взаимодействовать друг с другом, например, игры в социальных сетях. Но если мы возьмем OpenSocial платформу, то даже в ней для создания какой-то простой игры потребуется дополнительно изучать форматы сообщений, представления данных, почти как изучить новый язык. Не исключено, что Гугл захочет заставить прогеров писать снипеты, а также федеративные сервера, для GoogleWave на собственном языке.

Метки:   Категории:Google | Code


Ретинг блогосферы - пост 3

Провел небольшой эксперимент, имея на руках 4 параметра (visits24, links, comments, commenters), базу из 1000 постов за 3 дня, а также историю ТОПа с 40 постами за сутки, а попытался методом перебора коэффициентов найти наиболее подходящий вектор, на который делается проекция, как было описано в первом посте, чтобы после сортировки всех записей по величине этой проекции, в первых 100 оказывалось максимальное число постов, которые попали в топ, построенный по старому алгоритму. Результатом стал вектор (10,9,12,12) с результатом в 25 постов из 40. Это прежде всего говорит о том, что в текущем алгоритме есть явная завышенная зависимость от числа различных русскоязычных комментаторов к посту (commenters). Я же для сортировки записей беру вектор с равными весами = (1,1,1,1). Кроме того, стоит отметить два выявленных особенностей 1) В блогах на YaRu - внутренняя ссылка является также комментарием, поэтому важно уменьшать кисло комментариев на число ссылок. Иначе получается завышенное число ярушных блогов с высокими значениями. 2) Нормировка происходит не только в группах по типу блогплатформы, но и по типу блога или сообщества. То есть для блогов и сообществ максимумы значений считаются отдельно. После того, как записи в текущей куче постов за 3 дня отсортированы применяются фильтры. Их много, я их кратко перечислю по ходу применения: Далее...


Метки:   Категории:Code


Рейтинг блогосферы - пост 2

Сегодня я вернусь к вопросу правильности выбора параметров, от которых строится функция F(comms,visits,commenters,links) - входящая в композицию веса поста.
Первый вопрос, почему я отбросил другие параметры, кроме перечисленных четырех, такие как "число комментариев/ссылок/комментаторов за последние 24 часа", а также "вес ссылок - linksweight". Ответ: Я достаточно долго работал с данными, собираемыми распределенной системой по всему миру и убедился, что такой параметр как время становится более чем относительной характеристикой. В этот параметр вкладывается и задержка поступления данных с разного индексирующего кластера, и месторасположение блогплатформы, у которой серверное время может выдаваться со сдвигом и прочее и прочее. Однако, стоит заметить, что параметр linksweight в алгоритме учитывается. Так как в старом алгоритме придавалась большая значимость количеству ссылок, которые делаются на запись, и кроме того есть механизмы обнаружения спамерских ссылок, то в новом алгоритме я оставляю требование на наличии хотя бы одной неспамерской по версии Яндекса ссылки.

Второй вопрос, почему четыре параметра входят в функцию с одинаковыми весами. Ответ: При построении интегрального коэффициента глупо было бы отдавать предпочтение одному из параметров. Записи должны отсеиваться на основании тех параметров, которые определяют текущее состояние экспертной системы, а следовательно базируются на выборке из всех записей блогосферы, а не одной конкретной, о которой накрутчикам известно все и они могут подкрутить любой из параметров. С такой точки зрения, все четыре параметра равноценны, однако, у меня есть большое недоверие к параметру посещений, так как он весьма условный и вероятно считается некорректно. Но это не так важно, так как наш интегральный параметр задает лишь критерии сортировки записей перед выборкой и не является определяющим при помещении записи в ТОП.

В заключение отмечу, что в единицу времени в ТОП помещается только одна запись, так как эта операция меняет основные параметры экспертной системы и следовательно дискретна. За день в ТОП может попасть не более 70 записей. Если этого будет много, то я уменьшу этот параметр.

В следующий раз я затрону тему фильтров 1)по темам дня 2) отсеивание ссылок на плохие сайты 3) отсеивание дублей методов сравнения слов-низкочастотников в постах находящихся в ТОПе. А пока, результат работы нового алгоритма формирование рейтинга популярных тем блогосферы публикуется на сайте beta.topbot.ru. Присылайте вопросы на topbot@ya.ru.


Метки:   Категории:Yandex | Code


Url Shorteners API

Добавил в библиотеку BlogsAPI(только в исходники, не в релиз) класс для работы с Bit.ly API. По умолчанию использует мой девелоперский ключ, но можно в конструкторе задать и свой. Позволяет получить сокращенную ссылку по длинной следующим кодом. Также есть возможность извлечения числа переходов по ссылке:

Copy Source | Copy HTML
  1. [TestFixture]
  2. public class Shorteners
  3. {
  4.     [Test]
  5.     public void Bitly()
  6.     {
  7.         BitLy shortener = new BitLy();
  8.         String sRet = shortener.ConvertDataTo("http://s-c.me", ItemType.FullUrl, ItemType.ShortUrl);
  9.         Assert.AreEqual(false,String.IsNullOrEmpty(sRet));
  10.     }
  11. }

Метки:   Категории:Twitter | Code


Capitalize first symbol of each word

Интересную фишку обнаружил в .Net, оказывается, чтобы в тексте сделать каждый символ заглавным, не нужно придумывать никаких сложных регулярных выражений, как это предлагалось на хабре для программистов Java. Достаточно воспользоваться услужливо написанной для насв Микрософте функцией:
Copy Source | Copy HTML
  1. using System.Globalization;
  2.  
  3. string capitalized = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("asp.net simply rocks!!!");
  4. //yelds "Asp.Net Simply Rocks!!!" 

Метки:   Категории:Code


BlogsAPI published-FOAF-parser

После некоторых раздумий выложил исходники BlogsAPI в опен сорс. Мне не жалко, если кто будет их использовать для своих проектов, ведь главное, что они будут написаны на .Net. Большую часть Юнит-тестов я исключил из проекта, чтобы не палить пароли от реальных аккаунтов. Отдельно обращаю внимание на то, как с помощью библиотеки парсить FOAF файлы:Далее...

Метки:   Категории:Blogs | Twitter | Yandex | Code


Regex for String

На днях была обнаружена ошибка при подсветке строковых констант на сайте Source Code for Me. Проблема была когда в коде встречалось экранирование обратного слэша перед закрывающей кавычкой - (\\"). Всвязи с этим я доработал регулярное выражение по извлечению строковых констант. Надеюсь оно кому-нить пригодится. Выражение выглядит следующим образом:
Copy Source | Copy HTML
  1. Regex rString = new Regex(@"@?""""|@?"".*?((?!\\).|(?:\\\\)+)""|''|'.*?(?!\\).'|\b\d+?(?=\b|$)%?|‘’|‘.*?(?!\\).’");

Метки:   Категории:S-c.me | Code


Open or Close project's code

Все наслышаны про open source проекты, но наверно никто из Вас не принимает участие в их написании. Некоторое могут негативно относится к таким проектам, а некоторые боготворят, думая, что только так создается настоящий продукт. Но факты есть факты, что даже в разработке открытого Linux вклад в разработку от "случайных разработчиков" не превышает 30%. Остальное было сделано корпоративной разработкой под нужды клиентов.
Если пойти далее, то можно найти описание того, из чего состоит вклад "случайных" разработчиков в open source проект и мы увидим, что они даже програмный код не пишут. И итоге я прихожу к выводу, что выкладывать исходники продукта - полезно, а вот принимать сторонние изменения или тратить время на разбор сторонних предложений по изменению кода - бесполезно.
Так что же из себя представляют эти 30%:
1) Обратная связь с пользователями - программист, открывший open source проект, представляет из себя опытного пользователя, который, в отличии от простого пользователя, с охотой сообщает разработчикам о проблемах в работе программы или своих пожеланиях на будущие версии продукта.
2) Помощь другим - пользователь, поставивший open source проект понимает, что поддержку ему никто не гарантирует, поэтому за помощью обращается к более опытным знакомым и сам более активно помогает другим, бесплатно консультируя о работе продукта.
3) Написание документации - часто "помощь другим" выражается в написании документации или редактировании документации, созданной основными разработчиками продукта.
4) Пожертвования денег - тут все ясно. 5) Прочее - организация фан сайтов, юзер групп, форумов и т.д., тоже является неотъемлемой частью конечного продукта.

Метки:   Категории:Code | life


.Net: Max connections

Максимальное число допустимых открытых соединений с клиентов - весьма важная настройка при создании веб-сервисов в .Net, о которой обычно все забывают. Причиной такой забывчивости является то, что по умолчанию разрешено 2 соединения с любого клиента и этого вполне достаточно для работы веб-сайта в сети Интернет, где куча пользователей с разных хостов по очереди обращаются к одному серверу. Но когда речь идет о взаимодействии двух серверов активно передающих между собой запросы, то полезно выставить число одновременно открытых соединений на побольше. Делается это следующими строчками в конфиге:
Copy Source | Copy HTML
  1. <configuration>
  2.   <system.net>
  3.     <connectionManagement>
  4.       <add address = "http://www.com" maxconnection = "4" />
  5.       <add address = "*" maxconnection = "10" />
  6.     </connectionManagement>
  7.   </system.net>
  8. </configuration>
  9.  

Метки:   Категории:bugs | Code


ТОПБЛОГЕРы РУнета

После некоторого гемора выложил новый сайт для тестирования, а точнее даже два: topbloger.ru и смежный ему top4blog.ru. Первый содержит информацию обо всех топовых блогерах, а второй просто набор постов, попавших в топ. Зато теперь информацию искать удобнее и выглядит красивее чем на моем же deep-water.ru. Для полной красоты не хватает возможности автоматически извлекать ссылку на кэшированную копию поста в Яндексе. Из приятных возможностей - RSS подписка на топовые записи определенного блогера, а также то, что можно давать ссылки на "карточки топблогеров" как со знаком вопроса, так и без, что упрошает запоминание адреса.

Монетизация проекта возможна через размещение платных ссылок на рекламные агенства или добавление(убирание) информации о платных постах блогера.

Метки:   Категории:Blogs | topbot | Code


Tag Cloud for ASP.NET by jQuery

Ниже я раскажу как написать простенький компонент для отображения облака тэгов в ASP.NET. Пост содержит много кода. Для начала нам потребуется jQuery, который нужно где-нить подключиться на странице. Если Вы не знаете, что такое jQuery - то в поиск. Далее на странице, где у нас будет облако тэгов, а их может быть несколько, подключаем CSS и JS: Далее...

Метки:   Категории:BlogEngine | Code


Twitter API

Все знают, что у твиттера есть API для разработчиков, но мало кто реально им пользуется. Обычно все находят программы уже созданные кем-то на западе. Если же у вас необходимость создать какое-то приложение для твиттера на .Net, то рекомендую достаточно молодой опен-сорс проект Twitterizer. Ниже много кода, демонстрирующие как просто я добавил возможности твиттера в библиотеку BlogsAPI (закрытый проект пока): Далее...

Метки:   Категории:Blogs | Twitter | Code


How to RSS your data

Что такое RSS большинство должно знать - это форма экспорта текстовых данных с сайта. Лично меня в RSS не устраивает то, что нельзя задать идентификатор сообщения уникальный для моего поста в рамках сегодняшнего дня, а не в рамках ресурса, за что отвечает поле guid. Это нужно для того, чтобы RSS агрегатор, типа reader.google.com, мог понять, что эти 3 новости перекопированные на разные сайты - есть одно и тоже. Например новости Яндекса копируются на хабр и на яру, а у меня из-за этого в 3 раза больше сообщений. Введение такого хэш-идентификатора "на день" вполне оправдано. И согласуется с тем, как работают сервисы сокращения ссылок, замещая старые короткие ссылки, новыми значениями, что позволяет короткой ссылке оставаться короткой.

Другая интересная несогласованность проявляется при попытке создания RSS выдачи при помощи сериализации объекта класса (рекомендую библиотеку RssToolKit 2.0 для этого). Как мы знаем все строки в CSharp храняться в виде UTF-16, поэтому при сериализации мы получаем XML в этой кодировке, жестко указанной в заголовке. Но, как оказалось, некоторые браузеры - FireFox, IE8 (в Opera все впорядке) - наотрез отказываются воспринимать такой XML, требуя UTF-8 и жесткого задания версии RSS, поэтому пришлось дописать RssToolKit, добавив преобразование кодировок следующим образом:
Copy Source | Copy HTML
  1. /// <summary>
  2. /// Returns XML of the Generic Type.
  3. /// </summary>
  4. /// <param name="rssDocument">The RSS document.</param>
  5. /// <typeparam name="T">RssDocumentBase</typeparam>
  6. /// <returns>string</returns>
  7. public static string ToRssXml<T>(T rssDocument) where T : RssDocumentBase
  8. {
  9.     if (rssDocument == null)
  10.     {
  11.         throw new ArgumentNullException("rssDocument");
  12.     }
  13.  
  14.     MemoryStream memoryStream = new MemoryStream();
  15.     String XmlizedString = null;
  16.     using (XmlTextWriter output = new XmlTextWriter(memoryStream, Encoding.UTF8))
  17.     {
  18.  
  19.         XmlSerializer serializer = new XmlSerializer(typeof(T));
  20.         serializer.Serialize(output, rssDocument);
  21.         memoryStream = (MemoryStream)output.BaseStream;
  22.         XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
  23.         return XmlizedString;
  24.     }
  25. }
  26.  
  27. /// <summary>
  28. /// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
  29. /// </summary>
  30. /// <param name="characters">Unicode Byte Array to be converted to String</param>
  31. /// <returns>String converted from Unicode Byte Array</returns>
  32. private static String UTF8ByteArrayToString(Byte[] characters)
  33. {
  34.     UTF8Encoding encoding = new UTF8Encoding();
  35.     String constructedString = encoding.GetString(characters);
  36.     return (constructedString);
  37. }
После этого создание RSS asp-сайта занимает несколько строчек:
Copy Source | Copy HTML
  1. //говорим, что ответом есть XML/RSS
  2. Response.ContentType = "application/rss+xml";
  3. //вытаскиваем из ьазы данные
  4. using (MySQL db = new MySQL())
  5. {
  6.     DataSet ds = db.GetData("get_rss");
  7.     if (ds != null && ds.Tables[0].Rows.Count > 0)
  8.     {
  9.         RssDocument rss = new RssDocument()
  10.         {
  11.             Version = "2.0",
  12.             Channel = new RssChannel()
  13.             {
  14.                 LastBuildDate = DateTime.Now.ToString(),
  15.                 Language = "ru-RU",
  16.                 WebMaster = "topbot@ya.ru",
  17.             }
  18.         };
  19.         rss.Channel.Title = "blabla"
  20.         rss.Channel.Link = ds.Tables[0].Rows[0]["linkto"].ToString();
  21.         rss.Channel.Items = new List<RssItem>(0);
  22.         foreach (DataRow dr in ds.Tables[0].Rows)
  23.         {
  24.             RssItem ritem = new RssItem()
  25.             {
  26.                 PubDate = ((DateTime)dr["when"]).ToString("s"),
  27.                 Description = dr["text"].ToString()
  28.             };
  29.             rss.Channel.Items.Add(ritem);
  30.         }
  31.         Response.Write(rss.ToXml(DocumentType.Rss));
  32.     }
  33.     else
  34.     {
  35.         Response.ContentType = "application/rss+xml";
  36.     }
  37.  
  38. }

Метки:   Категории:Csharp | Code


web vs desktop developing

На хабре недавно проскакивал вопрос - есть ли отличие между Web разработкой и desktop разработкой? Немало людей, если не большинство, ошибочно ответило, что разницы нет. Это не удивительно, с учетом того, что весь девелоперский инструментарий и компании заинтересованы в универсальном программисте, решающем любые задачи. Однако, я, как вовлеченный и в ту и в другую деятельность перечислю ниже основные отличия между web и desktop разработками:Далее...

Метки:   Категории:Analytics | Code


Multi-thread testing for web-service

В работе постоянно приходится тестировать с помощью NUnit различные web-службы. Но я делаю не банальный одиночный вызов или серию последовательных вызовов, а создаю серию потоков вплоть до максимально разрешенного на текущей машине, каждый из которых по команде начинает делать запрос в web-службу. В случае, если на сервере IIS разрешено более одного процесса, для обслуживания ApplicationPool, то это может выявить неожиданные блокировки ресурсов, которые нужно уметь отлавливать. Эмитация такого многопоточного обращения к одному сервису сделана как показано ниже: Далее...

Метки:   Категории:S-c.me | Code


BlogEngine - MultiPost v0.1.4

Обновил расширение для BlogEngine позволяющее постить одновременно сразу в несколько блогомест. Качать архив файлов тут. Архив содержит 3 вещи, которые нужно поместить в корень вашего блога заменив старое - 1) папку admin с измененным файлом Settings, я там исправил ошибку с редактированием настроек 2) папку App_Code - в ней содержится код расширения, который вы сможете поправить, если нужно 3) Папку bin, которая содержит библиотеку BlogsAPI, в которой реализована работа с основными(lj,liru,yaru,blogsmail) блогохостингами. Не забудте внести изменения в web.config, как я писал ранее, а то не будет работать с Яндексом. Сейчас там реализовано копирование постов на Лиру и Яру. Но если есть желание, то можно дописать свой класс для копирования постов куда угодно, который имеет интерфейс IBlogHosting и поместить его в namespace MultiPostExtension.Blogs:Далее...

Метки:   Категории:Blogs | BlogEngine | Code


Волна микроблогов

Месяц Май ознаменовался серией событий по микроблогингу в рунете и вообще. Толчек обсуждению был задан публикациями в журнале f5.ru - печатное издание обо всем в блогосфере. Скачать и почитать их в онлайне тут. (Статейки хорошие, молодцы, даже ссылку на меня печатают. Денег правда на раскрутку тратят некисло, сразу видно, что "двухбуквенник"). В журнале перечислены все сервисы по микроблогингу, которые бы могли заинтересовать рускоговорящих пользователей.

Однако, списоу из 8ми сервисов оказался не полным и буквально на днях мы узнали о проекте ljchat.ru и обновленный ЖЖ-мессенжер от Микрософта ljtalk. Последний еще не доступен для всех, но то, что мелкомяйкие решили приложить руку к ЖЖ - уже странно.

Примечательно, что у микроблогинга нет монетизации, а на горизонте уже маячит, объявленный GoogleWave, который должен стать объединением всего лучшего от F*Connect+Jabber+HTML5 - и должен убить микроблогинг.

Чтобы закрыть эту тему приведу код, который я использую в проекте подсветки кода, для формирования коротких ссылок и дальнейшей вставки в микроблоги. Для сжатия я выбрал 64х базу, дополнив строчный и прописной английский алвафит двумя знаками "_" и "-". В итоге получаем такие вот короткие ссылки на код - s-c.me/wX.

Метки:   Категории:Blogs | Twitter | Code


Все важное за месяц в сфере ASP.NET

Постоянно выходят обновления ключевых компонент, о которых стоит знать каждому web-разработчику ASP.NET.
Апрель-май запомнится выходом следующих обновлений:
  • BlogEngine 1.5 - новая версия блогового движка, но котором и сделан мой блог. Выход готовился полгода и очень много изменений. Движок сам по себе содерщит много фишек, которыми вы даже пользоваться не будете, такие как SiteMap, PingBack и т.д., но которые очень полезны для хорошей находимости вашего блога в поисковиках и взаимодействия в социальной среде.
  • DotNetOpenAuth 3.0 - библиотека организации распределенной аутентификации, как на базе OpenID, так и на базе oAuth, даже есть liveCards - последнее достижение микрософта, встроенное в Висту. Работа с библиотекой потребует внимательного изучения примеров, благо их много и они хорошо прокомментированы. Уже применил ее в ряде своих проектов.
  • Ajax Control Toolkit - свежее обновление компонент жизненно необходимых для создания простых веб страничек. Потестировать не успел. Радует добавление комбобокса, на подобии десктопной среды. Интересно, появилось ли там удобное средство для задания даты и времени в одном поле.


Более детально остановится на этих продуктах я планировал после внедрения их в свой уютный бложик, только пока никак руки не доходят =(.

Метки:   Категории:microsoft | news | Code


Скриншоты сайтов на .Net

Как оказалось делать скриншоты сайтов не такая уж и простая задача. Но выход из нее можно найти создавая отдельным потоком скрытую форму с объектом WebBrowser и используя некоторые компоненты MS IE7+.
Ниже идет малокомментированный код, который подскажет Вам, как это правильнее всего сделать. Если есть вопросы, то гуглите и разбирайтесь в документации:
Copy Source | Copy HTML
  1. #region private event handlers
  2.  
  3.  
  4.     /// <summary>
  5.     /// События результата открытия страницы в браузере _webBrowser.Navigate(url.OriginalString);
  6.     /// </summary>
  7.     private unsafe void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
  8.     {
  9.         WebBrowser browser = (sender as WebBrowser);
  10.         if (browser != null)
  11.         {
  12.             if(!browser.DocumentText.Contains("<!--Error Body-->"))//если открылось
  13.             {
  14.                 int width = browser.Document.Body.ScrollRectangle.Size.Width;
  15.                 int height = browser.Document.Body.ScrollRectangle.Size.Height;
  16.                 this.Size = browser.Document.Body.ScrollRectangle.Size;
  17.                 this.ClientSize = browser.Document.Body.ScrollRectangle.Size;
  18.  
  19.                 this.Height = 10;
  20.                 this.Width = 20;
  21.                 browser.Width = width;
  22.                 this.Top = -200;
  23.                 browser.Top = -100;
  24.                 browser.Height = 5000;//height;
  25.                 panel.AutoScrollPosition = new Point(300, 300);
  26.                 this.Refresh();
  27.                 //повторный рендеринг страницы тут нужен
  28.                 back.RunWorkerAsync();
  29.             }
  30.         }
  31.     }
  32.  
  33.     void back_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  34.     {
  35.         WebBrowser browser = this._webBrowser;
  36.         if (browser != null)
  37.         {
  38.             if (!browser.DocumentText.Contains("<!--Error Body-->"))
  39.             {
  40.                 int width = browser.Document.Body.ScrollRectangle.Size.Width;
  41.                 int height = browser.Document.Body.ScrollRectangle.Size.Height;
  42.                 //объект из IE7+
  43.                 mshtml.IHTMLDocument2 document = (browser.Document.DomDocument as mshtml.IHTMLDocument2);
  44.  
  45.                 if (document != null)
  46.                 {
  47.                     mshtml.IHTMLElement element = (document.body as mshtml.IHTMLElement);
  48.                     if (element != null)
  49.                     {
  50.                         IHTMLElementRender render = (element as IHTMLElementRender);
  51.                         if (render != null)
  52.                         {
  53.                             Image img = new Bitmap(width, height);
  54.                             using (Graphics graphics = Graphics.FromImage(img))
  55.                             {
  56.                                 IntPtr hdcDestination = graphics.GetHdc();
  57.                                 render.DrawToDC(hdcDestination);
  58.                                 graphics.ReleaseHdc(hdcDestination);
  59.                               //  browser.DrawToBitmap((Bitmap)img, new Rectangle(0, 0, width, height));
  60.                                 string FileName = wheretosave;
  61.                                 _webBrowser.DrawToBitmap((Bitmap)img, new Rectangle(0, 0, width, height));
  62.                                 img.Save(FileName);
  63.                             }
  64.                         }
  65.                     }
  66.                 }
  67.             }
  68.         }
  69.         this.Close();
  70.     }
  71.  
  72.     void back_DoWork(object sender, DoWorkEventArgs e)
  73.     {
  74.         Thread.Sleep(5000);
  75.     }
  76.  
  77.     #endregion

Метки:   Категории:Csharp | Code


Кто я?

Программист. Я слежу за блогосферой и знаю, как будет развиваться интернет. Когда у меня есть время я даже прилагаю для этого усилия. Подробнее

Последние комментарии

Не отображать

Topbot at FeedsBurner

Мои Твиты

Twitter февраля 19, 06:57
Диоксин угрожает планете! http://dlvr.it/QGwPKJ https://twitter.com/f1ashr/status/965480472095555584/photo/1

Twitter февраля 11, 18:36
@typographera @lustforcookies Но Москва на 70 лет моложе и была основана при Кутузове, когда начали железную дорогу прокладывать.

Twitter февраля 11, 17:24
@lustforcookies @typographera А ничего, что Коломна основана от силы 270 лет назад?

Twitter февраля 11, 14:07
Украина готовит на Евровидение песню с быками http://dlvr.it/QFw6Kb

Twitter февраля 9, 14:07
Чем белые отличаются от черных? http://dlvr.it/QFh4j8 https://twitter.com/f1ashr/status/961964675469426690/photo/1

Twitter февраля 6, 09:57
Победа свободы над здравым смыслом http://dlvr.it/QFD2S4 https://twitter.com/f1ashr/status/960814600802377731/photo/1

Twitter февраля 4, 15:32
В Твиттере начался обвал фолловеров http://dlvr.it/QDzJLg

Twitter февраля 3, 08:34
Суммарная капитализация криптовалют http://dlvr.it/QDqJyj

Twitter февраля 2, 10:52
Музыка про прилет Американцев на Марс http://dlvr.it/QDhYq7 https://twitter.com/f1ashr/status/959378893017726977/photo/1

Twitter января 28, 17:04
Разбор трилогии Матрицы (The Matrix Trilogy) http://dlvr.it/QD3h9W https://twitter.com/f1ashr/status/957660569674199040/photo/1

Twitter января 24, 13:20
Google Lunar X Prize - за 10 лет никто не смог запуститься на Луну http://dlvr.it/QCYSRW https://twitter.com/f1ashr/status/956154641753911298/photo/1

Twitter января 24, 04:03
Разбор сериала Туман или 4 всадника Апокалипсиса http://dlvr.it/QCVWXz https://twitter.com/f1ashr/status/956014586666287104/photo/1

Twitter января 23, 19:50
Пасха в Москве 2 сентября 2017 года http://dlvr.it/QCS7cD https://twitter.com/f1ashr/status/955890398899007488/photo/1

Twitter января 23, 19:50
Пользователи умудрились поломать гео-локацию в Инстаграм http://dlvr.it/QCS7hp

Twitter января 23, 16:29
В бюджете Америки появились лишние 2 трлн. долларов http://dlvr.it/QCQpPr

Twitter января 22, 14:45
Добродел обновился http://dlvr.it/QCGHwl https://twitter.com/f1ashr/status/955451259439407105/photo/1

Twitter января 22, 13:32
Рейтинг каналов и ботов Телеграмм http://dlvr.it/QCFt9v https://twitter.com/f1ashr/status/955432885657395200/photo/1

Twitter января 21, 16:15
Битва за Мосул в 360 с вертолета http://dlvr.it/QC84Xk https://twitter.com/f1ashr/status/955111520337248256/photo/1

Twitter января 21, 16:15
3 февраля стартует год огненного Петуха http://dlvr.it/QC84XQ

Twitter января 21, 16:15
Независимая Подмосковия http://dlvr.it/QC84X3

Мой твиттер

Копирайт

Все мысли, высказанные в блоге, являются моим мнением и за это мнение меня никто не забанит! Кроме того, никто не имеет право копировать материалы блога без использования ctrl+C/V!

© Copyright 2008