Очистка URL сайта с первого результата поиска - PullRequest
0 голосов
/ 12 марта 2020

В настоящее время я работаю над проектом Excel, использующим код VBA для автоматизации того, что в противном случае было бы почти невозможным ручным заданием. У меня есть таблица из примерно 25 000 ключевых слов компании, из которой я хотел бы получить URL веб-сайта компании. Поэтому я хочу запустить скрипт VBA, который может запускать эти ключевые слова как поиск в Google, и перетащить URL-адрес первого результата в электронную таблицу. Я хотел бы заявить, что я очень новичок в использовании такого кода, поэтому, возможно, я упускаю из виду нечто, кажущееся простым для других.

Я протестировал код, найденный в похожая тема , но обнаружил, что результаты этого очень удачные; некоторые ключевые слова возвращали бы URL в следующем столбце, тогда как другие оставались бы пустыми. Похоже, он также извлекает URL-адрес оптимизированных вложенных ссылок Google в первом результате поиска, а не URL основного веб-сайта (см. Ссылку ниже):

Пример результата поиска Google

Затем я нашел следующий код здесь , который я запустил в примерном списке из 1000 ключевых слов. Автор этого блога утверждает, что этот код работает для Mozilla Firefox. Я протестировал код IE, который он также написал, но это не дало тех же результатов (это было добавление гиперссылок, состоящих из описательного текста из результатов поиска, а не из необработанного URL). Код Firefox (я вставил этот код для справки) работал без сбоев до 714-й строки, где макрос вернул сообщение об ошибке « Ошибка времени выполнения 91: переменная объекта или переменная блока не установлена . на данный момент и как я могу настроить этот код, чтобы избежать ошибок в будущем.

Sub GoogleURL ()

    Dim url As String, lastRow As Long

    Dim XMLHTTP As Object

    Dim html As Object

    Dim objResultDiv As Object

    Dim objH As Object

    lastRow = Range(“A” & Rows.Count).End(xlUp).Row

    For i = 2 To lastRow

        url = “https://www.google.co.uk/search?q=” & Cells(i, 1) & “&rnd=” & WorksheetFunction.RandBetween(1, 10000)

        Set XMLHTTP = CreateObject(“MSXML2.serverXMLHTTP”)

        XMLHTTP.Open “GET”, url, False

        XMLHTTP.setRequestHeader “Content-Type”, “text/xml”

        XMLHTTP.setRequestHeader “User-Agent”, “Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0”

        XMLHTTP.send

        Set html = CreateObject(“htmlfile”)

        html.body.innerHTML = XMLHTTP.ResponseText

        Set objResultDiv = html.getelementbyid(“rso”)

        Set objH = objResultDiv.getelementsbytagname(“h3”)(0)

        Cells(i, 2).Value = objH.innerText

        Set html = CreateObject(“htmlfile”)

        html.body.innerHTML = XMLHTTP.ResponseText

        Set objResultDiv = html.getelementbyid(“rso”)

        Set objH = objResultDiv.getelementsbytagname(“cite”)(0)

        Cells(i, 3).Value = objH.innerText

        DoEvents

    Next

End Sub

1 Ответ

1 голос
/ 13 марта 2020

Поскольку Firefox является сторонним браузером для поддержки Microsoft, я могу помочь вам проверить код VBA для браузера IE.

Вы сказали, что код VBA указан в эта ссылка для браузера IE создает описание со ссылкой, и вы должны сохранить описание и ссылку в отдельном столбце.

Я попытался изменить этот пример кода в соответствии с вашим требованием .

Вот модифицированный код из этого примера.

Option Explicit
Const TargetItemsQty = 1 ' results for each keyword

