Scraping on Amazon Prime Now postcode entry - excel

I'm looking to enter a postcode on primenow.amazon.co.uk submit the form and paste the results into excel
Sub PostCode_Delivery_Short()
Dim ie As Object
Dim form As Variant, button As Variant
'add the “Microsoft Internet Controls” reference in your VBA Project indirectly
Set ie = CreateObject("InternetExplorer.Application")
'Input box for postcode
Postcode = InputBox("Enter Postcode")
With ie
.Visible = True
.Navigate ("primenow.amazon.co.uk")
'we ensure that the web page downloads completely before we fill the form automatically
Application.Wait (Now + TimeValue("00:00:04"))
'assigning the vinput variables to the html elements of the form
ie.Document.getElementsByClassName("availability__form__instructions__heading")(0).innertext = Postcode
'accessing the button via the form
Set form = ie.Document.getElementsByClassName("form")
Set button = form(0).onsubmit
form(0).submit
End With
'cleaning up memory
Set ie = Nothing
End Sub
What I'm struggling with is element ID (I think), I keep getting a runtime "error of Object variable or With block variable not set".

getElementsByName returns a collection, not a single element, so try something like:
ie.Document.getElementsByName("prime-now-input")(0).innertext = Postcode
EDIT Also:
.Document.getElementsByTagName("availability__form__instructions__heading")
I'm pretty sure there's no HTML element with that tag name ;-)
Maybe you meant getElementsByClassName() ?
EDIT2: this is the element where you need to input the postcode (using .Value, not .innerText)
<input type="text"
placeholder="Enter a postcode to see if we deliver to your area ..."
maxlength="9" data-reactid=".0.1.0.1.1.0.0.1.0.0">
My version of IE doesn't even render the input, so I can't offer more suggestions.

The website may have update and the below is for U.K. but it enters a postcode and presses the Shop Now (submit) button.
I use a CSS selector of input[type='submit'] to target the submit button. It reads as element(s) with input tag having type attribute with value 'submit'. The "[]" means attribute. Using the querySelector method to apply this selector will retrieve only the first match, as required.
Option Explicit
Public Sub SubmitPostCode()
Dim ie As New InternetExplorer
Const URL As String = "https://primenow.amazon.co.uk/onboard?sourceUrl=%2F"
Const POSTCODE As String = "WC1A 1DG"
With ie
.Visible = True
.navigate URL
While .Busy Or .readyState < 4: DoEvents: Wend
.document.getElementById("lsPostalCode").Value = POSTCODE
.document.querySelector("input[type='submit']").Click
While .Busy Or .readyState < 4: DoEvents: Wend
Stop '<== Delete me
.Quit
End With
End Sub

Related

Click the button on the USPS Web Site to find 9 digit Zip Code

USPS ZipCode Website & Excel VBA -- I have all of the code working to populate the site, but I can not click the "FIND" submit button with Excel-VBA code.
Here is the URL for the site and all of the button clicking code I have submitted
https://tools.usps.com/zip-code-lookup.htm?byaddress
'All of the different submit Code I have tried:
html.all.getElementById("zip-by-address").Click
html.all.getelementbytagname("zip-by-address").Click
html.document.querySelector("Find[type=submit]").Click
html.document.getElementsByClassName("btn btn-primary").Click
html.document.getElementById("zip-by-address").Click
For Each Element In ie.document.getElementsByName("zip-by-address")
If Element.className = "btn-primary" Then
Element.Click
End If
Next
ie.document.querySelector("button[type=submit]").Click
For Each Element In ie.document.getElementsByTagName("zip-by-address")
If InStr(Element.innerText, "Find") > 0 Then Element.Click
Next
ie.document.getElementByTagName("Find").FireEvent "onclick"
ie.document.getElementById("zip-by-address").FireEvent "onkeypress"
ie.document.getElementById("zip-by-address").FireEvent "onclick"
Set frm = ie.document.forms(0)
frm.submit
I had to complete the city and state fields as well. You don't need to select the by address option as it is already part of the url.
.querySelector("#zip-by-address").Click is equivalent to .getElementById("zip-by-address").Click but faster as modern browsers (cough IE cough) are optimized for selecting by css selectors.
Public Sub ClickFindButton()
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.Navigate2 "https://tools.usps.com/zip-code-lookup.htm?byaddress" 'url is already by address so no need to click for it
Do
DoEvents
Loop While .Busy Or .ReadyState <> READYSTATE_COMPLETE
With .Document
.querySelector("#tCompany").Value = "The New York Times Company"
.querySelector("#tAddress").Value = "620 Eighth Avenue"
.querySelector("#tCity").Value = "New York"
.querySelector("[value=NY]").Selected = True
.querySelector("#zip-by-address").Click
Stop
End With
.Quit
End With
End Sub
Search by Id
Example
ie.Document.getElementById("zip-by-address").Click

