Getting meta proper content from url - vba

I am trying to get meta proper content from url but facing some problem
i want to grab "og:url" content detail, here is my code
Sub GrabCanonicalUrl3()
Const Url$ = "https://www.justdial.com/Ambala/Beauty-Parlours-in-Naraingarh"
Dim S$
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", Url, False
.Send
S = Replace(Replace(.responseText, "<!--", ""), "-->", "")
End With
With New HTMLDocument
.body.innerHTML = S
MsgBox .querySelector("meta[property='og:url']").getAttribute("content")
End With
End Sub
facing this earror
Object variable or block variable not set
MsgBox .querySelector("meta[property='og:url']").getAttribute("content")
I want to get url (og:url) link from inner HTML . but not
please help me out

Try this code
Sub Test()
Dim obj As Object, sResp As String
With CreateObject("MSXML2.xmlHttp")
.Open "GET", "https://www.justdial.com/Ambala/Beauty-Parlours-in-Naraingarh", False
.send
sResp = .responseText
End With
With CreateObject("HTMLFile")
.write sResp
For Each obj In .all(2).getElementsByTagName("meta")
If obj.getAttribute("Property") = "og:url" Then Debug.Print obj.Content: Exit For
Next obj
End With
End Sub

Related

Rest API in VBA Macros

When i wrote a http get request in vba to get the session id , instead of getting the session id , i am getting an HTML code in the immediate window?
Why is this so?
So basically , when you open the link on browser it will first ask the user to enter his username and password , then it will show him the session id.
But when i select the link in vba code , it shows me the html code
Sub Button1_Click()
Dim objRequest As Object
Dim strUrl As String
Dim blnAsync As Boolean
Dim strResponse As String
Set objRequest = CreateObject("MSXML2.XMLHTTP")
strUrl = "url to be entered"
blnAsync = True
With objRequest
.Open "GET", strUrl, blnAsync
.SetRequestHeader "Content-Type", "application/json"
.Send
'spin wheels whilst waiting for response
While objRequest.readyState <> 4
DoEvents
Wend
strResponse = .ResponseText
End With
Debug.Print strResponse
End Sub

How to use XMLHttpRequest using VBA with object data

I am currently trying to make a msgbox for a userform that I am making that responds with the data from the below javascript using VBA
$.ajax({
type: "GET",
url: app.global.AppPath + 'Dashboard/GetComments',
async: false,
data: {
id: 1015998
},
success: function(result) {}
});
VBA Code:
Private Sub UserForm_Click()
Dim strUrl As String
strUrl = "https://charter.osp-cloud.com/ATOM/Dashboard/GetComments"
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "Content-Type", "text/json"
.Send "id=1015998"
End With
MsgBox hReq.ResponseText
End Sub
Does anyone know what I am doing wrong? Is it because I am not sending a object .Send "{id: 1015998}"?
UPDATE:
upon a little more research I found that maybe parsejson might work but I cant seem to get it to recognize that there is an object
Dim JSON As Dictionary
Set JSON = JsonConverter.ParseJson("{""id"": 1015998}")
Error says "Object Required"
response pulled is below
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult GetComments(Int32)' in 'EZTRACKER.Controllers.DashboardController'.
You use POST not GET when sending data in the request body:
Also fix your content type
Private Sub UserForm_Click()
Dim strUrl As String, hreq
strUrl = "https://charter.osp-cloud.com/ATOM/Dashboard/GetComments"
Set hreq = CreateObject("MSXML2.XMLHTTP")
With hreq
.Open "POST", strUrl, False
.SetRequestHeader "Content-Type", "application/json"
.Send "{""id"":1015998}"
End With
Debug.Print hreq.ResponseText
End Sub
or if you want to use GET then the data goes in the querystring:
Private Sub UserForm_Click()
Dim strUrl As String, hreq
strUrl = "https://charter.osp-cloud.com/ATOM/Dashboard/GetComments?id=1015998"
Set hreq = CreateObject("MSXML2.XMLHTTP")
With hreq
.Open "GET", strUrl, False
.SetRequestHeader "Content-Type", "application/json"
.Send
End With
Debug.Print hreq.ResponseText
End Sub

