Scraping from VBA (very close to working!!) - vba

I have been playing around with a scraper for consumer stocks and I can scrape data from the main page of items but once i start using the second, thid parges,
Sub asosdesc2()
Const READYSTATE_COMPLETE = 4
Dim j As Integer
Dim ie As InternetExplorer
Dim Doc As IHTMLDocument
Dim xcolElements As IHTMLElementCollection
Dim ell As IHTMLElement
Dim pn As Integer
j = 1
Set ie = CreateObject("InternetExplorer.Application")
For pn = 1 To 1
ie.Visible = False
ie.Navigate "http://www.asos.com/Men/Sale/Accessories/Cat/pgecategory.aspx?cid=2097&CTARef=shop|sale|cat|accessories#parentID=-1&pge=0&pgeSize=36&sort=-1"
Do
DoEvents
Loop Until Not ie.Busy And ie.readyState = READYSTATE_COMPLETE
Set Doc = ie.Document
'Set xcolElements = Doc.getElementsByClassName("description")
'Here lies the problem. Description works perflectly, price doesn't
Set xcolElements = Doc.getElementsByClassName("desc")
For Each ell In xcolElements
On Error GoTo Skip
Range("B" & j).Value = ell.innerText
j = j + 1
Skip:
Next ell
On Error GoTo 0
Next pn
ie.Quit
Set el = Nothing
Set xcolElements = Nothing
Set Doc = Nothing
Set ie = Nothing
End Sub
I am trying to return the description, the price and the HREF code to identify the item

Instead of looping through the collection of "desc" anchors (which only contain the product description), I suggest you loop through their parent "items" collection. That way you can reference your anchors' siblings, which contain price etc.:
Sub asosdesc2()
Const READYSTATE_COMPLETE = 4
Dim j As Integer
Dim ie As InternetExplorer
Dim Doc As IHTMLDocument
Dim itemsColl As IHTMLElementCollection
Dim itemsEle As IHTMLElement
Dim itemsAttributesColl As IHTMLElementCollection
Dim itemsAttributesEle As IHTMLElement
Dim pn As Integer
On Error GoTo 0
j = 1
Set ie = CreateObject("InternetExplorer.Application")
For pn = 1 To 1
ie.Visible = True
ie.Navigate "http://www.asos.com/Men/Sale/Accessories/Cat/pgecategory.aspx?cid=2097&CTARef=shop|sale|cat|accessories#parentID=-1&pge=0&pgeSize=36&sort=-1"
Do
DoEvents
Loop Until Not ie.Busy And ie.readyState = READYSTATE_COMPLETE
Set Doc = ie.Document
Set itemsColl = Doc.getElementById("items").Children
For Each itemsEle In itemsColl
On Error GoTo Skip
Set itemsAttributesColl = itemsEle.Children
For Each itemsAttributesEle In itemsAttributesColl
If itemsAttributesEle.className = "desc" Then
Range("B" & j).Value = itemsAttributesEle.innerText 'Description
Range("E" & j).Value = itemsAttributesEle.getAttribute("href") 'Link
End If
If itemsAttributesEle.className = "productprice" Then
Range("C" & j).Value = itemsAttributesEle.Children(0).innerText 'recRP
Range("D" & j).Value = itemsAttributesEle.Children(1).innerText 'Outlet current price
End If
Next itemsAttributesEle
j = j + 1
Skip:
Next itemsEle
On Error GoTo 0
Next pn
ie.Quit
Set itemsColl = Nothing
Set itemsEle = Nothing
Set itemsAttributesColl = Nothing
Set itemsAttributesEle = Nothing
Set Doc = Nothing
Set ie = Nothing
End Sub

Related

Clicking on a link without Id or class

