Html 如何从谷歌地图中获取地址信息?

Html 如何从谷歌地图中获取地址信息?,html,excel,vba,web-scraping,Html,Excel,Vba,Web Scraping,我试图创建一个宏,从Excel中提取地址列表,并将每个地址输入到GoogleMaps中 Sub AddressLookup() Application.ScreenUpdating = False For i = 1 To Sheet1.Cells(Rows.Count, 1).End(xlUp).Row Dim IE As InternetExplorer Dim itemELE As Object Dim address As String Dim c

我试图创建一个宏,从Excel中提取地址列表,并将每个地址输入到GoogleMaps中

Sub AddressLookup() 

Application.ScreenUpdating = False

For i = 1 To Sheet1.Cells(Rows.Count, 1).End(xlUp).Row

    Dim IE As InternetExplorer
    Dim itemELE As Object
    Dim address As String
    Dim city As String
    Dim country As String

    Set IE = New InternetExplorer
    IE.Visible = True
    IE.navigate "https://www.google.com/maps"

    Do
        DoEvents
    Loop Until IE.readyState = READYSTATE_COMPLETE

    Dim Search As MSHTML.HTMLDocument
    Set Search = IE.document

    Search.all.q.Value = Cells(i, 1).Value

    Dim ele As MSHTML.IHTMLElement
    Dim eles As MSHTML.IHTMLElementCollection

    Set eles = Search.getElementsByTagName("button")

    For Each ele In eles

            If ele.ID = "searchbox-searchbutton" Then
                ele.click
        Else
        End If

    Next ele

    For Each itemELE In IE.document.getElementsByClassName("widget-pane widget-pane-visible")
        address = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h1")(0).innerText
        city = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h2")(0).innerText
        country = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h2")(1).innerText

    Next

    Cells(i, 2).Value = Trim(address)
    Cells(i, 3).Value = Trim(city)
    Cells(i, 4).Value = Trim(country)

    MsgBox country

Next

Application.ScreenUpdating = True

End Sub
然后,它将谷歌地图中的地址行、城市/邮政编码和国家/地区重新拉回到Excel中

它可以从谷歌地图中获取信息

Sub AddressLookup() 

Application.ScreenUpdating = False

For i = 1 To Sheet1.Cells(Rows.Count, 1).End(xlUp).Row

    Dim IE As InternetExplorer
    Dim itemELE As Object
    Dim address As String
    Dim city As String
    Dim country As String

    Set IE = New InternetExplorer
    IE.Visible = True
    IE.navigate "https://www.google.com/maps"

    Do
        DoEvents
    Loop Until IE.readyState = READYSTATE_COMPLETE

    Dim Search As MSHTML.HTMLDocument
    Set Search = IE.document

    Search.all.q.Value = Cells(i, 1).Value

    Dim ele As MSHTML.IHTMLElement
    Dim eles As MSHTML.IHTMLElementCollection

    Set eles = Search.getElementsByTagName("button")

    For Each ele In eles

            If ele.ID = "searchbox-searchbutton" Then
                ele.click
        Else
        End If

    Next ele

    For Each itemELE In IE.document.getElementsByClassName("widget-pane widget-pane-visible")
        address = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h1")(0).innerText
        city = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h2")(0).innerText
        country = itemELE.getElementsByClassName("section-hero-header-description")(0).getElementsByTagName("h2")(1).innerText

    Next

    Cells(i, 2).Value = Trim(address)
    Cells(i, 3).Value = Trim(city)
    Cells(i, 4).Value = Trim(country)

    MsgBox country

Next

Application.ScreenUpdating = True

End Sub

在运行您的代码并检查Google的地址搜索结果后,我能够通过引用section hero header subtitle类中的span标记检索整个地址块“City,Province Postal_code”

在不对代码进行任何其他更改的情况下,在For-Each循环上方添加以下行(循环通过小部件窗格可见类),并使用F8逐步遍历代码

Debug.Print IE.Document.getElementsByClassName("section-hero-header-subtitle")(0).getElementsByTagName("span")(0).innerText

在运行您的代码并检查Google的地址搜索结果后,我能够通过引用section hero header subtitle类中的span标记检索整个地址块“City,Province Postal_code”

在不对代码进行任何其他更改的情况下,在For-Each循环上方添加以下行(循环通过小部件窗格可见类),并使用F8逐步遍历代码

Debug.Print IE.Document.getElementsByClassName("section-hero-header-subtitle")(0).getElementsByTagName("span")(0).innerText

地理编码API不再是“免费”的,尽管我实际上相信,如果您保持在某个阈值内,那么通过设置计费帐户,您可以免费获取。作为一个新版本(maps/API已经更新),我认为期望这些API与实际的maps结合使用(但不要引用我的话)

请注意以下事项:

1) 正确等待页面加载
之后的。单击

While ie.Busy Or ie.readyState < 4: DoEvents: Wend

在选择器方面-

商业地址:

.section-info-line span.widget-pane-link
以及OP re的反馈:住宅:

.section-hero-header div.section-hero-header-description

地理编码API不再是“免费”的,尽管我实际上相信,如果您保持在某个阈值内,那么通过设置计费帐户,您可以免费获取。作为一个新版本(maps/API已经更新),我认为期望这些API与实际的maps结合使用(但不要引用我的话)

请注意以下事项:

1) 正确等待页面加载
之后的。单击

While ie.Busy Or ie.readyState < 4: DoEvents: Wend

