doc1 是一个 MSHTML.HTMLDocument 实例,它没有 FindElementByClass 方法。也不是 DOM 中任何节点的 .text 属性。您引用的方法是 Selenium Type 类中的一种,其中您有一个 WebDriver 的实例。
还有其他各种问题。您在页面上看到的内容是动态呈现的,您想要的数据来自使用返回 JSON 的 graphql 查询的 XHR POST 请求。您需要制定这些请求并在结果上使用 JSON 解析器,如下面的示例所示。
另外,使用Option Explicit,声明所有变量,使用有意义的名称,并通过在.Open 行中传递False 使请求同步。
parts 是您需要在For Each 之上的字典集合,然后是For Each Key,其中Key 是变体,在每个字典的.Keys 之上。
选择您想要的项目。键 abilities 返回一个集合,所以如果使用需要不同的处理。
待办事项:
-
R1 和 R2 您需要使用父 ID 并从请求中提取这些 ID 信息。下面的代码用于子 ID,并返回您想要的结果列 D。
-
data 请求更多您似乎需要的信息,以便您可以删除其中的许多参数。
JSON 库:
我使用JsonConverter.bas。从 here 下载原始代码并添加到名为 JsonConverter 的标准模块中。从复制的代码中删除顶部的 Attribute .... 行,如果已指定 Option Explicit。
然后你需要去:
VBE > Tools > References> 添加引用:
Microsoft Scripting Runtime
Microsoft HTML Object Library
Microsoft WinHTTP Services, version 5.1 Library (or your version).
在 VBA for JSON 中,[] 表示集合,{} 表示字典。
VBA:
Option Explicit
Public Sub PrintGetAxieDetail()
Dim response As Object
Set response = GetAxieGeneDetail("5016162")
Debug.Print JsonConverter.ConvertToJson(response)
End Sub
Public Function GetAxieGeneDetail(ByVal id As String) As Object
Dim http As WinHttp.WinHttpRequest
Dim doc1 As MSHTML.HTMLDocument
Dim data As String
Set http = New WinHttp.WinHttpRequest
Set doc1 = New MSHTML.HTMLDocument
With http
.Open "POST", "https://axieinfinity.com/graphql-server-v2/graphql", False
.setRequestHeader "content-type", "application/json"
.setRequestHeader "user-agent", "Mozilla/5.0"
.setRequestHeader "referer", "https://www.axie.tech/"
.setRequestHeader "accept-language", "en-GB,en-US;q=0.9,en;q=0.8"
data = "{""operationName"":""GetAxieDetail"",""variables"":{""axieId"":""" & id & """},""query"":""query GetAxieDetail($axieId: ID!)" & _
"{\n axie(axieId: $axieId) {\n ...AxieDetail\n __typename\n }\n}\n\nfragment AxieDetail on Axie {\n id\n image" & _
"\n class\n chain\n name\n genes\n owner\n birthDate\n bodyShape\n class\n sireId\n sireClass\n matronId\n matronClass" & _
"\n stage\n title\n breedCount\n level\n figure {\n atlas\n model\n image\n __typename\n }" & _
"\n parts {\n ...AxiePart\n __typename\n }\n stats {\n ...AxieStats\n __typename\n }" & _
"\n auction {\n ...AxieAuction\n __typename\n }\n ownerProfile {\n name\n __typename\n }" & _
"\n battleInfo {\n ...AxieBattleInfo\n __typename\n }" & _
"\n children {\n id\n name\n class\n image\n title\n stage\n __typename\n }\n __typename" & _
"\n}\n\nfragment AxieBattleInfo on AxieBattleInfo {\n banned\n banUntil\n level\n __typename" & _
"\n}\n\nfragment AxiePart on AxiePart {\n id\n name\n class\n type\n specialGenes\n stage\n abilities" & _
"{\n ...AxieCardAbility\n __typename\n }\n __typename\n}\n\nfragment AxieCardAbility on AxieCardAbility" & _
"{\n id\n name\n attack\n defense\n energy\n description\n backgroundUrl\n effectIconUrl\n __typename\n}" & _
"\n\nfragment AxieStats on AxieStats {\n hp\n speed\n skill\n morale\n __typename\n}\n\nfragment AxieAuction on Auction" & _
"{\n startingPrice\n endingPrice\n startingTimestamp\n endingTimestamp\n duration\n timeLeft\n currentPrice" & _
"\n currentPriceUSD\n suggestedPrice\n seller\n listingIndex\n state\n __typename\n}\n""}"
.send data
Dim axieDetail As Object, geneResults As Object
Set axieDetail = JsonConverter.ParseJson(.responseText)
Set geneResults = axieDetail("data")("axie")("parts") 'this returns a collection to For Each over
Set GetAxieGeneDetail = geneResults
End With
End Function
JSON 示例: