Amazon & HTML AgiltiyPack - screen-scraping

It seems almost all of my request are being hit with an 500 SERVICE ERROR.
Yet I am able to access the site through a web browser just fine.I am sending UserAgent through HAP as well.
Is there anyone with experince on this matter know how Amazon is detecting that the HAP request is a robot?
Dim aHtml As New HtmlWeb
Dim UserAgent1 As String = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"
Dim iPadAgent As String = "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10"
Dim AndroidAgent As String = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
Dim iPhoneAgent As String = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5"
Dim ChromeAgent As String = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"
aHtml.UserAgent = iPadAgent
Dim Credentials As New System.Net.NetworkCredential("", "", "")
Dim proxy As New System.Net.WebProxy
Dim proxyAddress As New Uri("http://11.11.11.11")
proxy.Address = proxyAddress
Dim aDoc As HtmlDocument = aHtml.Load(AmazonURL, "GET")
Dim aNode As HtmlAgilityPack.HtmlNode
aNode = aDoc.DocumentNode.SelectSingleNode("//div[#id='olpDivId']/span[2]")
If aNode.InnerText Is Nothing Then
End If
Dim UsedPrice1 As String = aNode.InnerText
Dim i As Integer = UsedPrice1.IndexOf("$")
Dim UsedPrice As Integer = UsedPrice1.Substring(i + 1)
System.Threading.Thread.Sleep(Delay)
Return UsedPrice
'
WebClient Method(Retunrs 503):
Dim filename As String = "amzContent.html"
Client.Headers("User-Agent") = ChromeAgent
Client.Proxy = proxy
Client.Credentials = Credentials
Client.DownloadFile(AmazonURL, (Server.MapPath("amz//") & _
filename))
Dim aDoc As HtmlDocument = aHtml.Load(Server.MapPath("amz//") & _
filename)

Using the WebClient Method above, and sending language,charset,and accept headers seems to work for now

Related

Accessing keys and values in nested object with VBA

