Импорт данных с использованием JSON - PullRequest
0 голосов
/ 20 июня 2019

Я разработал код для очистки данных с веб-сайтов, но, поскольку я очень мало знаю о JSON, я смог получить желаемый результат, поэтому код был разработан для этой сети: https://ngodarpan.gov.in/index.php/home/statewise_ngo/76/35/1 теперь я я копирую свой код для других сайтов, имеющих json, как этот: https://www.yelp.com/search?cflt=hvac&find_loc=San+Francisco%2C+CA; но этот код не работает должным образом. Вот мой код (я хочу, чтобы он был общим для большинства сетей)

Option Explicit

Public Sub FetchTabularInfo()
    Dim Http As XMLHTTP60, Html As HTMLDocument, col As Variant, csrf As Variant, i&, page As Long
    Dim headers(), ws As Worksheet, iCol As Collection

    Set ws = ThisWorkbook.Worksheets("Sheet1")
    headers = Array("SrNo", "Name", "Address", "Mobile", "Email")
    Set Http = New XMLHTTP60
    Set Html = New HTMLDocument

    ws.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers

    For page = 1 To 8 'To cover all pages

        With Http
            .Open "GET", "https://www.yelp.com/search?cflt=hvac&find_loc=San+Francisco%2C+CA" & CStr(page), Falsev 'Last letter of URL is page number whose range will be given in outerloop
            .send
            Html.body.innerHTML = .responseText
        End With
        Set iCol = New Collection
        With Html.querySelectorAll(".table tr a[onclick^='show_ngo_info']")
            For i = 0 To .Length - 1
                iCol.Add Split(Split(.Item(i).getAttribute("onclick"), "(""")(1), """)")(0)
            Next i
        End With

        Dim r As Long, results()
        ReDim results(1 To iCol.Count, 1 To UBound(headers) + 1)
        r = 0
        For Each col In iCol
            r = r + 1
            With Http
                .Open "GET", "https://www.yelp.com/index.php/ajaxcontroller/get_csrf", False
                .send
                csrf = .responseText
            End With

            csrf = Split(Replace(Split(csrf, ":")(1), """", ""), "}")(0)

            Dim json As Object
            With Http
                .Open "POST", "https://www.yelp.com/index.php/ajaxcontroller/show_ngo_info", False
                .setRequestHeader "X-Requested-With", "XMLHttpRequest"
                .setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"
                .send "id=" & col & "&csrf_test_name=" & csrf
                Set json = JsonConverter.ParseJson(.responseText)

                Dim orgName As String, address As String, srNo As Long, city As String
                Dim state As String, tel As String, mobile As String, website As String, email As String

                On Error Resume Next
                orgName = json("registeration_info")(1)("nr_orgName")
                address = json("registeration_info")(1)("nr_add")

                srNo = r                         '<unsure where this is coming from.

                mobile = json("infor")("0")("Mobile")

                email = json("infor")("0")("Email")
                On Error GoTo 0

                Dim arr()
                arr = Array(srNo, orgName, address, tel, email)
                For i = LBound(headers) To UBound(headers)
                    results(r, i + 1) = arr(i)
                Next
            End With
        Next col
        Set iCol = Nothing: Set json = Nothing
        ws.Cells(GetLastRow(ws) + 1, 1).Resize(UBound(results, 1), UBound(results, 2)) = results
    Next
End Sub

Public Function GetLastRow(ByVal sh As Worksheet) As Long
    On Error Resume Next
    GetLastRow = sh.Cells.Find(What:="*", _
                               After:=sh.Range("A1"), _
                               Lookat:=xlPart, _
                               LookIn:=xlFormulas, _
                               SearchOrder:=xlByRows, _
                               SearchDirection:=xlPrevious, _
                               MatchCase:=False).Row
    On Error GoTo 0
End Function

Пожалуйста, дайте мне знать об ошибках, которые я делаю, чтобы я позаботился о них в будущем.

1 Ответ

1 голос
/ 20 июня 2019

Краткий ответ:

Нет.

Я бы сказал, что невозможно написать что-то общее для большинства сетей .Можно сказать, что общей частью является сам синтаксический анализатор.Но вам нужно иметь некоторое представление о структуре json каждой конечной точки для правильного прямого анализа.Json сам определил структурный синтаксис / компоненты, но то, что вы хотите от них, будет иметь разные пути доступа и для этого потребуется разная обработка.Тогда есть аргументы, которые, возможно, потребуется указать, и различия в формате вывода.

Какой лучший сценарий?

Если у вас установлен список URL-адресов (в идеале - конечные точки API) у вас больше шансов написать что-то, что может длиться некоторое время, поскольку вы можете ознакомиться с возвращенным json.Но насколько это общее?Это на самом деле просто разветвленный код.

Повторно используемые вещи:

Может быть не парсером, который можно обобщать, например, создаваемые вами методы и классы, которые разбирают путидля всей структуры и искать ключевые слова и вернуть вам эти пути?Вспомогательные функции, которые вы пишете, могут рекурсивно выписывать вложенные структуры и т. Д. Код, который делает запрос и обрабатывает ошибки, и т. Д. .... Я бы определенно рекомендовал поискать классы для повторного использования кода в веб-очистке.основанные примеры:

Я добавлю к этому, как и когда

  1. https://stackoverflow.com/a/52301153/6241235
  2. https://codereview.stackexchange.com/questions/69009/vba-clickbot-featuring-ajax-waiting-and-element-searching
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...