Sub GWebSearchIECtl()

    Dim objSheet As Worksheet
    Dim objIE As Object
    Dim x As Long
    Dim y As Long
    Dim strSearch As String
    Dim lngFound As Long
    Dim st As String
    Dim colGItems As Object
    Dim varGItem As Variant
    Dim strHLink As String
    Dim strDescr As String
    Dim strNextURL As String

    Set objSheet = Sheets("Sheet1")
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True ' for debug or captcha request cases
    y = 1 ' start searching for the keyword in the first row
    With objSheet
        .Select
        .Range(.Columns("B:B"), .Columns("B:B").End(xlToRight)).Delete ' clear previous results
        .Range(.Columns("C:C"), .Columns("C:C").End(xlToRight)).Delete ' clear previous results
        .Range("A1").Select
        Do Until .Cells(y, 1) = ""
            x = 2 ' start writing results from column B
            .Cells(y, 1).Select
            strSearch = .Cells(y, 1) ' current keyword
            With objIE
                lngFound = 0
                .navigate "https://www.google.com/search?q=" & EncodeUriComponent(strSearch) ' go to first search results page
                Do
                    Do While .Busy Or Not .READYSTATE = 4: DoEvents: Loop ' wait IE
                    Do Until .document.READYSTATE = "complete": DoEvents: Loop ' wait document
                    Do While TypeName(.document.getelementbyid("res")) = "Null": DoEvents: Loop ' wait [#res] element
                    Set colGItems = .document.getelementbyid("res").getElementsByClassName("g") ' collection of search result [.g] items
                    For Each varGItem In colGItems ' process each item in collection
                        If varGItem.getelementsbytagname("a").Length > 0 And varGItem.getElementsByClassName("st").Length > 0 Then ' must have hyperlink and description
                            strHLink = varGItem.getelementsbytagname("a")(0).href ' get first hyperlink [a] found in current item
                            strDescr = GetInnerText(varGItem.getElementsByClassName("st")(0).innerHTML) ' get first description [span.st] found in current item
                            lngFound = lngFound + 1
                            'Debug.Print (strHLink)
                            'Debug.Print (strDescr)
                            With objSheet ' put result into cell
                                 .Cells(y, x).Value = strDescr
                                 .Hyperlinks.Add .Cells(y, x + 1), strHLink
                                .Cells(y, x).WrapText = True
                                x = x + 1 ' next column
                            End With
                            If lngFound = TargetItemsQty Then Exit Do ' continue with next keyword - necessary quantity of the results for current keyword found
                        End If
                        DoEvents
                    Next
                    If TypeName(.document.getelementbyid("pnnext")) = "Null" Then Exit Do ' continue with next keyword - no [a#pnnext.pn] next page button exists
                    strNextURL = .document.getelementbyid("pnnext").href ' get next page url
                    .navigate strNextURL ' go to next search results page
                Loop
            End With
            y = y + 1 ' next row
        Loop
    End With
    objIE.Quit

    ' google web search page contains the elements:
    ' [div#res] - main search results block
    ' [div.g] - each result item block within [div#res]
    ' [a] - hyperlink ancor(s) within each [div.g]
    ' [span.st] - description(s) within each [div.g]
    ' [a#pnnext.pn] - hyperlink ancor to the next search results page

End Sub

Function EncodeUriComponent(strText As String) As String
    Static objHtmlfile As Object

    If objHtmlfile Is Nothing Then
        Set objHtmlfile = CreateObject("htmlfile")
        objHtmlfile.parentWindow.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript"
    End If
    EncodeUriComponent = objHtmlfile.parentWindow.encode(strText)
End Function

Function GetInnerText(strText As String) As String
    Static objHtmlfile As Object

    If objHtmlfile Is Nothing Then
        Set objHtmlfile = CreateObject("htmlfile")
        objHtmlfile.Open
        objHtmlfile.Write "<body></body>"
    End If
    objHtmlfile.body.innerHTML = strText
    GetInnerText = objHtmlfile.body.innerText
End Function

Вывод в браузере IE 11:

enter image description here

Вы можете попробовать запустить его на своей стороне, чтобы увидеть результаты с большим объемом данных.

Если у вас возникнут какие-либо проблемы с производительностью, я предлагаю вам попробовать его с меньшим объемом данных.

...