I have a code that does a research for the user in a website and then get the information from that research.
In the process of acessing the information, I need to click o a link inside the website. This link can change everytime the user makes a different research, so I can't use it's href to acess it. I have no clue about what to do.
Here's my code until now: it goes until the webpage where the link is.
Steps of the code:
user insert his research. example: "icms base de calculo pis cofins"
open ie in: http://www.stj.jus.br/SCON/
insert the research
click on: "sumulas", "decisões monocromaticas" and "informativos de jurisprudencia". That way I acess only the "acordãos".
click on "pesquisar"
I need to click on the link in front of "Acórdãos"
Here's the code:
Sub teses2()
Dim pesquisa As String
Dim ie As InternetExplorer
Dim elemns As Object
Dim elem As Object
Dim elemns2 As Object
Dim elem2 As Object
Dim elem3 As Object
Dim obj As Object
pesquisa = InputBox("Digite os termos que quer pesquisar: ", "", "")
Set ie = New InternetExplorer
ie.Visible = True
ie.navigate "http://www.stj.jus.br/SCON/"
Application.Wait (Now + TimeSerial(0, 0, 20))
ie.document.getElementById("pesquisaLivre").innerText = pesquisa
Set elemns2 = ie.document.getElementsByTagName("input")
For Each elem2 In elemns2
If elem2.Value = "SUMU" Then
elem2.Click
End If
If elem2.Value = "DTXT" Then
elem2.Click
End If
If elem2.Value = "INFJ" Then
elem2.Click
End If
Next
Set elemns = ie.document.getElementsByTagName("input")
For Each elem In elemns
If elem.Value = "Pesquisar" Then
elem.Click
End If
Next
End Sub
I have revisited this and made it tighter.
Option Explicit
Sub teses2()
Dim pesquisa As String
Dim ie As InternetExplorer
'*SUSPENDED * pesquisa = InputBox("Digite os termos que quer pesquisar: ", "", "")
pesquisa = "icms base de calculo pis cofins"
Set ie = New InternetExplorer
ie.Visible = True
ie.navigate "http://www.stj.jus.br/SCON/"
While ie.Busy
DoEvents
Wend
While ie.Document.ReadyState = "complete"
DoEvents
Wend
'Stop
Application.Wait (Now + TimeSerial(0, 0, 3))
ie.Document.getElementById("pesquisaLivre").innerText = pesquisa
Dim oHtml As MSHTML.HTMLDocument '* gives intellisense
Set oHtml = ie.Document
Dim oSelectors As MSHTML.IHTMLDOMChildrenCollection
Set oSelectors = oHtml.querySelectorAll("div.blocoCampos input")
Dim lSelectorResultList As Long
lSelectorResultList = oSelectors.Length
Dim lSelectorResultLoop As Long
For lSelectorResultLoop = 0 To lSelectorResultList - 1
Dim objInputCheckbox As Object
Set objInputCheckbox = oSelectors.Item(lSelectorResultLoop)
If Not objInputCheckbox Is Nothing Then
Dim sLabel As String
sLabel = objInputCheckbox.Value
If VBA.InStr(1, "|SUMU|DTXT|INFJ|", "|" & sLabel & "|", vbTextCompare) > 0 Then
objInputCheckbox.Click
End If
End If
Next
'* release references
Set objInputCheckbox = Nothing
Set oSelectors = Nothing
Set oHtml = Nothing
Dim elemns As MSHTML.IHTMLDOMChildrenCollection
'Set elemns = ie.Document.getElementsByTagName("input")
Set oHtml = ie.Document
Set elemns = oHtml.querySelectorAll("div#botoesPesquisa input:nth-child(1)")
Debug.Assert elemns.Length = 1
Dim elem As Object
Set elem = elemns.Item(0)
'For Each elem In elemns
If elem.Value = "Pesquisar" Then
elem.Click
End If
'Next
'* release references
Set elem = Nothing
Set elemns = Nothing
While ie.Busy
DoEvents
Wend
'While ie.Document.ReadyState = "complete"
' DoEvents
'Wend
'* POST NAVIGATION
'Stop
Application.Wait (Now + TimeSerial(0, 0, 10))
Set oHtml = ie.Document
Dim objResultList As MSHTML.IHTMLDOMChildrenCollection
Set objResultList = oHtml.querySelectorAll("div#itemlistaresultados span:nth-child(2) a")
Dim lResultCount As Long
lResultCount = objResultList.Length
Debug.Print
Dim lResultLoop As Long
For lResultLoop = 0 To lResultCount - 1
Dim anchorLoop As MSHTML.HTMLAnchorElement
Set anchorLoop = objResultList.Item(lResultLoop)
Debug.Print anchorLoop.href
Next
ie.Quit
Set ie = Nothing
'Stop
End Sub

