使用vba从多个站点刮取数据

时间:2017-02-14 13:45:40

标签: vba web-scraping

我编写了一个代码,通过谷歌使用vba解析来自多个站点的数据。无论搜索是什么,它都可以刮掉标签元素[“h3”和“a”]。但是,如果我期待的是可能的话,我想解析任何搜索的名称或电话号码。在此先感谢您的帮助。

Sub GoogleSearch()
Dim http As New MSXML2.XMLHTTP60, html As New HTMLDocument, hmm As New HTMLDocument
Dim topics As Object, post As Object, link As Object, posts As Object
Dim url As String, z As String
Dim i As Long, LRow As Long

LRow = Range("A" & Rows.Count).End(xlUp).Row

For i = 3 To LRow
url = "https://www.google.co.in/search?q=" & Cells(i, 1)

http.Open "GET", url, False
http.setRequestHeader "Content-Type", "text/xml"
http.send

html.body.innerHTML = http.responseText

Set topics = html.getElementById("rso")
Set post = topics.getElementsByTagName("H3")(0)
Set link = post.getElementsByTagName("a")(0)

Cells(i, 2) = link.innerText
Cells(i, 3) = link.href
z = link.href
    http.Open "GET", z, False
    http.send
    hmm.body.innerHTML = http.responseText
    Set posts = hmm.getElementsByClassName("phone")
    If Not posts(0) Is Nothing Then
        Cells(i, 4) = posts(0).innerText
    Else    
        Cells(i, 4).Value = "Phone Not Found"
    End If
Next i
End Sub

1 个答案:

答案 0 :(得分:1)

  

我已经编写了一个代码来使用谷歌解析来自多个网站的数据。

不完全是。你所写的是非常具体和不灵活的代码,需要有一个"手机"类,否则会出错。执行此操作http.Open "GET", z, False后,您将导航到新网站,并且没有理由相信Yellopages和麦当劳甚至可以远程共享相同的结构。在这一点上,你所做的只是不够灵活,无法处理(不同)网站可能采取的无限结构:

http.send
hmm.body.innerHTML = http.responseText
Set posts = hmm.getElementsByClassName("phone")
Cells(i, 4) = posts(0).innerText

当你Set posts = hmm...假设必须一个具有ClassName =" phone"的元素时在每个网站上。如果没有这样的元素,则会出现错误(需要对象)。

为了获得任何元素,你需要了解一些你正在抓取的网站结构,但有几种方法可以做到:

  1. 您可以使用对getElementsByTagNamegetElementsByClassName(您目前正在做的)的索引来电,但这需要您知道标记名称或类名
  2. 如果您的条件被发现,则在getElementsByTagName返回Exit For返回的集合时匹配某些条件
  3. 如果您的浏览器支持,则可以使用getElementByID(如果ID标记可用,则为唯一标识符)
  4. 如果已知,您可以为元素提供xpath标识符。
  5. 您可以尝试摄取整个结果并使用正则表达式从纯HTML源中提取电话号码,在这种情况下这可能是最可靠的。
  6. 如果您提供正在解析的网页的示例源代码,则可能更容易为您提供特定帮助,但是,由于您显然正在尝试抓取各种网站,因此不太可能获得单一解决方案。

    我可能会做什么,跟进你的评论是这样的:

        http.Open "GET", z, False
        http.send
        hmm.body.innerHTML = http.responseText
    
        Set posts = hmm.getElementsByClassName("phone")
        If posts Is Nothing Then'# This condition is True if no "phone" element exist
            cells(1,4).Value = "phone not found at " & z
        Else
            Cells(i, 4) = posts(0).innerText
        End If
    
    Next i
    

    这至少会运行而不会出错,它会识别不包含"电话的网址"类。然后,您可以检查这些网页的源HTML,并修改代码以处理其他情况。

    您可以尝试摄取整个结果并使用正则表达式从纯HTML源中提取电话号码,在这种情况下这可能是最可靠的。