I use the translation API from Deepl in VBA. My request is working pretty fine and returns some translated html-text. However, I am not able to get the "text"-value in the returned object:
So my request looks as follows:
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
url = api & "?" & authKey & "&" & targetLng & "&" & tagHandling & "&" & sourceLng
Debug.Print url
objHTTP.Open "POST", url, False
objHTTP.setRequestHeader "Host", "api-free.deepl.com"
objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Accept", "*/*"
objHTTP.send "text=" & text
textResponse = objHTTP.responseText 'textResponse is defined as String
Debug.Print textResponse
I get the following output:
{
"translations":
[
{"detected_source_language":"DE",
"text":"<h2>SizeI</h2>love \"Paperwhite\".<br><br><img
src=\"https://ws-eu.amazon-adsystem.com/widgets/q?_encoding=UTF8"
}
]
}
I further tried:
'get the script control:
Set ScriptEngine = CreateObject("ScriptControl")
ScriptEngine.Language = "JScript"
'Get the string and parse it:
Set jsonObject = ScriptEngine.Eval("(" & textResponse & ")")
jsonObject returns [object Object] and I have no idea how to process this.
How can I access this object and return just the text-value?
Using VBA-JSON from here: https://github.com/VBA-tools/VBA-JSON
Function Test20220318()
Dim json As Object, txt, trans As Collection, t As Object, k
txt = [E1].Value 'using json stored in a cell for testing
Set json = JsonConverter.ParseJson(txt) 'a Dictionary object
Set trans = json("translations") 'access dictionary by key to get collection/array
For Each t In trans 'loop over items in collection/array
For Each k In t 'loop over keys in t
Debug.Print k, "=", t(k) 'print key and associated value
Next
Next t
End Function
The response is a JSON String.
You have to convert the JSON string to an object
Set jsonObject = DecodeJsonString(objHTTP.responseText)

How to POST to salesforce custom object?

I'm trying to POST information to a salesforce custom object, I can do it using postman. I can do a GET call already and get the information back, I have tried reading the salesforce REST API, google etc. and I just cant figure it out and I get a 400 - Bad request error.
Here's my code:
Dim jsonFields as string="{"Related_Claim__c", "a060U0000048UZRQA2"},{"Name", "TEST-08182020"}})
Dim req As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("https://na123.salesforce.com/services/data/v36.0/sobjects/Letters__c")
req.ContentType = "application/json"
req.Method = "POST"
req.Headers.Add("Authorization: Bearer 00D0U0000009rxm!AQsAQP.08BW_eXhCyx_EcrLmT.h8Ckt4PfmhZSSj7Gro8rV3U3e0.rsdJ1nX6TVMmcePkSunMdmnLf0Zjfl2EglHp392mnsk")
Dim JsonSerialized As String = JsonConvert.SerializeObject(jsonFields)
Dim bytes As Byte() = Encoding.UTF8.GetBytes(JsonSerialized )
req.ContentLength = bytes.Length
Dim os As System.IO.Stream = req.GetRequestStream()
os.Write(bytes, 0, bytes.Length)
os.Close()
Dim resp As System.Net.WebResponse = req.GetResponse()
End Sub

Exchange a OAuth 2.0 Xero Authorization Code for a Xero Access Token

This is the structure of how to get a Xero Access Token from an OAuth 2.0 Xero Authorization Code according to https://developer.xero.com/documentation/oauth2/auth-flow
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
I have created the following vb.net framework 4.6.1 Winforms code:
Dim base64Decoded As String = xeroClientId & ":" & xeroClientSecret
Dim base64Encoded As String
Dim data As Byte()
data = System.Text.ASCIIEncoding.ASCII.GetBytes(base64Decoded)
base64Encoded = System.Convert.ToBase64String(data)
Dim Basic As String = "Basic " & base64Encoded
Dim getTenant As RestClient = New RestClient("https://identity.xero.com/connect/token")
getTenant.Timeout = -1
Dim request = New RestRequest(Method.POST)
request.AddHeader("authorization", Basic)
request.AddHeader("Content-Type", "application/x-www-form-urlencoded")
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls
request.AddParameter("grant_type", "authorization_code", ParameterType.RequestBody)
request.AddParameter("code", xeroCode, ParameterType.RequestBody)
request.AddParameter("redirect_uri", String.Format("http://localhost:5000/"), ParameterType.RequestBody)
Dim response As IRestResponse = getTenant.Execute(request)
This code gives me the error
"unsupported_grant_type"
Isn't request.AddParameter("grant_type", "authorization_code", ParameterType.RequestBody) the right way of creating grant_type=authorization_code in the request body? What am I missing?
Any help would be appreciated.

How to copy from a database to a text file using VBScript?

I have an example in C# code, but it is using streamWriter. It must be involving with FileSystemObject rite. If yes, what are methods should I use? I want to code using VBScript WSH, and my database is MS SQL Server 2005.
Any solution, references, or guide are helpful.
using (StreamWriter tw = File.AppendText("c:\\INMS.txt"))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
tw.WriteLine("id, ip address, message, datetime");
while (reader.Read())
{
tw.Write(reader["id"].ToString());
tw.Write(", " + reader["ip"].ToString());
tw.Write(", " + reader["msg"].ToString());
tw.WriteLine(", " + reader["date"].ToString());
}
tw.WriteLine("Report Generate at : " + DateTime.Now);
tw.WriteLine("---------------------------------");
tw.Close();
reader.Close();
}
}
In VBScript you need ADODB objects and the FileSystemObject from the Scripting library. Something akin to:-
Dim conn: Set conn = CreateObject("ADODB.Connection")
conn.Open "an ole DB mysql connection string", usernameIfneeded, passwordIfNeeded
Dim cmd : Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "your SQL code here"
cmd.CommantType = 1 ''# adCmdText Command text is a SQL query
Dim rs : Set rs = cmd.Execute
Dim fs : Set fs = CreateObject("Scripting.FileSystemObject")
Dim textStream : Set textStream = fs.OpenTextFile("c:\inms.txt", 8, True)
textStream.WriteLine "id, ip address, message, datetime"
Do Until rs.EOF
textStream.Write rs("id") & ","
textStream.Write rs("ip") & ","
textStream.Write rs("msg") & ","
textStream.WriteLine rs("date")
rs.MoveNext
Loop
textStream.Close
rs.Close
conn.Close

Upload TXT or CSV file Using WinHTTP and LotusScript

'Declare long
Dim lng_resolveTimeout, lng_connectTimeout, lng_sendTimeout,
lng_receiveTimeout As Long
'Declare integer
Dim int_serverCredentials As Integer
'Declare variants
Dim var_submitObject As Variant
'Set values
int_serverCredentials = 0
lng_resolveTimeout = 120000 'miliseconds = 2 minutes
lng_connectTimeout = 1200000
lng_sendTimeout = 1200000
lng_receiveTimeout = 1200000
'Create HTTP object
Set var_submitObject = CreateObject("WinHTTP.WinHTTPRequest.5.1")
Call var_submitObject.SetTimeouts(lng_resolveTimeout,
lng_connectTimeout, lng_sendTimeout, lng_receiveTimeout)
'Standards for this post
%REM
Content-Type: multipart/form-data; boundary={boundary}
{boundary}
Content-Disposition: form-data; name="data"; filename="{filename}"
Content-Type: text/plain
{contents}
{boundary}--
%END REM
'Set post parameters
Call var_submitObject.open("POST", str_url, False)
Call var_submitObject.setRequestHeader("Accept", "application/xml")
Call var_submitObject.setRequestHeader("Authorization", "Basic " & str_auth)
Call var_submitObject.setRequestHeader("Content-Type", "multipart/form-data; boundary=b1")
str_boundary = |--b1| & Chr(13) &_
|Content-Disposition: form-data; name="data"; filename="name.txt"| & Chr(13) &_
|Content-Type: text/plain| & Chr(13) &_
str_fileContent & |b1--|
'Send the HTTP request
Call var_submitObject.Send(str_boundary)
'Wait for the answer and set object as returned value for further validation
Call var_submitObject.WaitForResponse
Set submitHTTP = var_submitObject
'Clear memory
Set var_submitObject = Nothing
Questions:
How to specify the "boundary" and send the file content correctly as a TXT file upload?
How to specify the line break for this boundary content?
Re the EOL question, you specify Chr(13) but that's not a complete line-feed in Windows (I assume you're using Windows based on the winhttp tag you also mention). An EOL entity in Windows is CR + LF where a carriage return is Chr(13) and a line-feed is Chr(10).
With regards text, you specify that in your content-type.

Resources