MSXML2.XMLHTTP method data extraction issue

I am using MSXML2.XMLHTTP method for data extraction but unable to extract data from specific page
Currently using following code for data extraction from different pages.This code is working fine with other pages but not working proper for specific page.
I want to extract following values for sample page.Price,Seller name etc
Dim http As Object, html As New MSHTML.HTMLDocument, topics As Object, titleElem As Object, detailsElem As Object, topic As HTMLHtmlElement
Dim j As Long
Dim RowCount As String
Dim maxid As Long
Dim productdesc1 As String
Dim features As String
Dim news As String
Dim comb As String
t122 = Now
Rin = DMin("[id]", "url", "[Flag] = False")
If Not IsNull(Rin) Then
Set http = CreateObject("MSXML2.XMLHTTP")
'http = http.SetOption(2, 13056)
'; //ignore all SSL Cert issues
RowCount = DMin("[id]", "url", "[Flag] = False")
maxid = DMax("[id]", "url", "[Flag] = False")
'MsgBox (RowCount)
Do While RowCount <> ""
'RowCount = DMin("[id]", "url", "[Flag] = False")
url = DLookup("[url]", "url", "ID = " & ([RowCount]))
url = Trim(url)
t31 = ""
t31 = (DateDiff("n", t122, Now))
On Error Resume Next
http.Open "GET", url, False
http.Send
html.body.innerHTML = http.ResponseText
brand = html.body.innerText
Set my_data1 = html.getElementsByClassName("a-row a-spacing-mini olpOffer")
i = 1
For Each Item In my_data1
pr1 = Item.getElementsByClassName("a-size-large a-color-price olpOfferPrice a-text-bold")
pr2 = pr1.innerText
dlmsg = Item.innerHTML
If dlmsg Like "*olpShippingPrice*" Then
dpr = Item.getElementsByClassName("olpShippingPrice")
dpr2 = dpr.innerText
End If
Data should be visible from following webpage using above code.https://www.amazon.co.uk/gp/offer-listing/B00551P0Q8
The following will print out all. You can sort where to write the values to
Option Explicit
Public Sub Test()
Dim prices As Object, sellers As Object, html As HTMLDocument, i As Long
Set html = New HTMLDocument
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.amazon.co.uk/gp/offer-listing/B01GK4YHMQ", False
.Send
html.body.innerHTML = .ResponseText
End With
Set prices = html.querySelectorAll(".olpOfferPrice")
Set sellers = html.querySelectorAll(".olpSellerName a")
For i = 0 To prices.Length - 1
Debug.Print Trim$(prices.Item(i).innerText)
Debug.Print Trim$(sellers.Item(i).innerText)
Next
End Sub

Can't parse phone number from a page hindered by <br> tag