Filling Internet Explorer Forms from Excel

I want to fill information onto the site 'select picker' section on the left side of the picture.
SITE
There is an element name 'picker' but it won't work.
The search bar is being completed using jQuery auto-complete which submits a form that navigates to an associate from the auto-complete box has been selected
I tried
IE.Document.All("picker").Value = "Testing"
IE.Document.GetElementByID("pickerCtrl.currentPicker").Value = "Testing"
IE.Document.GetElementsByClassName("input-group input-group-sm").Item(0).Value = "Testing"
PS.
Is there way to just copy and paste the row at the current position where cursor is positioning at?
I can sendkeys tab 18 times to get to that specific search bar but do not know how to insert the entire row from my Excel sheet.
eg. IE.Document.all("picker").Value = ThisWorkbook.Sheets("Main_1").Range("B" & intRow).Value
I am completely new to this.
Try to make a test with example below may help to solve the issue.
Sub demo1()
Dim i As Long
Dim URL As String
Dim IE As Object
Dim HWNDSrc As Long
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "D:\Backup20190913\tests\367.html"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
IE.Document.querySelector("[name='picker']").Value = "test value"
Stop
Set IE = Nothing
End Sub
HTML
<input class="form-control ng-valid ng-isolate-scope ng-touched ng-dirty" ng-model="pickerCtrl.currentpicker" name="picker" type="text" typeahead="" typeahead-source="pickerCtrl.getpickerStrings()" ng-disabled="pickerCtrl.errorLoadingPickers || pickerCtrl.noPickerstrings" ng-hide="pickerCtrl.disableTypeahead" autocomplete="off">
Output:

Filling forms in an IE Window: Press buttons and fill in text boxes

I am trying to automate filling in an IE site that is repetitive and time consuming.
I wrote code that launches IE, makes it visible to the user, Dims the variables that it needs to fill in.
I have found the ID and the name of the text box but I cannot fill it in.
The site is a corporate site so I cannot attach the link.
I can attach the HTLM code of the box I am trying to fill and button I'm am trying to click.
TEXT BOX
<input name="ctl00$m$g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af$ctl00$grdLineItems$ctl02$txtDescription"
type="text"
id="ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_grdLineItems_ctl02_txtDescription"
class="txtDescription"
onkeydown="return (event.keyCode!=13);"
style="width:680px;margin-top:2px;margin-bottom:2px" />
BUTTON CLICK
<input type="submit"
name="ctl00$m$g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af$ctl00$ButtonAdd"
value="Add New Item"
id="ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_ButtonAdd"
style="color:Black;background-color:White;font-size:Medium;font-weight:bold;width:150px;"/>
I tried different ways. I tried getting the text box by name but I am getting an error on the document command.
MY CODE
Sub Fill_in_eShipper()
Dim IE As Object Dim web_address As String
Dim number_of_elements As Integer
Dim MydataSet As Variant
Dim ObjCollection As Object
Windows("eshipper filler.xlsm").Activate
Set IE = CreateObject("InternetExplorer.Application")
web_address = Range("c2") Range("D2").Formula = "=ROWS(A1:A161)-1"
number_of_elements = Range("d2")
IE.navigate web_address
IE.Visible = True
While IE.Busy DoEvents 'Wait till IE is done loading Wend
'Number of elements to populate
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range("D1").Select
ActiveCell.FormulaR1C1 = "=ROWS(RC[-3]:R[160]C[-3])-1"
IE.document.getelementsbyid("ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_grdLineItems_ctl02_txtDescription").Value = Range("A2")
IE.document.All("ctl00$m$g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af$ctl00$ButtonAdd").Click
End Sub
Try - changed Elements to Element and just stuck with .getElementById for the click as well.
IE.document.getElementById("ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_grdLineItems_ctl02_txtDescription").Value = Range("A2")
IE.document.getElementById("ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_ButtonAdd").Click
You have been given the best selector method in the existing answer, which is to use the element id attributes.
Here is alternate syntax for the same thing using the CSS on the page and id selectors ("#").
With ie.document
.querySelector("#ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_grdLineItems_ctl02_txtDescription").Value = Range("A2")
.querySelector("#ctl00_m_g_8fbfd2b6_3945_4bee_9a3b_20cfc2c846af_ctl00_ButtonAdd").Click
End With

