Данная функция возвращает исходный текст web-страницы:
Function GetHTTPResponse(ByVal sURL As String) As String On Error Resume Next Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP") With oXMLHTTP .Open "GET", sURL, False ' раскомментируйте следующие строки и подставьте верные IP, логин и пароль ' если вы сидите за proxy ' .setProxy 2, "192.168.100.1:3128" ' .setProxyCredentials "user", "password" .send GetHTTPResponse = .responseText End With Set oXMLHTTP = Nothing End Function
Пример использования функции GetHTTPResponse
Private Sub ПримерИспользованияФункции_GetHTTPResponse() ' считываем исходный текст страницы ExcelVBA.ru в переменную txt txt = GetHTTPResponse("http://ExcelVBA.ru") ' получаем путь к папке "Рабочий стол" ПутьКРабочемуСтолу = CreateObject("WScript.Shell").SpecialFolders("Desktop") ' сохраняем текст из переменной txt в файл PageText.txt на рабочем столе SaveTXTfile ПутьКРабочемуСтолу & "\PageText.txt", txt ' открываем созданный текстовый файл в Excel Workbooks.OpenText ПутьКРабочемуСтолу & "\PageText.txt" End Sub Function SaveTXTfile(ByVal filename As String, ByVal txt As String) As Boolean On Error Resume Next: Err.Clear Set fso = CreateObject("scripting.filesystemobject") Set ts = fso.CreateTextFile(filename, True) ts.Write txt: ts.Close SaveTXTfile = Err = 0 Set ts = Nothing: Set fso = Nothing End Function
PS: Если вас интересует ТЕКСТ страницы - используйте эту функцию: http://excelvba.ru/code/GetWebPageText
Еще один вариант кода - где можно задать таймаут
(чтобы код не подвисал, если нет ответа от сайта в течение нескольких секунд)
ВНИМАНИЕ: Надо подключить в Tools - References библиотеку Microsoft WinHTTP Services 5.1
Const TIMEOUT& = 6 ' в секундах Function GetResponse(ByVal URL$) As String On Error Resume Next: Err.Clear Static xmlhttp As WinHttpRequest If xmlhttp Is Nothing Then Set xmlhttp = New WinHttpRequest xmlhttp.Open "GET", URL$, True: DoEvents xmlhttp.Send: DoEvents If Not xmlhttp.WaitForResponse(TIMEOUT&) Then Debug.Print "timeout", URL: Exit Function End If GetResponse = xmlhttp.responsetext End Function
Sub test() ' пример использования On Error Resume Next txt = GetResponse("http://ExcelVBA.ru/") Debug.Print Len(txt) ' возвращает длину текста: 62737 символов End Sub
Ещё один пример функции - с возможностью задать кодировку:
Sub ТекстВебСтраницы_вКодировке_Windows1251() URL$ = "http://ExcelVBA.ru/" MsgBox GetHTTPResponse(URL$) ' MsgBox GetHTTPResponse(URL$, "windows-1251") ' если бы сайт выдавал страницу в windows-1251 End Sub
Function GetHTTPResponse(ByVal URL$, Optional ByVal Encoding$) As String On Error Resume Next Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP") With oXMLHTTP .Open "GET", URL$, False .Send If Len(Encoding$) Then With CreateObject("ADODB.Stream") filename$ = Environ("tmp") & "\response.txt" .Charset = Encoding$: .Type = 1 ' adTypeBinary: .Open: .Write oXMLHTTP.ResponseBody .SaveToFile filename$, 2 .Type = 2 'adTypeText .LoadFromFile filename$ GetHTTPResponse = .ReadText .Close End With Else GetHTTPResponse = .ResponseText End If End With Set oXMLHTTP = Nothing End Function
' еще один вариант макроса для загрузки страницы
Sub test_internet() On Error Resume Next URL$ = "http://ExcelVBA.ru/" Const TIMEOUT& = 6 ' в секундах Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1") xmlhttp.Open "GET", URL$, True: DoEvents xmlhttp.Send: DoEvents If Not xmlhttp.WaitForResponse(TIMEOUT&) Then MsgBox "timeout", URL: Exit Sub End If txt$ = xmlhttp.responsetext MsgBox txt, vbInformation, "Длина ответа: " & Len(txt) End Sub
А эту заготовку кода я использовал, когда писал макросы для загрузки данных с сайтов
(последние несколько лет подобные макросы не пишу, ибо сделал универсальную надстройку «Парсер сайтов», в которой всё это реализуется 1-2 простейшими командами)
Sub LoadInfo() ' On Error Resume Next Dim ra As Range: Set ra = Range(Range("b2"), Range("b" & Rows.Count).End(xlUp)) If ra.Row = 1 Then MsgBox "На листе не найден список ИНН", vbCritical: Exit Sub Dim cell As Range, txt$, res$, result_cell As Range, v Const TIMEOUT& = 6: Static xmlhttp As Object If xmlhttp Is Nothing Then Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1") For Each cell In ra.Cells URL$ = "https://sbis.ru/contragents/" & Trim(cell) xmlhttp.Open "GET", URL$, True: DoEvents xmlhttp.Send: DoEvents If Not xmlhttp.WaitForResponse(TIMEOUT&) Then Debug.Print "timeout", URL Else txt$ = "": txt$ = xmlhttp.responsetext ' обработка ответа сервера ' функцию GetTags можно взять здесь: excelvba.ru/code/html res$ = "": res$ = GetTags(txt, "div", "class", "cCard__Content-Var", "config 1") res$ = Replace(res$, "%22", "'"): res$ = Replace(res$, """", "'") ' ищем в ответе нужные данные With cell.EntireRow .Cells(3) = Replace(GetValue(res$, "УставнойКапитал"), " ", "") .Cells(4) = GetValue(res$, "Статус") .Cells(5) = GetValue(res$, "ВыручкаСтатистика") .Cells(6) = GetValue(res$, "ПрибыльСтатистика") .Cells(7) = GetValue(res$, "Выручка") .Cells(8) = GetValue(res$, "Прибыль") .Cells(9) = GetValue(res$, "ЧисленностьСотрудников") End With End If Next cell End Sub
Комментарии
Какую функцию использовали?
GetHTTPResponse или GetResponse?
Если первую, - то попробуйте вторую, и ошибка наверняка исчезнет.
Добрый день.
Использовал этот код при сканировании базы newhomes.e1.ru
Еще неделю назад все работало отлично. Сейчас же при запросе к любому действующему объявлению код выдает пустой файл.
В чем может быть причина? Какая-то защита?
Здравствуйте. Пробую этот код и он работает только для некоторых сайтов (для этого сайта, рамблера), для других же возвращает пустой файл (яндекс, гугл, спортс и тп). Не подскажете, в чем причина?
Владлен, а вы попробуйте скопировать (это же секундное дело), - а потом спрашивайте...
Поскольку функция не задействует возможностей Excel, - то код без переделок будет работать и в VB6
Ну и в DLL можно вынести, при желании.
Добрый день! А можно ли эту функцию вынести в ДЛЛ? Если писать её на ВБ6 - какие-то будут изменения, или можно просто скопировать?
В том то и дело, что доступ есть, а синхронный запрос дает быстрый и правильный результат. А макрос, который я прислал тормозит примерно на 5 сек. и выдает 0. Ничего не понимаю.
У меня, ваша функция возвращает корректную дату, - 16.07.2013
Так что все работает. Ищите проблему в другом (может, у Excel нет доступа в интернет)
Наверное туплю... Но мне надо получать из интернета текущую дату. Я с помощью этой странички написал такой макрос:
Function current_date() As Date
Const sURI = "http://www.gov.ru/"
Const timeout& = 10
Dim htmlcode, htmlcode1 As String
On Error Resume Next
Err.Clear
Static xmlhttp As WinHttpRequest
If xmlhttp Is Nothing Then Set xmlhttp = New WinHttpRequest
xmlhttp.Open "GET", sURI, True: DoEvents
xmlhttp.Send: DoEvents
If Not xmlhttp.WaitForResponse(timeout&) Then
current_date = 0
Exit Function
End If
htmlcode = xmlhttp.ResponseText
htmlcode1 = Mid(htmlcode, InStr(1, htmlcode, """setDate"">") + 10, 10)
current_date = DateSerial(CInt(Right(htmlcode1, 4)), CInt(Mid(htmlcode1, 4, 2)), CInt(Left(htmlcode1, 2)))
End Function
но он всегда выдает мне 0. Видимо я что-то недопонимаю...
А вы прочитайте статью до конца, - и решение найдётся)
Здравствуйте. Как хорошо, что я нашел эту страничку, вот спасибо. Вот только не могу никак понять, как прерывать запрос и возвращать пустую строку, если запрос выполняется, например, более 10 секунд. Заранее благодарю.
Все получилось.
Большое спасибо.
Конечно можно.
Добавьте эту строку кода перед строкой
Вы совершено правы в случае «если у макроса (точнее, у Excel) есть доступ к интернету.»
Этот макрос изумительно работает на домашнем компьютере, на рабочем же не происходит считывание страниц ни с какого сайта.
В то же время первый вариант кода, без таймаута и библиотеки Microsoft WinHTTP Services 5.1, работает даже на рабочем компьютере, за исключением сайтов имеющих задерку «Verifying you're human...».
Можно ли в первый вариант кода ввести задерку типа «Application.Wait Now + 3 / 86400 ' пауза 3 секунды»?
Никакие «рекомендации» вам не нужны.
Я вам дал готовый код, который работает, если у макроса (точнее, у Excel) есть доступ к интернету.
Результат работы вашего макроса можно увидеть на скриншоте:
http://ExcelVBA.ru/pictures/20130423-1h7-102kb.jpg
Спасибо.
Библиотеку Microsoft WinHTTP Services 5.1 подключил.
Макрос отрабатывает до конца, табличка с кнопкой "ОК" выводится но текста считываемой страници нет.
Рекомендации в ответе " #13 Ильшат, 8 Сен 2012 - 23:16."
не дают результата.
Сергей, в статье написано, что надо сделать:
При выполнении «ЭтаКнига.test», останавливается на - xmlhttp As WinHttpRequest,
Выскакивает табличка
Compile error:
User-defined type not defined
Что я не так сделал?
Здравствуйте, Сергей.
Мне хватило паузы в 2-3 секунды:
Добрый день.
Используя функцию GetHTTPResponse для считывания исходного текста страницы, столкнулся со следующим:
На некоторых сайтах, при открытии страницы в качестве защиты от роботов, появляется строка «Verifying you're human...» на 10-30 сек и только потом загружается страница. Соответственно функция GetHTTPResponse считывает только «Verifying you're human...».
(пример такого сайта https:// success-trade . net/)
Возможно ли, сделать задержку на считывание, регулируемую по времени, либо другим путем обойти эту проблему?
Тут от версии Office ничего не зависит.
Сколько пользуюсь кодом - с подобной проблемой не сталкивался.
Хотя, я в основном пользуюсь другим кодом - функцией GetResponse, - где можно задать таймаут.
Добавил новый код в текст статьи (там точно не ограничения на длину текста)
Во-первых, огромное спасибо за статью!
Подскажите, а Вы не сталкивались с проблемой, что в 2007 офисе данный код сохраняет страницу не до конца (сохраняет не более 32000 символов)? В чем может быть проблема?
Спасибо, все работает
Но есть необходимость получать данные, где необходимо авторизоваться
Но авторизация не проходит
Алексей, проще всего сделать это через RegExp - регулярные выражения.
Если же достаточно проверять только начало строки - <тд align="center"><фонт class="grn">
то задача упрощается.
К примеру, исходный код страницы у вас находится в переменной txt
Для начала, разбиваем строку на массив, используя в качестве разделителя текст <тд align="center"><фонт class="grn">:
Потом проходим в цикле по этому массиву, оставляя от каждого элемента текст до символа "<":
Здравствуйте. Я получил код страницы. Все работает. Как мне получить все значения
<td align="center"><font class="grn">1000</font></td>
в макросе.Их там 60 штук. значение 1000 - может быть любым, это для примера.
Скачать исходный код ВСЕГО сайта - нереально.
Но это в вашем случае и не требуется.
Если на сайте есть страницы (неважно, сколько их), где присутствуют ссылки на все необходимые для закачки файлы, - то сделать можно.
Принцип работы макроса:
1) в цикле перебираем все страницы со ссылками на файлы
2) по каждой ссылке с каждой страницы загружаем файл
Универсального решения тут нет - макрос надо разрабатывать под конкретный сайт.
Оформляйте заказ - попробую помочь.
Добрый день!
Подскажите, пожалуйста, можно ли как-то скачать исходный код всего сайта, а не только страницы?
Исходная задача следующая:
Автоматически скачать с сайта загруженные на него файлы (не все, только необходимые). Из исходного кода, необходимо вернуть часть ссылки, по которой будет идти загрузка.
Ссылки на файлы лежат на нескольких страницах, поэтому считывая код одной страницы, в исходном коде информация есть только о части файлов.
Из этого следует вопрос можно ли как-то получить исходный код всех страниц? Или возможно есть другой вариант решения данной задачи?
Ильшат, я тут недавно редактировал код функции, и допустил ошибку.
Надо строку
поменять на
Внёс исправления в статью.
Не получается. Пустой файл сохраняет. Разные урл скармливал. Очень нужна данная функция. Если можете подправьте. Буду очень признателен.
Нет, тормозить не будет.
Преобразование текстовой строки в массив выполняется моментально (за тысячные доли секунды) даже на очень древних компьютерах.
Запись массива на лист (если там не тысячи строк) тоже выполняется очень быстро - по крайней мере, в десятки раз быстрее, чем производится загрузка данных с сайта.
Спасибо.
Второй способ не подходит ни как
А первый мне кажется будет тормозить т.к. комп на работе тормоз.
Да, можно.
Но к коду получения исходного текста веб-страницы это не имеет отношения.
Вариантов несколько, вот 2 из них, которыми бы я воспользовался
(выбрал бы один из вариантов, в зависимости от конкретного сайта):
1. Скачать ТЕКСТ (а не ИСХОДНЫЙ КОД) веб-страницы, и обработать полученную текстовую строку макросом, получив из неё массив значений.
Потом этот массив записать на лист.
2. Использовать веб-запрос.
Это куда проще, если веб-страница нормально структурирована.
Тут даже макросы не нужны - запрос составляется через инструментарий Excel буквально за несколько секунд.
И обновлять запрос очень легко - достаточно нажать одну кнопку («Обновить»).
А как можно таблицу загруженную с сайте (то есть в HTMLе),раложить по ячейкам в Excel.
А то получается все в сплошные строки, без разделителей.
Пример кода:
Время
Плавка
Марка
Тн.
№
C
Mn
Si
S
P
Cr
Ni
Cu
Al
Ti
Mo
V
W
N2
As
B
Ca
03.02.12 03:46134757 041 .1510 1.2300 .4100 .0150 .0120 .0430 .0360 .0290 .0290 .0037
Отправить комментарий