我一直在搜索,但运气不佳。我试图获取https://www.sportsinteraction.com/football/nfl-betting-lines/上正在玩的游戏的文字。因此,最后我希望像下面这样吐出一些东西(不一定是干净的)。
Carolina Panthers 休斯顿德州人 点差 +4.0 1.90 -4.0 1.92
MONEYLINE 2.69 1.49
上方/下方 Ø +47.0 1.91 ü +47.0 1.91
下面的代码显然是错误的:
Sub Pulldata2()
Dim ieObj As InternetExplorer
Dim appIE As Object
Dim htmlEle As IHTMLElement
Dim i As Integer
Dim strSheet As String
strSheet = Sheet2.Range("P2")
i = 1
Set ieObj = New InternetExplorer
ieObj.Visible = False
ieObj.navigate Sheet2.Range("P2").Value
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Wait Now + TimeValue("00:00:03")
Sheet13.Activate
For Each htmlEle In ieObj.document.getElementsByClassName("game")(0)
With ActiveSheet
.Range("A1").Value
End With
i = i + 1
On Error Resume Next
Next htmlEle
End Sub
答案 0 :(得分:1)
为什么?
这是一个有趣的练习技巧,值得花时间尝试。有趣的是,没有一种立即明显的方法可以用关联的元数据来``阻止''每个事件,例如日期,时间,比赛标题;并且下注内容在水平分组和垂直分组之间切换,使您的选择节点识别节点的策略特别重要。
策略:
我决定采用的策略如下:使用css类选择器获取包含所有所需信息的长节点列表。 date, time and title
是节点,我需要为每个gameBettingContent
块中的每个团队在两行中重复其信息。
注意:内容是静态的,因此可以使用XHR来避免打开浏览器和呈现不必要内容的开销。这种方法要快很多。
逻辑块的剖析:
请注意,每个类别为gameBettingContent
的父节点包含3个类别为betTypeContent
的子节点。这些孩子与PointSpread, MoneyLine and Over/Under
相对应。这些将需要在输出中占据自己的列,包括将price
与handicap
分开。对于每个逻辑块,如上所示,将有两行,在输出的前几列中重复一些信息。
nodeList:
因此,最初,我们在nodeList
上有className
个匹配的所有感兴趣的元素。这些节点中有一些子节点,然后我们需要访问这些子节点。为避免复杂的访问器语法,当我们到达需要访问其子节点(或更深节点)的节点时,我们将该节点的html加载到“代理”中,即new HTMLDocument
变量中,因此我们可以利用再次使用querySelectorAll
的{{1}}方法。这使我们的语法易于阅读,并且成本最低。
我们循环显示HTMLDocument
(如左上方所示),并测试每个当前节点的nodeList
,然后使用className
语句确定要做什么。如果当前的className为Select Case
,我们将存储该节点的date, time or title
供以后使用(请记住,我们需要在流道1和流道2上重复此值)。如果.innerText
为className
,我们将该节点的gameBettingContent
加载到代理outerHTML
中,即HTMLDocument
。然后,我们可以收集html2
并开始填充输出数组runners
。首先,我们在变量resultsTable
中添加+2(行计数器),因此我们准备好进行下一个逻辑块(即匹配),然后使用r
和r-2
。
使用替代HTMLDocument变量在DOM较深的节点上利用r-1
:
由于我们将querySelectorAll
与MSXML2.XMLHTTP
一起使用,因此无法访问nth-of-type pseudo class css选择器语法(在使用MSHTML.HTMLDocument
时要与ie.document
一起使用)区分SHDocVw.InternetExplorer
中的下注类型的3个div(列);而我们可以将类选择器和adjacent sibling combinators链接起来,使其在div(列)中从左向右移动,例如
PointSpread:
gameBettingContent
MoneyLine:
.gameBettingContent #runnerNames + .betTypeContent
上方/下方:
.gameBettingContent #runnerNames + .betTypeContent + .betTypeContent
我发现将这些div收集到nodeList中更干净
.gameBettingContent #runnerNames + .betTypeContent + .betTypeContent + .betTypeContent
然后将每个div(列)Set contentDivs = html2.querySelectorAll(".betTypeContent")
加载到新的outerHTML
代理HTMLDocument
中,并再次利用querySelectorAll从每一列的索引中收集两行信息。
例如,html3
将是PointsSpread
中的第一个节点,我们将其读入contentDivs
:
html3
然后我们选择差点和价格
html3.body.innerHTML = contentDivs.item(0).outerHTML
并且可以使用索引来获得跑步者1与跑步者2的值:
Set pointSpreadHandicaps = html3.querySelectorAll(".handicap")
Set pointSpreadPrices = html3.querySelectorAll(".price")
这几乎是大部分逻辑。输出数组的大小基于等于的行数
resultsTable(r - 2, 5) = pointSpreadHandicaps.item(0).innerText: resultsTable(r - 1, 5) = pointSpreadHandicaps.item(1).innerText
即有多少名运动员。列数等于我们在html.querySelectorAll("#runnerNames li").Length
数组中指定的项目数(由于数组是从0开始的,所以我们在headers
上加1)。然后将数组和标题一样写到表中。
VBA:
Ubound
从结果中选择示例:
其他阅读内容: