#使用Excel VBA刮取HTML时的N/A值

#使用Excel VBA刮取HTML时的N/A值,excel,vba,Excel,Vba,我在从.HTM游戏报告中提取HTML代码时遇到问题。如您所见,我正在使用Split()拆分HTML文件,它通常会为这个特定的逐场播放报告创建大约60000行 现在,对于100个游戏中的99个游戏来说,这是非常好的,但是偶尔(比如使用这个确切的GameID),无论出于什么原因,它都会在几千行之后开始输出#N/A,这在文档中很早就出现了 我检查了有问题的.HTM,它看起来就像我提取的任何其他文档一样 下面是代码片段: Dim ie As Object, doc As HTMLDocument Dim

我在从.HTM游戏报告中提取HTML代码时遇到问题。如您所见,我正在使用
Split()
拆分HTML文件,它通常会为这个特定的逐场播放报告创建大约60000行

现在,对于100个游戏中的99个游戏来说,这是非常好的,但是偶尔(比如使用这个确切的GameID),无论出于什么原因,它都会在几千行之后开始输出
#N/A
,这在文档中很早就出现了

我检查了有问题的.HTM,它看起来就像我提取的任何其他文档一样

下面是代码片段:

Dim ie As Object, doc As HTMLDocument
Dim Y1 As String, Y2 As String, GameID As String
Dim SourceCode As Worksheet, c As Range

Set ie = New InternetExplorer
Set SourceCode = Worksheets("Source Code")    
Y1 = "2017"
Y2 = "2018"
GameID = "0003"

ie.navigate "http://www.nhl.com/scores/htmlreports/" & Y1 & Y2 & "/PL02" & GameID & ".HTM"

Do
    DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE

Set doc = ie.document

arr = Split(doc.DocumentElement.innerHTML, vbLf)

SourceCode.Range("A1").Resize(UBound(arr) + 1, 1).Value = Application.Transpose(arr)
这就是(偶尔)发生的情况:


有人对如何处理这个错误有什么建议吗?我一点也不知道是什么原因造成的。

使用Excel内置的web查询工具可能更容易。(如果您以前没有使用过该功能,它可能看起来比现在更复杂。)单击“数据”菜单,然后单击“从Web”,进入网站,Excel将下载在那里可以找到的所有有组织的数据。所附图片显示了步骤和结果,这里是指向的链接

要实现自动化,可以记录导入文件步骤的宏,然后将宏编辑为VBA以输入自定义日期等

如果您对MS Access比较满意,那么它更适合于刮削;我有一个可以传递的文件,我曾经用它来抓取从谷歌到eBay的所有东西(在我了解API之前!)


编辑:

哦!!您的一个问题是:您的代码完成后没有设置ie=nothing,因此每次运行代码时,Excel都会打开另一个Internet Explorer副本(隐藏在后台)。CTRL-ALT-DEL以查看任务管理器,我打赌您有多个iexplore.exe的副本正在运行,占用了所有内存,并导致崩溃。重新启动以修复该问题,然后重试,或尝试其他方法(重新启动后)

这是另一种方法,更方便记忆:

Sub nhl_test()

    Dim ie As Object, doc As HTMLDocument
    Dim Y1 As String, Y2 As String, GameID As String, html As String
    Dim SourceCode As Worksheet, c As Range, y As Long, x As Long

    Set ie = New InternetExplorer
    Set SourceCode = Worksheets("Source Code")
    Y1 = "2017"
    Y2 = "2018"
    GameID = "0003"

    ie.navigate "http://www.nhl.com/scores/htmlreports/" & Y1 & Y2 & "/PL02" & GameID & ".HTM"

    Do
        DoEvents
    Loop Until ie.readyState = READYSTATE_COMPLETE

    Set doc = ie.document
    html = doc.DocumentElement.innerHTML 'put HTML into a variable
    Set doc = Nothing 'free up memory
    Set ie = Nothing 'free up memory, close IE

    arr = Split(html, vbLf) 'now split the html into lines

    For x = 1 To UBound(arr) ' x counts the line # in the file
        If Trim(arr(x)) <> "" Then
            y = y + 1 ' y counts the line # that isn't blank
            SourceCode.Cells(y, 1).Value = arr(x) 'put line x into row y
        End If
    Next x
    MsgBox "done (" & y & "rows)"
