【问题标题】:Scrape table for nested table in local html using selenium使用 selenium 在本地 html 中为嵌套表抓取表
【发布时间】:2018-12-10 19:55:20
【问题描述】:

在这个线程 [Link}(Scraping table from local HTML with unicode characters) 中,QHarr 帮助我从本地 html 文件中抓取了一个表格。 我在Link 有一个 html 文件

我使用相同的代码并对变量“startTableNumber”和“endTableNumber”以及“numColumns”进行了一些编辑

Public Sub Test()
Dim fStream  As ADODB.Stream, html As HTMLDocument
Set html = New HTMLDocument
Set fStream = New ADODB.Stream
With fStream
    .Charset = "UTF-8"
    .Open
    .LoadFromFile "C:\Users\Future\Desktop\Sample 2.html"
    html.body.innerHTML = .ReadText
    .Close
End With

Dim hTables As Object, startTableNumber As Long, i As Long, r As Long, c As Long
Dim counter As Long, endTableNumber, numColumns As Long

startTableNumber = 91
endTableNumber = 509
numColumns = 14

Set hTables = html.getElementsByTagName("table")
r = 2: c = 1

For i = startTableNumber To endTableNumber Step 2
    counter = counter + 1
    If counter = 10 Then
        c = 1: r = r + 1: counter = 1
    End If
    Cells(r, c) = hTables(i).innerText
    c = c + 1
Next

End Sub

但是我得到了表格的分散数据更多我想找到一种灵活的方法,以便让代码识别这些变量而无需手动分配它们 我希望找到使用硒的解决方案。希望也不要收到负面的代表。我已尽力澄清问题 问候

【问题讨论】:

  • 我真的在没有资格表的情况下编写了 Cells(r, c) 吗?嗯..... :-) 可能对人们有所帮助的是,有嵌套的表格标签元素,其中许多包含重复的相同内容。稍后在表格标记集合中,文本内容以通常在 td 标记中的方式出现在各个表格中,即您最终在该点将表格标记元素视为 td 写出时。
  • 别管那点我的导师..
  • 这不适用于您当前的文件,因为顺序略有不同,因此您不能简单地将一个元素一个接一个地假设它是下一个要写入的元素复制工作表中的总体表格外观。
  • 如何采用该代码在 selenium 中使用并调整结果?

标签: html excel vba selenium web-scraping


【解决方案1】:

所以,正如我在 cmets 中所说,您需要研究数据在后面的表格标签中的显示方式,并执行映射以获得正确的排序。下面写出表格。正如我也提到的,这并不可靠,只有方法可以转移到其他文档。

在您的情况下,您不会从文件中读取,而是会使用

Set tables = driver.FindElementsByCss("table[width='100%'] table:first-child")

然后,您将在集合中的 Web 元素上 For Each 根据需要调整语法,例如.Text 而不是 .innerText。由于它对 webElements 的索引,selenium 可能还有一些其他的适应,但您需要的一切都应该在下面显而易见。

VBA:

Option Explicit
Public Sub ParseInfo()
    Dim html As HTMLDocument, tables As Object, ws As Worksheet, i As Long
    Set ws = ThisWorkbook.Worksheets("Sheet2")
    Dim fStream  As ADODB.Stream
    Set html = New HTMLDocument
    Set fStream = New ADODB.Stream
    With fStream
        .Charset = "UTF-8"
        .Open
        .LoadFromFile "C:\Users\User\Desktop\test.html"
        html.body.innerHTML = .ReadText
        .Close
    End With

    Set tables = html.querySelectorAll("table[width='100%'] table:first-child")
    Dim rowCounter: rowCounter = 2
    Dim mappings(), j As Long, headers(), arr(13)
    headers = Array("Notes", "Type", "Enrollment status", "Governorate of birth", "Year", "Month", "Day", "Date of Birth", "Religion", _
    "Nationality", "Student Name", "National Number", "Student Code", "M")

    mappings = Array(3, 8, 9, 12, 11, 10, 2, 7, 1, 6, 5, 4, 13)
    ws.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers

    For i = 89 To 504 Step 26
        arr(0) = vbNullString

        For j = 0 To 12
            arr(mappings(j)) = tables.item(2 * j + i).innerText
        Next

        ws.Cells(rowCounter + 1, 1).Resize(1, UBound(arr) + 1) = arr
        rowCounter = rowCounter + 1
    Next
End Sub

【讨论】:

  • 太棒了。非常感谢您的大力帮助。你能发布你如何得到映射数组的快照吗?
  • 还有一点:如何通过代码确定89和504,使其更灵活?有没有可能?
  • 有没有办法使用 selenium 下载 html 页面以与我在第一篇文章中附加的文件相同?因为我有大约 200 页 ..
  • 我认为应该是 .count 属性
  • 非常感谢您付出的巨大努力。你帮了我很多..最好的问候
猜你喜欢
  • 2020-11-28
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 2015-08-12
  • 1970-01-01
相关资源
最近更新 更多