Excel 用VBA从气象网站中提取数据

Excel 用VBA从气象网站中提取数据,excel,vba,web-scraping,Excel,Vba,Web Scraping,我正试图从天气预报表上复制特定数据。更确切地说,我正试图从一个类似的链接以表格格式(但现在任何格式都可以)获取Excel中的时间和云量。到目前为止,我已经尝试了很多方法来获取这些特定的数据,但我还是做不到(我对使用VBA进行网页抓取还不熟悉)。这些概念和命令对我来说非常清楚,它们也适用于其他网站,但对于这个网站,我束手无策。目前,我正在使用: Sub WeatherScrap() Range("A1").Select Dim mainlink As String Dim http As Ne

我正试图从天气预报表上复制特定数据。更确切地说,我正试图从一个类似的链接以表格格式(但现在任何格式都可以)获取Excel中的时间和云量。到目前为止,我已经尝试了很多方法来获取这些特定的数据,但我还是做不到(我对使用VBA进行网页抓取还不熟悉)。这些概念和命令对我来说非常清楚,它们也适用于其他网站,但对于这个网站,我束手无策。目前,我正在使用:

Sub WeatherScrap()

Range("A1").Select

Dim mainlink As String Dim http As New XMLHTTP60, html As New HTMLDocument Dim CloudCover As Object

mainlink = "https://www.wunderground.com/hourly/ro/mizil/45.00,26.44/date/2020-04-15"

    With http
        .Open "GET", mainlink, False
        .send
        html.body.innerHTML = .responseText
    End With

    For Each CloudCover In html.getElementsByClassName("wu-value wu-value-to")
        ActiveCell.Value = CloudCover.innerText
        ActiveCell.Offset(1, 0).Select
    Next CloudCover

End Sub
我显然没有在html上引用正确的类、标记或ID(到目前为止,我已经尝试了很多,但没有一个检索到所需的数据)。网站上的html元素是:

<lib-display-unit _ngcontent-app-root-c213="" _nghost-app-root-c122="" class="ng-star-inserted"><span _ngcontent-app-root-c122="" class="test- wu-unit wu-unit-chance ng-star-inserted"><!----><!----><!----><span _ngcontent-app-root-c122="" class="wu-value wu-value-to">100</span>&nbsp;<span _ngcontent-app-root-c122="" class="wu-label"><span _ngcontent-app-root-c122="" class="ng-star-inserted">%</span>
100%

目前,只要了解如何从表中获取云覆盖率就足够了。有人能帮忙吗?非常感谢

我没有读你的全部问题,但我猜你想要这样的东西(这是与基于web的表交互的一种非常常见的方式)

结果:


我没有读你的全部问题,但我猜你想要这样的东西(这是与基于web的表交互的一种非常常见的方式)

结果:


看起来不错,您是否检查了您的
http.responseText
是否确实包含您期望的HTML,而不是一些重定向或CloudFlare验证码页面或类似的内容?再次看,您将HTML字符串指定给
HTMLDocument
的正文内容看起来很奇怪。如果你知道我的意思,你最终会得到这样一个文档,
,我不确定这是否正确处理。您不能直接使用
CreateDocumentFromUrl
,或者至少将
写入到文档中,而不是分配
InnerHTML
?为什么不尝试使用Power Query链接?@CherryDT这不是问题所在。提供的网站使用JavaScript API获取其显示的天气信息。如果需要,您也必须使用此API。例如,或者可能取决于需要哪些信息。一般来说,虽然您应该获得自己的API密钥……好吧,对了,我没有查看相关页面,我假设OP知道他们在处理什么HTML。谢谢,这是正确的方法。您是否检查了您的
http.responseText
是否确实包含您期望的HTML,而不是一些重定向或CloudFlare验证码页面或类似的内容?乍一看,将HTML字符串指定给
HTMLDocument
的正文内容看起来很奇怪。如果你知道我的意思,你最终会得到这样一个文档,
,我不确定这是否正确处理。您不能直接使用
CreateDocumentFromUrl
,或者至少将
写入到文档中,而不是分配
InnerHTML
?为什么不尝试使用Power Query链接?@CherryDT这不是问题所在。提供的网站使用JavaScript API获取其显示的天气信息。如果需要,您也必须使用此API。例如,或者可能取决于需要哪些信息。一般来说,虽然您应该获得自己的API密钥……好吧,对了,我没有查看相关页面,我假设OP知道他们在处理什么HTML。谢谢你,这是去的方式-非常感谢!我不得不增加等待时间,因为java脚本加载速度变慢了。谢谢!直到objIE.ReadyState=4,而不是objIE.Busy应该自动处理。也许当你试着运行它时,有些东西被弄坏了。不管怎样,我很高兴我没能为你工作非常感谢!我不得不增加等待时间,因为java脚本加载速度变慢了。谢谢!直到objIE.ReadyState=4,而不是objIE.Busy应该自动处理。也许当你试着运行它时,有些东西被弄坏了。不管怎样,我很高兴我没有为你工作!!
Sub Web_Table()
    Dim HTMLDoc As New HTMLDocument
    Dim objTable As Object
    Dim lRow As Long
    Dim lngTable As Long
    Dim lngRow As Long
    Dim lngCol As Long
    Dim ActRw As Long
    Dim objIE As InternetExplorer
    Set objIE = New InternetExplorer
    objIE.Navigate "https://www.wunderground.com/hourly/ro/mizil/45.00,26.44/date/2020-04-15"

    Do Until objIE.ReadyState = 4 And Not objIE.Busy
        DoEvents
    Loop
    Application.Wait (Now + TimeValue("0:00:03")) 'wait for java script to load
    HTMLDoc.body.innerHTML = objIE.Document.body.innerHTML
    With HTMLDoc.body
        Set objTable = .getElementsByTagName("table")
        For lngTable = 0 To objTable.Length - 1
            For lngRow = 0 To objTable(lngTable).Rows.Length - 1
                For lngCol = 0 To objTable(lngTable).Rows(lngRow).Cells.Length - 1
                    ThisWorkbook.Sheets("Sheet1").Cells(ActRw + lngRow + 1, lngCol + 1) = objTable(lngTable).Rows(lngRow).Cells(lngCol).innerText
                Next lngCol
            Next lngRow
            ActRw = ActRw + objTable(lngTable).Rows.Length + 1
        Next lngTable
    End With
    objIE.Quit
End Sub