End Sub
Sub-nhl_测试()
Dim ie作为对象,doc作为HTMLDocument
Dim Y1作为字符串,Y2作为字符串,GameID作为字符串,html作为字符串
将源代码标注为工作表,将c标注为范围,将y标注为长度,将x标注为长度
Set ie=新的InternetExplorer
设置源代码=工作表(“源代码”)
Y1=“2017年”
Y2=“2018”
GameID=“0003”
即“导航”http://www.nhl.com/scores/htmlreports/&Y1&Y2&“/PL02”&GameID&.HTM”
做
多芬特
循环直到ie.readyState=readyState\u完成
Set doc=ie.document
html=doc.DocumentElement.innerHTML'将html放入变量
Set doc=Nothing'释放内存
设置ie=Nothing'释放内存,关闭ie
arr=Split(html,vbLf)'现在将html拆分为行
对于x=1到UBound(arr),x计算文件中的行
如果修剪(arr(x))”“那么
y=y+1'y计算非空行#
SourceCode.Cells(y,1).Value=arr(x)'将第x行放入第y行
如果结束
下一个x
MsgBox“完成”(&y&“行)”
端接头

…但它仍然不是一组非常有组织的数据。一旦将html加载到工作表中,您的计划是什么?

Transpose
函数的65536项有一个未记录的限制。有一些关于MSDN的讨论,你可以在谷歌上搜索“transpose vba limit”并查看其他一些线程

所以你的文件大约有60000行,有些可能超过了65536行的限制,看起来你的游戏ID达到了这个限制

一种解决方法是创建第二个数组,例如

Dim arr2() As String <-- we will make this a 2d array and fill it from arr

'... later in the code

arr = Split(doc.DocumentElement.innerHTML, vbLf) '<-- get the array with your original code
ReDim Preserve arr2(1 To UBound(arr), 1 To 1) '<-- redim arr2 to be suitable for writing to a range

' now fill the array from arr - basically doing a "manual" transpose
Dim i As Long
For i = 1 To UBound(arr)
    arr2(i, 1) = arr(i)
Next i

这也是我的第一个想法=)不幸的是,我的Excel在尝试使用此工具刮取.HTM页面时崩溃。我看到NHL页面非常糟糕,并且被锁定,所以你甚至不能右键单击“查看页面源代码”(尽管在Firefox中CTRL+U可以克服这一点)。将数据输入Excel的最快方法就是文件→ 打开→ 浏览→ 并粘贴到您的URL
http://www.nhl.com/scores/htmlreports/20172018/PL020003.HTM
您将获得一份格式良好的页面副本。单元格中是否有带#N/a的公式,或者只有字符串?只有字符串!=)我相信这是一个
Transpose
问题-请看下面我的答案非常感谢您的投入和努力!这看起来更加可靠,并且解决了大多数我出错的情况!然而,在某些情况下,仍然会出现相同的错误,但这一次,它会在文件的下一行出现,例如第53 614行。你知道为什么会这样吗?编辑:实际上,它总是在第53 614行。应该说,我在一个for循环中使用这段代码,其中GameID从0001增加到1230,所以我在循环的每个实例中使用这段代码两次(使用arr3作为变量,第二次使用arr4作为数组两次)。。。是否我必须在循环的每个实例之后清空数组?
Option Explicit

Sub Foo()

    Dim ie As Object, doc As HTMLDocument
    Dim Y1 As String, Y2 As String, GameID As String
    Dim SourceCode As Worksheet, c As Range
    Dim arr As Variant, arr2() As String

    Set ie = New InternetExplorer
    Set SourceCode = Worksheets("Source Code")
    Y1 = "2017"
    Y2 = "2018"
    GameID = "0003"

    ie.navigate "http://www.nhl.com/scores/htmlreports/" & Y1 & Y2 & "/PL02" & GameID & ".HTM"

    Do
        DoEvents
    Loop Until ie.readyState = READYSTATE_COMPLETE

    Set doc = ie.document

    arr = Split(doc.DocumentElement.innerHTML, vbLf)
    ReDim Preserve arr2(1 To UBound(arr), 1 To 1)
    Dim i As Long
    For i = 1 To UBound(arr)
        arr2(i, 1) = arr(i)
    Next i

    SourceCode.Range("A1").Resize(UBound(arr), 1).Value = arr2

    ' see comment by ashleedawg on the other answer
    Set ie = nothing

End Sub