(см. продолжение Еще раз о чтении динамических WEB-страниц)
Понадобилось мне читать довольно быстро (несколько раз в минуту) меняющиеся данные на одной из динамических WEB - страниц, чтобы набрать некоторую статистику. В интернете обнаружилось довольно много материала на эту тему (см. ссылки), а в типовых конфигурациях - примеров успешной реализации подобных задач. Например, это касалось отслеживания курса валют на сайте Центрального Банка Российской Федерации. В типовых конфигурациях для этого использовалась внешняя компонента v7plus.dll, ее объект AddIn.V7HttpReader и методы ПолучитьКакСтроку(Адрес, Стр) и ПолучитьКакФайл(Адрес, Файл).
Раньше мне не приходилось решать таких задач, поэтому я решил пойти проторенной дорожкой и использовать эти опробованные практикой "родные" для 1С средства. Однако первый же опыт применения ПолучитьКакСтроку(Адрес, Стр) дал отрицательный результат: динамическая WEB-страница читалась очень быстро (за секунды), но, к моему сожалению, урезалась до 1 - 2 кб (по разному для разных страниц и методов). Попробовал ПолучитьКакФайл(Адрес, Файл) - та же история. Поняв, что с налету мне эту задачу не осилить, решил заняться более капитально. Сделал небольшую обработку ЧтениеWEBстраницы.ert , в которой протестировал несколько вариантов решения задачи, упоминавшихся в интернете в статьях и на форумах. (см. скриншот обработки)
В качестве динамической WEB-страницы я использовал страницу файлового архива моего сайта http://www.almazsoft.ru/ (информация о скачиваниях файлов на ней меняется). При работе с этой обработкой Вы также можете использовать этот адрес http://www.almazsoft.ru/index.php?option=com_remository&Itemid=34&func=select&id=5, или ввести адрес любой другой известной Вам динамической WEB-страницы.
- Вариант 3. V7HttpReader: Получить(Адрес,Результат, 1) - в файл и вариант 4. V7HttpReader: Получить(Адрес,Стр, 2) - в строку дали те же результаты, что и упомянутые выше варианты 1. V7HttpReader: ПолучитьКакСтроку(Адрес, Стр) и 2. V7HttpReader: ПолучитьКакФайл(Адрес, Результат). Их реализация не отняла много времени, по сути они делают одно и то же.
- А вот с вариантом 5. V7HttpReader: Получить(Адрес,Стрим, 3) - в ADODB.Stream пришлось повозиться. В интернете материалов по этой связке (1С + v7plus.dll + V7HttpReader: Получить(Адрес,Стрим, 3) + ADODB.Stream) мне найти не удалось, пришлось искать в статьях похожие связки и пытаться их править под свою задачу. Однако, когда вариант удалось реализовать, он дал те же результаты, что и предыдущие 4 варианта: отличную скорость чтения и урезание содержимого страницы.
- Вариант 6. ФС.КопироватьФайл(Адрес,Результат) пришлось добавить, потому, что в одном из форумов (http://www.itland.ru/forum/lofiversion/index.php/t21318.html) было высказано такое утверждение: "И еще проще:
КопироватьФайл("http://img.yandex.net/i/yandex-v9.gif","C:\temp.gif")". Пришлось его проверить. Как я понял, речь шла об ФС.КопироватьФайл. Так вот, команда ФС.КопироватьФайл(Адрес,ФайлКопии) отрабатывает моментально и без ошибок, но ФайлКопии даже не создается. Что и ожидалось. Уж слишком просто. - Вариант 7. WinHttp.WinHttpRequest.5.1 вначале исследовался как 7. MSScriptControl + WinHttp + ADODB.Stream. Он был сделан на основе статьи http://www.itland.ru/forum/lofiversion/index.php/t21318.html путем небольшой модификации предложенного в ней кода. Вариант отрабатывал без ошибок, но в файл результата попадало только первые 3 символа текста динамической WEB-страницы. Дальнейшее изучение возможностей WinHttpRequest (см. http://msdn.microsoft.com/en-us/library/aa384106%28VS.85%29.aspx) и примера его использования в Visual Basic 6 (см. Retrieving Data Using Visual Basic) показало, что объекты MSScriptControl и ADODB.Stream в этом коде вообще не нужны!. После их удаления и небольшой правки получился простой и понятный работающий код, полностью считывающий содержимое динамической WEB-страницы. Правда, скорость чтения примерно в 3 раза медленнее, чем в первых 5 вариантах.
- Вариант 8. InternetExplorer.Application был реализован без проблем. Правда, работает он в 3-4 раза медленнее варианта 7. Но благодаря наличию у COM-объекта InternetExplorer.Application свойства document и метода getElementsByTagName(TagName) в этом варианте с динамической WEB-страницы может читаться не все содержимое, а только содержимое указанных тэгов. Это может значительно облегчить последующий парсинг содержимого. Поскольку разбор прочитанного содержимого динамической WEB-страницы выходит за рамки этой статьи, то не будем на нем останавливаться. По моему мнению (его надо проверить опытным путем), выгоды предварительного парсинга не компенсируют медленную скорость чтения. Парсинг - не такая уж сложная задача и не требует много времени.
Выводы
- По результатам вариантов 1-5 можно высказать утверждение, что внешняя компонента v7plus.dll и ее объект AddIn.V7HttpReader не годятся для чтения динамических WEB-страниц.
- Для чтения часто меняющихся данных динамических WEB - страниц наиболее подходит вариант 7. WinHttp.WinHttpRequest.5.1.
На этом я собирался прекратить опыты и довольствоваться полученными результатами. Но, как оказалось, я рано обрадовался и поторопился с выводами по вариантам 7 и 8 . При новых опытах нашлась страница http://www.vezetmne.ru/rating?top500, на которой эти варианты заткнулись: в варианте 7 страница урезалась до 330 символов, а вариант 8 выдал ошибку доступа к странице. А в тех вариантах, в которых эта страница прочиталась, оказалось, что вместо кириллицы в файле результата знаки вопроса, хотя При ручном сохранении этой страницы в htm или txt кириллица пишется в файл правильно.
Кроме того, один из участников обсуждения статьи предложил добавить вариант, использующий СоздатьОбъект("MSXML2.XMLHTTP"). Поэтому я решил продолжить опыты и опробовал еще 5 вариантов чтения динамических WEB - страниц. (см. новый скриншот обработки).
- Вариант 9. MSXML2.XMLHTTP сделан без использования MSScriptControl. Читает быстро. В заголовке запроса имеет средства для указания желаемой кодировки текста, получаемого от сервера, но манипуляции с ними не помогли избавиться от знаков вопроса в файле результата вместо кириллицы.
- Вариант 10. WinHttp.WinHttpRequest.5.1 + MSScriptControl. Также работает быстро. В заголовке запроса имеет богатые средства для настройки кодировки текста, но избавиться от знаков вопроса в файле результата вместо кириллицы не удалось.
- Вариант 11.MSXML2.XMLHTTP + MSScriptControl + VBScript. Используется запуск встроенного скрипта, сделанного на основе vbs-скрипта HTTP-test.vbs, скачанного по ссылке в статье Получение и отправка данных с других web-сайтов из asp-скрипта. Страницу http://www.vezetmne.ru/rating?top500 прочитал без знаков вопроса в файле результата вместо кириллицы. Но читал очень долго, больше минуты, несколько раз запрашивал разрешения на продолжение чтения.
- Вариант 12. MSXML2.XMLHTTP (http-test.vbs + WScript.Shell) . Используется запуск указанного в варианте 11 внешнего vbs-скрипта HTTP-test.vbs. Работает аналогично варианту 11. Совершенно неприемлемая скорость чтения.
- Вариант 13. Microsoft.XMLHTTP+ MSScriptControl+ADODB.Stream. Сделан на основе процедуры СохранитьФайлИзИнтернета(Ссылка), найденной в статье V7HttpReader, проблемы с его методами. Несмотря на то, что это устаревший объект (был разработан еще для ИЕ 5.5), он, в отличие от современных объектов MSXML2.XMLHTTP и XMLHttpRequest, справился со всеми моими проблемами: показал вполне приемлемую скорость чтения и прочитал нормально ВСЕ предлагаемые ему динамические WEB - страницы, в том числе и каверзную страницу http://www.vezetmne.ru/rating?top500, причем нормально прочитал и кириллицу. Наконец-то я нашел то, что нужно.
Кстати, занятное совпадение: вариант 13, сегодня пятница, 13-е ноября. Сколько плохих примет. А у меня такая удача. Вот и верь после этого в несчастливые числа и плохие приметы!
Ссылки:
- Работа с HTTP с помощью v7plus.dll
- Пример MSScriptControl + запрос WinHttp + ADODB.Stream
- Обработка для получения курса валют
- Как сделать POST (ну и GET) запрос
- VBScript RegExp Example: Regular Expression Tester
- Interactive Regex Tester and Debugger
- VB: Загрузка курсов валют с "ручным" разбором HTML документа
- VB: Function GetCookie(strUrl)
- Получить файл через https
- HTTP/HTTPS и заголовки запроса
- WinHttpRequest Object
- Как импортировать данные из HTML?
- Отрывок из книги "Книга 1С: Предприятие 7.7/8.0. Системное программирование. 2-е издание (+CD) "
- Retrieving Data Using Visual Basic
- Объекты InternetExplorer и WebBrowser
- Получение и отправка данных с других web-сайтов из asp-скрипта
- VBS: работа с Object("MSXML2.XMLHTTP")
- XMLHttpRequest (Материал из Википедии)
- XMLHTTPRequest: описание, применение, частые проблемы
- Как написать AJAX-приложение
- HTTP протокол
- Гипертекстный протокол HTTP
- Visual Basic + HTML = VBScript
- Объект Microsoft Script Control в 1Cv7
- Получение и отправка данных с других web-сайтов из asp-скрипта.
- V7HttpReader, проблемы с его методами