Tried to get the contact details from a page but when i run my script it only grabs the first portion of each category and ignores the rest because of some br tag, as in from contact details category it only grabs the name not the phone number or fax. Hope somebody will give me any idea how i could get that? Here is what I tried with:
Sub RestData()
Dim http As New MSXML2.XMLHTTP60
Dim html As New HTMLDocument
Dim ele As Object, post As Object
With CreateObject("MSXML2.serverXMLHTTP")
.Open "GET", "http://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736", False
.send
html.body.innerHTML = .responseText
End With
Set ele = html.getElementsByClassName("contact-details block dark")(0).getElementsByTagName("p")
For Each post In ele
x = x + 1
Cells(x, 1) = post.innerText
Next post
Set html = Nothing: Set ele = Nothing: Set docs = Nothing
End Sub
Html element for that:
<p>Company Name: Vaucraft Braford Stud<br>Phone: +61 7 4942 4859<br>Fax: +61 7 4942 0618<br>Email: florfamily1#bigpond.com<br>Web: <a target="_blank" href="http://www.vaucraftbrafords.com.au">http://www.vaucraftbrafords.com.au</a></p>
You may try something like this...
Sub RestData()
Dim http As New MSXML2.XMLHTTP60
Dim html As New HTMLDocument
Dim ele As Object, post As Object
Dim TypeDetails() As String
Dim TypeDetail() As String
Dim i As Long, r As Long
With CreateObject("MSXML2.serverXMLHTTP")
.Open "GET", "http://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736", False
.send
html.body.innerHTML = .responseText
End With
Set ele = html.getElementsByClassName("contact-details block dark")(0).getElementsByTagName("p")(2)
r = 2
TypeDetails() = Split(ele.innerText, Chr(10))
For i = 0 To UBound(TypeDetails)
TypeDetail() = Split(TypeDetails(i), ":")
Cells(r, 1) = VBA.Trim(TypeDetail(0))
Cells(r, 2) = VBA.Trim(TypeDetail(1))
r = r + 1
Next i
Set html = Nothing: Set ele = Nothing: Set docs = Nothing
End Sub

Login into website using MSXML2.XMLHTTP instead of InternetExplorer.Application with VBA

