Как использовать макрос Excel для очистки первого столбца класса Table, вложенного в Div id - PullRequest
0 голосов
/ 08 ноября 2018

Хорошо, это целевые веб-страницы: http://dnd.arkalseif.info/items/index.html_page=27

Вот мой текущий код:

Sub GetItemsList()
' This macro uses manually entered links to scrap the content of the target page.
' It does not (yet) capture hyperlinks, it only grabs text.
Dim ie As Object
Dim retStr As String
Dim sht As Worksheet
Dim LastRow As Long
Dim rCell As Range
Dim rRng As Range
Dim Count As Long
Dim Status As String
Dim BadCount As Long


Set sht = ThisWorkbook.Worksheets("List")
BadCount = 0

LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
    Set ie = CreateObject("internetexplorer.application")
    Set rRng = sht.Range("b1:b" & LastRow)
    Status = "Starting at row "
    For Each rCell In rRng.Cells
        Count = rCell.Row
        Application.StatusBar = BadCount & " dead links so far. " & Status & Count & "of " & LastRow & "."
        Wait 1
        If rCell = "" Then
            With ie
                .Navigate rCell.Offset(0, -1).Value
                .Visible = False
            End With
            Do While ie.Busy
                DoEvents
            Loop
            Wait 1

            On Error GoTo ErrHandler
'            rCell.Value = ie.Document.getElementById("content").innerText
            rCell.Value = ie.Document.getElementsByClassName("common").innerText
            rCell.WrapText = False
            Status = "This row successfully scraped. Moving on to row "
            Application.StatusBar = BadCount & " dead links so far. " & Status & Count + 1 & "of " & LastRow & "."
            Status = "Previous row succeded. Now at row "
98            Wait 1
        End If
    Next rCell
    If BadCount > 0 Then
        Application.StatusBar = "Macro finshed running with " & BadCount & " errors."
        Else
        Application.StatusBar = "Finished."
    End If
    Exit Sub
ErrHandler:
    rCell.Value = ""
    Status = "Previous row failed. Moving on to row "
    BadCount = BadCount + 1
    Application.StatusBar = "This row is a dead link. " & BadCount & " dead links so far. Moving on to row " & Count + 1 & "of " & LastRow & "."
    Resume 98
End Sub

(попробуйте игнорировать все мои обновления StatusBar, этот код изначально предназначался для более длинного списка гиперссылок, и мне нужно было (в то время) знать, когда что-то не так)

Теперь закомментированная строка работает, так как она захватывает все тело текста из div id Content . Но я хочу получить гиперссылки, расположенные внутри первого столбца таблицы, который вложен в div id (для этого и была следующая строка). Но это просто не удается. Excel ничего не делает, обрабатывает это как ошибку и переходит к следующей ссылке.

Я предполагаю, что мне нужно сказать Excel, чтобы он искал Table class внутри Div id. Но я не знаю, как это сделать, и я не смог понять это.

Спасибо всем.

1 Ответ

0 голосов
/ 08 ноября 2018

Я бы использовал селекторы CSS для таргетинга ссылок и XMLHTTP в качестве более быстрого метода поиска, чем запуск браузера.


Селекторы CSS:

Следующее:

td:first-child [href]

td: first-child - это :first-child селектор псевдокласса CSS из td тегового элемента; " " - селектор комбинатора , [] - селектор атрибута . По сути, он выбирает первый элемент td в каждой строке в этом случае, то есть первый столбец, а затем элемент атрибута href внутри.

CSS-псевдокласс: first-child представляет первый элемент среди группа родственных элементов.

К сожалению, реализация VBA не поддерживает селектор :not, поскольку точные элементы также могут совпадать с .common tr + tr td :not([href*='rule'],br). Поддержка псевдо-селекторов очень ограничена. В этом случае использование селектора псевдокласса :nth-child() CSS td:nth-child(1) позволило бы получить определенные элементы, если бы они поддерживались в комбинации потомков как td:nth-child(1) [href]. Я продолжаю писать о том, что есть и что не поддерживается, если кто-то захочет в качестве ссылки. Полезно знать о даже не поддерживаемых VBA методах, если вы решили переключиться на язык, который поддерживает.

Селектор применяется с помощью метода querySelectorAll, в данном случае HTMLDocument. Он возвращает все совпадения в виде nodeList, чей .Length может быть пройден для доступа к отдельным сопоставленным элементам по индексу.

элементы списка узлов:

enter image description here


Option Explicit
Public Sub GetLinks()
    Dim sResponse As String, html As HTMLDocument, nodeList As Object, i As Long
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "http://dnd.arkalseif.info/items/index.html_page=27", False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
    End With
    Set html = New HTMLDocument
    With html
        .body.innerHTML = sResponse
        Set nodeList = .querySelectorAll("td:first-child [href]")
        For i = 0 To nodeList.Length - 1
            Debug.Print Replace$(nodeList.item(i), "about:", "http://dnd.arkalseif.info/items/")
        Next
    End With
End Sub

Ссылки (VBE> Инструменты> Ссылки):

  1. Библиотека объектов Microsoft HTML
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...