#使用Excel VBA刮取HTML时的N/A值
我在从.HTM游戏报告中提取HTML代码时遇到问题。如您所见,我正在使用#使用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
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