Write in an HTML input field using Excel VBA

I load an internet page and log in with myusername and mypassword using VBA.
I would like to write a search-term in an input field of the webpage using VBA.
Because there is no name and ID in the input field, I didn't succeed.
Here is my code :
Sub MyLogin()
Dim IE As InternetExplorer
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True
.navigate "https://www.example.com"
Do Until .readyState = 4
DoEvents
Loop
.document.all.Item("username").Value = "myusername"
.document.all.Item("password").Value = "mypassword"
.document.forms(0).submit
End With
Do Until IE.readyState = 4
DoEvents
Loop
Dim inputfield As HTMLInputElement
For Each inputfield In IE.document.getElementsByTagName("input")
If inputfield.Type = "text" Then inputfield.Value = "mysearch"
Next
Do Until IE.readyState = 4
DoEvents
Loop
End Sub
The HTML field I want to fill:
input class="input-inboxsearch form-control" type="text" value="" placeholder="Nom, email" maxlength="71"
How can I set the value of the input field?
Further to #Miqi180's comment, you can try replacing your the section of your code starting with Dim inputfield As HTMLInputElement with this:
Dim inputfield As Object
Set inputfield = IE.document.getElementsByClassName("input-inboxsearch form-control")
If inputfield.length > 0 Then
inputfield(0).Value = "mysearch"
End If
'carry on with your code
The getElementsByClassName method will return a collection so you have to check its length and then access the items of the collection. If there is only one element with that class then you can reference the 0th element of the collection.
I've set the inputfield variable as an Object because you appear to be using late binding.

Fill USPS webform dropdown using VBA EXCEL

I am trying to automatically fill a USPS webform, and it is working for street address, city and zipcode, but I can't make it fill the State dropdown. Any ideas?
Here's the code I currently have:
Sub USPS()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "https://tools.usps.com/go/ZipLookupAction!input.action?mode=1&refresh=true"
Do
DoEvents
Loop Until IE.READYSTATE = 4
Call IE.Document.getElementByID("tAddress").SetAttribute("value", "2 Peabody Terrace")
Call IE.Document.getElementByID("tCity").SetAttribute("value", "Cambridge")
Call IE.Document.getElementByID("sState").SetAttribute("value", "MA")
Call IE.Document.getElementByID("Zzip").SetAttribute("value", "02138")
Set AllHyperLinks = IE.Document.GetElementsByTagName("A")
For Each hyper_link In AllHyperLinks
If ID = "lookupZipFindBtn" Then
hyper_link.Click
Exit For
End If
Next
End Sub
Thank you very much for your help!
Make this change to your code:
'Call IE.Document.getElementByID("sState").SetAttribute("value", "MA")
With IE.Document.getElementByID("sState")
For i = 0 To .Length - 1
If .Item(i).Value = "MA" Then
.Item(i).Selected = True
Exit For
End If
Next
End With
This will work... but the web page will still show like the Select element has not changed. It's an illusion. I suspect there is some JavaScript in the page interfering with this element's display.
HOWEVER, if you do this in the Immediate Window of the VBEditor:
?IE.Document.getElementByID("sState").value
...you will see that the value for the control has indeed changed to 'MA'.
Further, if you go ahead and click on the web page's Find button, you will see that 'MA' was in fact included under 'You entered:'.
So my code above is the solution to your problem.
CSS selectors:
You can use css selectors to do this.
① The first selector I use is for the initial landing page to select the search by address:
#zip-lookup-app a > span
This says span tag within an a tag, inside element with id zip-lookup-app. "#" means id.
This matches the following, of which I want the first.
② The second selector:
#tState option[value='MA']
This says select option tag with attribute value, having value of 'MA', within element with id tState. The "[]" means attribute.
VBA:
As I want the first match I can use the querySelector method of document to apply the CSS selector as shown below:
Option Explicit
Public Sub MakeStateSelection()
Dim ie As New InternetExplorer, html As HTMLDocument
With ie
.Visible = True
.navigate "https://tools.usps.com/go/ZipLookupAction!input.action?mode=1&refresh=true"
While .Busy Or .READYSTATE < 4: DoEvents: Wend
Set html = .document
html.querySelector("#zip-lookup-app > div > div:nth-child(1) > div > ul > li:nth-child(1) > a > span").Click
While .Busy Or .READYSTATE < 4: DoEvents: Wend
html.querySelector("#tState option[value='MA']").Selected = True
'other code
Stop '<== Delete me
'.Quit '<== Uncomment me
End With
End Sub

Resources