Error While using Macro to add google's first image link to excel

I'm using the below Code to input Google's first images link in B1
for certain values in A1.
Public Sub Test()
Dim IE As InternetExplorer
Dim HTMLdoc As HTMLDocument
Dim imgElements As IHTMLElementCollection
Dim imgElement As HTMLImg
Dim aElement As HTMLAnchorElement
Dim N As Integer, I As Integer
Dim Url As String, Url2 As String
Dim LastRow As Long
Dim m, sImageSearchString
LastRow = Range("A" & Rows.Count).End(xlUp).Row
For I = 1 To LastRow
Url = "http://www.google.co.in/search?q=" & Cells(I, 1) & "&source=lnms&tbm=isch&sa=X&rnd=1"
Set IE = New InternetExplorer
With IE
.Visible = False
.Navigate Url 'sWebSiteURL
Do Until .readyState = 4: DoEvents: Loop
'Do Until IE.document.readyState = "Complete": DoEvents: Loop
Set HTMLdoc = .document
Set imgElements = HTMLdoc.getElementsByTagName("IMG")
N = 1
For Each imgElement In imgElements
If InStr(imgElement.src, sImageSearchString) Then
If imgElement.ParentNode.nodeName = "A" Then
Set aElement = imgElement.ParentNode
Url2 = imgElement.src
N = N + 1
End If
End If
Next
Cells(I, 2) = Url2
IE.Quit
Set IE = Nothing
End With
Next
End Sub
however I'm receiving the below error, can you please advise?
I'm using Windows 10, Excel 365
In VBA Menu - Tools - References - tick MS Internet Controls.
Or
Using Late Binding
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")

Web scraping with Excel and VBA

I am trying to extract the team names but i get the "Run time error 424 Object required" on this line
Set lists = html.getElementsByClassName("KambiBC-event-item__participants-container")
, if anyone could point me in the right direction it would be nice.
Sub useClassnames()
Dim lists As IHTMLElementCollection
Dim anchorElements As IHTMLElementCollection
Dim ulElement As HTMLUListElement
Dim liElement As HTMLLIElement
Dim row As Long
Dim ie As InternetExplorer
Set ie = New InternetExplorer
With ie.navigate "https://www.unibet.ro/betting#filter/all/all/all/all/in-play"
.Visible = True
Do While ie.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
End With
Set lists = html.getElementsByClassName("KambiBC-event-item__participants-container")
row = 1
For Each ulElement In lists
For Each liElement In ulElement.getElementsByClassName("KambiBC-event-participants")
Set anchorElements = liElement.getElementsByClassName("KambiBC-event-participants__name")
If anchorElements.Length > 0 Then
Cells(row, 1) = anchorElements.Item(0).innerText
row = row + 1
End If
Next liElement
Next ulElement
End Sub
Error 424 is an Object Required Error. What is Html in Set lists = html.getElementsByClassName("KambiBC-event-item__participants-container")?
What you need is
Set lists = ie.document.getElementsByClassName("KambiBC-event-item__participants-container")
Code that I used
Sub useClassnames()
Dim lists As IHTMLElementCollection
Dim anchorElements As IHTMLElementCollection
Dim ulElement As HTMLUListElement
Dim liElement As HTMLLIElement
Dim row As Long
Dim ie As InternetExplorer
Set ie = New InternetExplorer
With ie
.navigate "https://www.unibet.ro/betting#filter/all/all/all/all/in-play"
.Visible = True
Do While ie.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
End With
Set lists = ie.document.getElementsByClassName("KambiBC-event-item__participants-container")
row = 1
For Each ulElement In lists
For Each liElement In ulElement.getElementsByClassName("KambiBC-event-participants")
Set anchorElements = liElement.getElementsByClassName("KambiBC-event-participants__name")
If anchorElements.Length > 0 Then
Cells(row, 1) = anchorElements.Item(0).innerText
row = row + 1
End If
Next liElement
Next ulElement
End Sub
Screenshot

I'm trying to import innertext from a td-class. Getting lots of extra text

