【问题标题】:Webscrape VBA - ListWeb Scraper VBA - 列表
【发布时间】:2021-02-01 22:35:03
【问题描述】:

我正在尝试设置一个网页抓取 VBA 代码以将数据从该网站导入 Excel:https://www.thewindpower.net/windfarms_list_en.php

我希望启动这个网页,选择一个国家,然后从下表中抓取数据(包括名称列中的 url)。

然而,我有几个问题:

  • 如何在 VBA 代码中选择我希望的国家/地区?
  • 标签中没有id或class,如何选择表格?
  • 如何导入名称列中包含的 URL?

这是我已经准备好的代码(基于网络上的一些研究:

Sub Grabdata()

'dimension (set aside memory for) our variables
Dim objIE As InternetExplorer
Dim ele As Object
Dim y As Integer

'start a new browser instance
Set objIE = New InternetExplorer
'make browser visible
objIE.Visible = True

'navigate to page with needed data
objIE.navigate "https://www.thewindpower.net/windfarms_list_en.php"
'wait for page to load
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop

'we will output data to excel, starting on row 1
y = 1

'look at all the 'tr' elements in the 'table' with id 'myTable',
'and evaluate each, one at a time, using 'ele' variable
For Each ele In objIE.document.getElementById("myTable").getElementsByTagName("tr")
    'show the text content of 'tr' element being looked at
    Debug.Print ele.textContent
    'each 'tr' (table row) element contains 4 children ('td') elements
    'put text of 1st 'td' in col A
    Sheets("Sheet1").Range("A" & y).Value = ele.Children(0).textContent
    'put text of 2nd 'td' in col B
    Sheets("Sheet1").Range("B" & y).Value = ele.Children(1).textContent
    'put text of 3rd 'td' in col C
    Sheets("Sheet1").Range("C" & y).Value = ele.Children(2).textContent
    'put text of 4th 'td' in col D
    Sheets("Sheet1").Range("D" & y).Value = ele.Children(3).textContent
    'increment row counter by 1
    y = y + 1
'repeat until last ele has been evaluated
Next

'save the Excel workbook
ActiveWorkbook.Save

结束子

【问题讨论】:

  • 你会怎么做选择表?您愿意从该表中获取内容吗?你不需要IE。您只需发送一个 post http 请求以及适当的参数来填充表格。
  • 我想根据我选择的国家/地区获取所有表格(例如英国)。在获得此表(名称列中包含 URL)后,我希望通过访问名称上的每个 URL 并从那里获取一些数据,为表的每一行运行另一个宏

标签: excel vba web-scraping


【解决方案1】:

大多数可抓取页面几乎总是具有静态页面布局,因此使用它们的索引选择元素是相当安全的。

下面的代码选择id为bloc_texte的容器元素,然后选择里面的第二个表。

如果您打算按照您的评论建议执行大量请求,则应添加一些代码以减慢您的请求(Application.wait 类型交易)。一个又一个请求触发可能会惹恼主机。

' Required References
' Microsoft HTML Object Library
' Microsoft XML, v6.0

Sub Main()
    GetData ("GB")
End Sub

Sub GetData(ByVal Location As String)

Dim Request As MSXML2.ServerXMLHTTP60: Set Request = New MSXML2.ServerXMLHTTP60

Dim Result As HTMLDocument: Set Result = New HTMLDocument

Request.Open "POST", "https://www.thewindpower.net/windfarms_list_en.php", False
Request.setRequestHeader "content-type", "application/x-www-form-urlencoded"
Request.send "action=submit&pays=" & Location

Result.body.innerHTML = Request.responseText

Dim oRows As MSHTML.IHTMLElementCollection
Dim oRow As MSHTML.IHTMLElement

Dim oCells As MSHTML.IHTMLElementCollection
Dim oCell As MSHTML.IHTMLElement

Dim oLinks As MSHTML.IHTMLElementCollection

Set oRows = Result.getElementById("bloc_texte").getElementsByTagName("table")(2).getElementsByTagName("tr")

Dim iRow As Integer 'output row counter
Dim iColumn As Integer 'output column counter
Dim Sheet As Worksheet 'output sheet

Set Sheet = ThisWorkbook.Worksheets("Sheet1")
iRow = 1
iColumn = 1

For Each oRow In oRows
    If Not oRow.className = "puce_texte" Then
        Set oCells = oRow.getElementsByTagName("td")
        For Each oCell In oCells
            Set oLinks = oCell.getElementsByTagName("a")
            If oLinks.Length = 0 Then
                Sheet.Cells(iRow, iColumn).Value = oCell.innerText
            Else
                Sheet.Cells(iRow, iColumn).Value = Replace(oLinks(0).getAttribute("href"), "about:", "")
            End If
            iColumn = iColumn + 1
        Next oCell
        iRow = iRow + 1
        iColumn = 1
    End If
Next oRow

End Sub

【讨论】:

  • 非常感谢您的回答尼克!我仍然遇到以下行“Dim Request As MSXML2.ServerXMLHTTP60: Set Request = New MSXML2.ServerXMLHTTP60”的问题我收到一条错误消息“未定义用户类型”,你知道为什么吗?
  • 您需要添加引用。在 VBA Editor -> Tools -> References 中选择代码块顶部显示的两项。
  • 非常感谢,它完美运行!我开始处理我的报废的第二部分(逐页部分)!
  • 您有什么资源可以让我在您使用索引选择时学习它吗?我已经陷入流程的第二部分,我认为这对我有很大帮助!
  • 我只使用 Chrome 开发工具。找到最近的具有 id 的容器元素,计算在您需要的元素之前出现的任何元素的数量。您还可以选择目标元素(表格)并打开上下文菜单(复制->复制 XPath),这通常会为您提供定位数据所需的所有信息。例如//*[@id="bloc_texte"]/table[2] -> id 为 bloc_texte 的元素,子表编号为 2
猜你喜欢
  • 2021-10-19
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2021-10-29
  • 2015-03-20
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
相关资源
最近更新 更多