在选择器方面-

商业地址:

.section-info-line span.widget-pane-link
以及OP re的反馈:住宅:

.section-hero-header div.section-hero-header-description
此答案将与WebRequest一起使用

与使用
Internet Explorer进行抓取相反,这是为此目的而设计的(更快、更可靠、更多信息)。这也可以用实现,但您需要一个API密钥并跟踪成本

如果你使用尊重他们,但最好有自己的安装

Public Function GeocodeRequestNominatim(ByVal sAddress As String) As Dictionary
    Dim Client As New WebClient
    Client.BaseUrl = "https://nominatim.openstreetmap.org/"

    Dim Request As New WebRequest
    Dim Response As WebResponse
    Dim address As Dictionary

    With Request
        .Resource = "search/"
        .AddQuerystringParam "q", sAddress
        .AddQuerystringParam "format", "json"
        .AddQuerystringParam "polygon", "1"
        .AddQuerystringParam "addressdetails", "1"
    End With
    Set Response = Client.Execute(Request)
    If Response.StatusCode = WebStatusCode.Ok Then
       Set address = Response.Data(1)("address")
       Set GeocodeRequestNominatim = address

       'Dim Part As Variant
       'For Each Part In address.Items
       '    Debug.Print Part
       'Next Part

    Else
      Debug.Print "Error: " & Response.StatusCode & " - " & Response.Content
    End If
End Function
示例(打印国家/地区,对于其他字段,请查看提名网站示例中返回的JSON字符串):

此答案将与WebRequest一起使用

与使用
Internet Explorer进行抓取相反,这是为此目的而设计的(更快、更可靠、更多信息)。这也可以用实现,但您需要一个API密钥并跟踪成本

如果你使用尊重他们,但最好有自己的安装

Public Function GeocodeRequestNominatim(ByVal sAddress As String) As Dictionary
    Dim Client As New WebClient
    Client.BaseUrl = "https://nominatim.openstreetmap.org/"

    Dim Request As New WebRequest
    Dim Response As WebResponse
    Dim address As Dictionary

    With Request
        .Resource = "search/"
        .AddQuerystringParam "q", sAddress
        .AddQuerystringParam "format", "json"
        .AddQuerystringParam "polygon", "1"
        .AddQuerystringParam "addressdetails", "1"
    End With
    Set Response = Client.Execute(Request)
    If Response.StatusCode = WebStatusCode.Ok Then
       Set address = Response.Data(1)("address")
       Set GeocodeRequestNominatim = address

       'Dim Part As Variant
       'For Each Part In address.Items
       '    Debug.Print Part
       'Next Part

    Else
      Debug.Print "Error: " & Response.StatusCode & " - " & Response.Content
    End If
End Function
示例(打印国家/地区,对于其他字段,请查看提名网站示例中返回的JSON字符串):



也许用谷歌的地图API来代替?一定要用谷歌的,而不是缓慢和不可靠的(丑陋的)刮擦。我以前从未使用过API,所以我甚至不知道从哪里开始查看我上面的链接,但我注意到他们改变了使用条款。不知道现在什么是免费的。您可以使用发送请求和解析响应。作为免费的替代方案(但请尊重),您可以使用开放式街道地图。对于大量使用,请安装您自己的OSM。也许我以后会创建一个VBA Web示例作为答案。你应该提供测试输入和预期输出。也许可以使用谷歌的Map API来代替?一定要使用谷歌的,而不是缓慢和不可靠(丑陋)的刮擦。我以前从未使用过API,所以我甚至不知道从哪里开始查看上面的链接,但我注意到他们改变了使用条款。不知道现在什么是免费的。您可以使用发送请求和解析响应。作为免费的替代方案(但请尊重),您可以使用开放式街道地图。对于大量使用,请安装您自己的OSM。也许我以后会创建一个VBA Web示例或作为答案。您应该提供测试输入和预期输出。由于某种原因,我仍然无法使其工作-您是否更改了其他内容?由于某种原因,我仍然无法使其工作-您是否更改了其他内容?@SIM谢谢。我仍然认为它可以改进。我曾尝试使用一个我认为可以使用的选择器,但老实说,我没有使用过很多测试用例。你可以在URL中传递查询,跳过“插入查询”和“单击”。看@ComputerVersteher是的,我想是的。谢谢!这太棒了!但是,当它从电子表格中获取一个值时,我似乎无法让它工作。例如,如果我拉取值A1(即值为21 Bay St Toronto),它将不会完全加载,因此不会将该值拉入电子表格。有什么想法吗?示例:.querySelector(“#searchboxinput”).Value=Sheet1.Range(“A1”).ValueHey,我实际上基本上解决了这个问题-看起来不是所有地址都能使用“.section信息行span.widget窗格链接”,所以我不得不使用“.section hero header div.section-hero-header-description”。商业地址似乎适用于你的版本,但不适用于普通的街道地址(这正是我试图找到的)@SIM谢谢。我仍然认为它可以改进。我曾尝试使用一个我认为可以使用的选择器,但老实说,我没有使用过很多测试用例。你可以在URL中传递查询,跳过“插入查询”和“单击”。看@ComputerVersteher是的,我想是的。谢谢!这太棒了!但是,当它从电子表格中获取一个值时,我似乎无法让它工作。例如,如果我拉取值A1(即值为21 Bay St Toronto),它将不会完全加载,因此不会将该值拉入电子表格。有什么想法吗?考试