I'm trying to get the innertext of 'wfm-bodyText'. So, I want to loop through items on a webpage and import, in this case, 'H. Validate Gamer Correct'
I thought the script below would work, but it actually gives me all kinds of extra text!!
Public Sub CopyFromURL()
Dim IE As InternetExplorer, doc As HTMLDocument
Dim thisClass As IHTMLElement2, thisLink As IHTMLElement
Dim rng As Range, cell As Range
Const READYSTATE_COMPLETE As Integer = 4
Dim TR_col As Object, TR As Object
Dim TD_col As Object, TD As Object
Dim row As Long, col As Long
row = 1
'Set rng = Range("A1:A5")
'For Each cell In rng
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate URL
Do While (IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE)
DoEvents
Loop
Set TR_col = IE.Document.getElementsByTagName("TR")
For Each TR In TR_col
Set TD_col = TR.getElementsByTagName("TD")
row = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).row
col = 1
For Each TD In TD_col
Cells(row, col) = TD.innerText
col = col + 1
Next
row = row + 1
Next
'Next cell
IE.Quit
End Sub
The URL is behind a firewall. I can't share it.
Again, below is the structure of the page. I want to copy the 'E. Verify phone number if applicable' into my sheet.
I tried the script below in an attempt to get every element from the page.
Sub DumpData()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "http://www.SharePoint.aspx"
'Wait for site to fully load
IE.Navigate2 URL
Do While IE.Busy = True
DoEvents
Loop
RowCount = 1
With Sheets("Sheet1")
.Cells.ClearContents
RowCount = 1
For Each itm In IE.document.all
.Range("A" & RowCount) = itm.tagname
.Range("B" & RowCount) = itm.ID
.Range("C" & RowCount) = itm.classname
.Range("D" & RowCount) = Left(itm.innertext, 1024)
RowCount = RowCount + 1
Next itm
End With
End Sub
I still can't tell where the relevant data is coming from.

Scraping from VBA - scraper already works on some data but not others

I have used code from this website to pull data from property site Foxtons, the code is as follows
Sub foxtons()
Const READYSTATE_COMPLETE = 4
Dim j
Dim xcolElements
Dim Doc, ell, ie
Dim pn
j = 1
For pn = 1 To 10
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = False
ie.Navigate "http://www.foxtons.co.uk/search?current_page=" & pn & "&location_ids=288&search_form=map&search_type=SS&sold=1&submit_type=search"
Do
DoEvents
Loop Until Not ie.Busy And ie.readyState = READYSTATE_COMPLETE
Set Doc = ie.Document
Set xcolElements = Doc.getElementsByClassName("description")
'Here lies the problem. Description works perflectly, price doesn't
For Each ell In xcolElements
Range("B" & j).Value = ell.FirstChild.Data
j = j + 1
Next
Next pn
ie.Quit
Set el = Nothing
Set xcolElements = Nothing
Set Doc = Nothing
Set ie = Nothing
End Sub
The above code works and should pull in 600 property descriptions into column B. The problem arises when I switch "descriptions" to price. Here I receive an error message yet this is probably much more important for me
Use this code to retrieve the price elements:
Private Sub CommandButton1_Click()
Const READYSTATE_COMPLETE = 4
Dim j As Integer
Dim ie As InternetExplorer
Dim Doc As IHTMLDocument
Dim xcolElements As IHTMLElementCollection
Dim ell As IHTMLElement
Dim pn As Integer
j = 1
Set ie = CreateObject("InternetExplorer.Application")
For pn = 1 To 10
ie.Visible = True
ie.Navigate "http://www.foxtons.co.uk/search?current_page=" & pn & "&location_ids=288&search_form=map&search_type=SS&sold=1&submit_type=search"
Do
DoEvents
Loop Until Not ie.Busy And ie.readyState = READYSTATE_COMPLETE
Set Doc = ie.Document
'Set xcolElements = Doc.getElementsByClassName("description")
'Here lies the problem. Description works perflectly, price doesn't
Set xcolElements = Doc.getElementsByClassName("price")
For Each ell In xcolElements
On Error GoTo Skip
Range("B" & j).Value = ell.Children(0).Children(1).innerText
j = j + 1
Skip:
Next ell
On Error Goto 0
Next pn
ie.Quit
Set el = Nothing
Set xcolElements = Nothing
Set Doc = Nothing
Set ie = Nothing
End Sub
Good luck finding your new home :)