first time posting,
I'm trying to get the ID "dadosDoUsuario" from a website's page I have to be logged in. I got it working using "InternetExplorer.Application" object, but can't get the ID value when using "MSXML2.XMLHTTP" object. It seems it won't go past the login page, since I'm able to get other IDs from this page (example: "tituloPagina"). Could someone give a hint on how I get the data from the page after logged in? Thanks!
InternetExplorer.Application code (this one works):
Sub testIE()
Dim texto As String
Set ie = CreateObject("InternetExplorer.Application")
my_url = "https://www.nfp.fazenda.sp.gov.br/login.aspx"
With ie
.Visible = False
.Navigate my_url
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
End With
ie.Document.getelementbyid("userName").Value = "MYUSERNAME"
ie.Document.getelementbyid("Password").Value = "MYPASSWORD"
ie.Document.getelementbyid("Login").Click
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
ie.Document.getelementbyid("btnConsultarNFSemestre").Click
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
texto = ie.Document.getelementbyid("dadosDoUsuario").innerText
MsgBox texto
ie.Quit
End Sub
MSXML2.XMLHTTP code (this one doesn't work):
Sub testXMLHTTP()
Dim xml As Object
Dim html As Object
Dim dados As Object
Dim text As Object
Set xml = CreateObject("MSXML2.XMLHTTP")
Set html = CreateObject("htmlFile")
With xml
.Open "POST", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False
.setRequestHeader "Content-Type", "text/xml"
.send "userName=MYUSERNAME&password=MYPASSWORD"
.Open "GET", "https://www.nfp.fazenda.sp.gov.br/Inicio.aspx", False
.setRequestHeader "Content-Type", "text/xml"
.send
End With
html.body.innerhtml = xml.responseText
Set objResult = html.GetElementById("dadosDoUsuario")
GetElementById = objResult.innertext
MsgBox GetElementById
End Sub
EDIT: I followed the steps suggested by #Florent B., and added a scripcontrol to get the encoded values for __VIEWSTATE, __VIEWSTATEGENERATOR and __EVENTVALIDATION. Got it working!
Sub testXMLHTTP()
Dim xml As Object
Dim html As HTMLDocument
Dim dados As Object
Dim text As Object
Dim html2 As HTMLDocument
Dim xml2 As Object
Set xml = CreateObject("Msxml2.ServerXMLHTTP.6.0")
Set html = CreateObject("htmlFile")
With xml
.Open "GET", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False
.send
End With
strCookie = xml.getResponseHeader("Set-Cookie")
html.body.innerhtml = xml.responseText
Set objvstate = html.GetElementById("__VIEWSTATE")
Set objvstategen = html.GetElementById("__VIEWSTATEGENERATOR")
Set objeventval = html.GetElementById("__EVENTVALIDATION")
vstate = objvstate.Value
vstategen = objvstategen.Value
eventval = objeventval.Value
'URL Encode ViewState
Dim ScriptEngine As ScriptControl
Set ScriptEngine = New ScriptControl
ScriptEngine.Language = "JScript"
ScriptEngine.AddCode "function encode(vstate) {return encodeURIComponent(vstate);}"
Dim encoded As String
encoded = ScriptEngine.Run("encode", vstate)
vstate = encoded
'URL Encode Event Validation
ScriptEngine.AddCode "function encode(eventval) {return encodeURIComponent(eventval);}"
encoded = ScriptEngine.Run("encode", eventval)
eventval = encoded
'URL Encode ViewState Generator
ScriptEngine.AddCode "function encode(vstategen) {return encodeURIComponent(vstategen);}"
encoded = ScriptEngine.Run("encode", vstategen)
vstategen = encoded
Postdata = "__EVENTTARGET=" & "&__EVENTARGUMENT=" & "&__VIEWSTATE=" & vstate & "&__VIEWSTATEGENERATOR=" & vstategen & "&__EVENTVALIDATION=" & eventval & "&ctl00$ddlTipoUsuario=#rdBtnNaoContribuinte" & "&ctl00$UserNameAcessivel=Digite+o+Usuário" & "&ctl00$PasswordAcessivel=x" & "&ctl00$ConteudoPagina$Login1$rblTipo=rdBtnNaoContribuinte" & "&ctl00$ConteudoPagina$Login1$UserName=MYUSERNAME" & "&ctl00$ConteudoPagina$Login1$Password=MYPASSWORD" & "&ctl00$ConteudoPagina$Login1$Login=Acessar" & "&ctl00$ConteudoPagina$Login1$txtCpfCnpj=Digite+o+Usuário"
Set xml2 = CreateObject("Msxml2.ServerXMLHTTP.6.0")
Set html2 = CreateObject("htmlFile")
With xml2
.Open "POST", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False
.setRequestHeader "Cookie", strCookie
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Content-Lenght", Len(Postdata)
.send (Postdata)
End With
html2.body.innerhtml = xml2.responseText
Set objResult = html2.GetElementById("dadosDoUsuario")
GetElementById = objResult.innertext
MsgBox GetElementById
End Sub
It's possible but not that easy.
First you need to use CreateObject("Msxml2.ServerXMLHTTP.6.0") and not CreateObject("MSXML2.XMLHTTP").
Then follow these steps:
Open and send a GET to https://www.nfp.fazenda.sp.gov.br/login.aspx
Parse and store the cookie from the response header "Set-Cookie"
Parse and store the __VIEWSTATE, __VIEWSTATEGENERATOR, __EVENTVALIDATION from the HTML response
Build the data for the next query with the values parsed previously and with your user-name/password :
__EVENTTARGET:""
__EVENTARGUMENT:""
__VIEWSTATE:"..."
__VIEWSTATEGENERATOR:"..."
__EVENTVALIDATION:"..."
ctl00$ddlTipoUsuario:"#rdBtnNaoContribuinte"
ctl00$UserNameAcessivel:"Digite+o+Usuário"
ctl00$PasswordAcessivel:"x"
ctl00$ConteudoPagina$Login1$rblTipo:"rdBtnNaoContribuinte"
ctl00$ConteudoPagina$Login1$UserName:"..."
ctl00$ConteudoPagina$Login1$Password:"..."
ctl00$ConteudoPagina$Login1$Login:"Acessar"
ctl00$ConteudoPagina$Login1$txtCpfCnpj:"Digite+o+Usuário"
Open a POST to https://www.nfp.fazenda.sp.gov.br/login.aspx
Set the header "Cookie" with the cookie parsed at step 2
Set the header Content-Type: "application/x-www-form-urlencoded"
Set the header Content-Length with the length of the data
Send the POST with the data from step 4