Я хотел бы очистить веб-сайт (извлечь цену продукта) с одной страницы веб-сайта (с помощью HTTP-запроса XML). Но перед запуском этого скрипта мне нужно сначала выбрать правильный магазин (сохраненный в переменной cookie браузера или включенный любым другим способом / запросом, если это возможно), поскольку цены в разных магазинах разные.
Я создал рабочий код, но его запуск занимает очень много времени, поэтому я предполагаю, что должен быть более быстрый и чистый способ :). Мне также нужно было включить приложение, чтобы ждать, пока веб-сайт выполнит шаги.
Мой текущий код vba:
Выбор правильного магазина (и сохранение его в файле cookie браузера)
Sub SetStore()
Dim IE As New SHDocVw.InternetExplorer
Dim HTMLDoc As MSHTML.HTMLDocument
Dim HTMLSearchbox As MSHTML.IHTMLElement
Dim HTMLSearchboxes As MSHTML.IHTMLElementCollection
Dim HTMLButton As MSHTML.IHTMLElement
Dim HTMLButtons As MSHTML.IHTMLElementCollection
Dim HTMLSearchButton As MSHTML.IHTMLElement
Dim HTMLSearchButtons As MSHTML.IHTMLElementCollection
Dim HTMLStoreID As MSHTML.IHTMLElement
Dim HTMLStoreIDs As MSHTML.IHTMLElementCollection
Dim HTMLSaveStore As MSHTML.IHTMLElement
Dim HTMLSaveStores As MSHTML.IHTMLElementCollection
'set on False to hide IE screen
IE.Visible = True
'navigate to url with limited content
IE.navigate "https://www.jumbo.com/content/algemene-voorwaarden/"
Do While IE.readyState <> READYSTATE_COMPLETE
Loop
Set HTMLDoc = IE.document
Set HTMLButtons = HTMLDoc.getElementsByTagName("button")
For Each HTMLButton In HTMLButtons
If HTMLButton.getAttribute("data-jum-action") = "openHomeStoreFinder" Then
HTMLButton.Click
Exit For
End If
Next HTMLButton
Application.Wait Now + #12:00:02 AM#
Set HTMLSearchboxes = HTMLDoc.getElementsByTagName("input")
For Each HTMLSearchbox In HTMLSearchboxes
If HTMLSearchbox.getAttribute("id") = "searchTerm__DkKYx4XylsAAAFJktpb2Guy" Then
'input field store name/location to show search results
HTMLSearchbox.Value = "Oosterhout"
Application.Wait Now + #12:00:03 AM#
HTMLSearchbox.Click
Exit For
End If
Next HTMLSearchbox
Set HTMLSearchButtons = HTMLDoc.getElementsByTagName("button")
For Each HTMLSearchButton In HTMLSearchButtons
If HTMLSearchButton.getAttribute("data-jum-filter") = "search" Then
HTMLSearchButton.Click
Exit For
End If
Next HTMLSearchButton
Application.Wait Now + #12:00:05 AM#
Set HTMLStoreIDs = HTMLDoc.getElementsByTagName("li")
For Each HTMLStoreID In HTMLStoreIDs
'oosterhout = YC8KYx4XB88AAAFIDcIYwKxJ
'nieuwegein = 84IKYx4XziUAAAFInSYYwKrH
'vaassen = JYYKYx4XC1oAAAFItvcYwKxJ
'brielle = OG8KYx4XP4wAAAFIlsEYwKxK
If HTMLStoreID.getAttribute("data-jum-store-id") = "YC8KYx4XB88AAAFIDcIYwKxJ" Then
HTMLStoreID.Click
Application.Wait Now + #12:00:03 AM#
Exit For
End If
Next HTMLStoreID
Set HTMLSaveStores = HTMLDoc.getElementsByTagName("button")
For Each HTMLSaveStore In HTMLSaveStores
If HTMLSaveStore.getAttribute("data-jum-action") = "saveHomeStore" Then
HTMLSaveStore.Click
Exit For
End If
Next HTMLSaveStore
'IE.Quit
End Sub
Извлечение данных со страницы продукта (HTTP-запрос IE, работа со значением хранилища файлов cookie)
Sub GetJumboPriceIE()
Dim IE As New SHDocVw.InternetExplorer
Dim HTMLDoc As MSHTML.HTMLDocument
Dim JumInputs As MSHTML.IHTMLElementCollection
Dim JumInput As MSHTML.IHTMLElement
Dim JumPrice As MSHTML.IHTMLElement
Dim JumboPrice As Double
Dim Price_In_Cents_Tag As String
Dim SKU_tag As String, SKU_url As String
SKU_tag = "173140KST"
SKU_url = "https://www.jumbo.com/lu-bastogne-koeken-original-260g/173140KST/"
IE.Visible = False
IE.navigate SKU_url
Do While IE.readyState <> READYSTATE_COMPLETE
Loop
Set HTMLDoc = IE.document
IE.Quit
Set JumInputs = HTMLDoc.getElementsByTagName("input")
Price_In_Cents_Tag = "PriceInCents_" & SKU_tag
Set JumPrice = HTMLDoc.getElementById(Price_In_Cents_Tag)
JumboPrice = JumPrice.getAttribute("value") / 100
Debug.Print JumboPrice
End Sub
Приведенный выше код работает, но хотелось бы использовать код HTTP-запроса XML, как показано ниже (но с использованием правильного хранилища). Напечатана цена 1,39.
Извлечение данных со страницы продукта (с помощью HTTP-запроса XML), но значение cookie не используется
Sub GetJumboPriceXML()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim JumInputs As MSHTML.IHTMLElementCollection
Dim JumInput As MSHTML.IHTMLElement
Dim JumPrice As MSHTML.IHTMLElement
Dim JumboPrice As Double
Dim Price_In_Cents_Tag As String
Dim SKU_tag As String, SKU_url As String
SKU_tag = "173140KST"
SKU_url = "https://www.jumbo.com/lu-bastogne-koeken-original-260g/173140KST/"
XMLReq.Open "GET", SKU_url, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Problem" & vbNewLine & XMLReq.Status & " - " & XMLReq.statusText
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set JumInputs = HTMLDoc.getElementsByTagName("input")
Price_In_Cents_Tag = "PriceInCents_" & SKU_tag
Set JumPrice = HTMLDoc.getElementById(Price_In_Cents_Tag)
JumboPrice = JumPrice.getAttribute("value") / 100
Debug.Print JumboPrice
End Sub
Этот код не использует правильный магазин и выводит цену, которую я не хочу (напечатана цена 1,48).
Подвести итоги:
Если магазин не выбран (файлы cookie не установлены), по следующему URL-адресу теперь указана цена 1,48 евро.
Я хотел бы, чтобы сценарий VB настроил магазин на «Jumbo Oosterhout Nieuwe Bouwlingstraat», а затем очистил предварительно определенный список URL-адресов продуктов и извлек цены (URL-адрес выше дает 1,39 евро).
Затем настройте магазин на другой местный магазин «Jumbo Brielle Thoelaverweg» и очистите идентичный список URL-адресов продуктов. Приведенный выше URL дает 1,48 евро.
Вы можете выбрать другой магазин, щелкнув значок булавки в правом верхнем углу страницы.
Большое спасибо за вашу помощь
Я поднял вопрос здесь, но ответа пока нет.
@QHarr, извините, я этого не знал :) Вопрос с Альбертом Хейном был решен вашим другим ответом в другом сообщении и теперь отлично работает с использованием запроса на отдых API, stackoverflow.com/questions/52181293/… Текущий открытый вопрос для Jumbo, другого супермаркета, где цены разные в разных магазинах. Пожалуйста, дайте мне знать, если вопрос все еще ясен для вас. Или я должен уточнить / объяснить больше. Спасибо!
Ой! Я сбиваюсь с пути
Привет, @Qharr, есть ли способ помочь мне в дальнейшем в этом проекте? Извините, что беспокою вас снова! Я снова резюмировал вопрос в отредактированной теме (внизу сообщения) с реальными ценами, чтобы проиллюстрировать вопрос. Пожалуйста, дайте мне знать, если я могу помочь с дополнительной информацией. Спасибо!
Я ищу. За этим вопросом немного сложно следить в его текущем формате, но я дам вам знать.
Вы хотите сказать, что знаете, как это сделать с помощью IE, но хотите сделать это с помощью XMLHTTP?
Хорошо, отлично, пожалуйста, дайте мне знать, можно ли и как я могу объяснить это больше, чтобы лучше понять. Я ценю вашу помощь!
Да, с помощью IE он работает (открытие браузера, установка файла cookie и начало запроса страниц), но это очень медленно. Я знаю, что XMLHTTP работает быстрее, если только запрашивает страницу продукта и сбрасывает цену. Однако я не могу установить файл cookie и заставить XMLHTTP запомнить правильное локальное хранилище.
Вы делаете это для множества магазинов? Как долго работает IE?
Мне нужно было бы извлечь цены для 4 разных магазинов. (200 товаров в окончательном списке). При использовании текущего метода IE для извлечения всех 200 продуктов требуется до 15 минут. Так что на это уйдет не меньше часа. Нет необходимости придерживаться метода XMLHTTP, если есть другие более быстрые методы, которые можно использовать для получения того же вывода.
Привет, @QHarr, есть ли у вас новые идеи, как с этим справиться? Извините, что снова спрашиваю! Спасибо Морис
Я так запуталась, на какие из них я ответил! Смешной. Итак, я думаю, что я сказал, что проще всего было бы автоматизировать настройку местного магазина в каждом случае и получение цен. XMLHTTP на основе файлов cookie может быть чувствительным ко времени - не знаю, каков срок их действия для каждого экземпляра магазина.
Спасибо @Qharr, так что вы предлагаете придерживаться того кода, который у меня есть? Я думаю, что срок действия cookie установлен на неограниченный. Есть ли более простой способ установить магазин в файле cookie и ссылаться на этот файл cookie (или сеанс) в следующем запросе страницы продукта (и извлечь цену)? Я думаю, что мой текущий способ установки cookie в IE - не лучший возможный код :) Я мог бы установить разные магазины (один раз) в разных сеансах и направить их для очистки страниц продукта (и переключения сеансов между ними?) Не уверен, что это работает?
Привет, Морис. Вы должны поставить @qharr, чтобы я получал уведомления о сообщении в чате. Я только что увидел твое сообщение. Последнее, что я помню, я дошел до того, что, если у разработчиков API не будет способа, я, вероятно, выберу длинный путь автоматизации настройки локального магазина между каждым набором извлечения цен.