需要使用VBA-JSON从URL编号发生变化的不同URL中提取数据
我正在从我玩的加密游戏中收集数据。我已经可以使用网站的API来解析“我的怪物”中的数据。我正在尝试为游戏中的所有mons收集相同的数据。该API可让您一次提取99个mons的数据(一次最多可提取99个)。有大约。存在48,000个mons,并且这个数字还在继续增加。每个星期一都有一个ID号(第一个被捕获为1,之后为每个n + 1)。
我需要先提取1-99,然后100-198,然后199-297等数据,直到48000。
我想从每个星期一收集ID号,“ class_name”,“ total_level”,“ perfect_rate”,“ create_index”(都是字典),最重要的是,我想要“ total_battle_stats”(它是一个数组) 。
这是我要提取清单中所有mons变量的代码(它引用了其他链接),但是它已经包含了我想要的方式。
我只需要那些相同的变量,但要引用很多不同的链接,而不仅仅是一个。
显式选项
公共Sub WriteOutBattleInfo() Dim headers(),r为Long,i为Long,json为对象,键为Variant,ws为工作表,battleStats为对象 设置ws = ThisWorkbook.Worksheets(“ Sheet1”) 标头= Array(“ Monster#”,“ Name”,“ Total Level”,“ Perfection”,“ Catch Number”,“ HP”,“ PA”,“ PD”,“ SA”,“ SD”,“ SPD” )
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.etheremon.com/api/user/get_my_monster?trainer_address=0x2Fef65e4D69a38bf0dd074079f367CDF176eC0De", False
.Send
Set json = JsonConverter.ParseJson(.ResponseText)("data")("monsters") 'dictionary of dictionaries
End With
r = 2
ws.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
For Each key In json.Keys
With ws
.Cells(r, 1) = key
.Cells(r, 2) = json(key)("class_name")
.Cells(r, 3) = json(key)("total_level")
.Cells(r, 4) = json(key)("perfect_rate")
.Cells(r, 5) = json(key)("create_index")
Set battleStats = json(key)("total_battle_stats")
For i = 1 To battleStats.Count
.Cells(r, i + 5) = battleStats.Item(i)
Next i
End With
r = r + 1
Next
Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 key:=Range("C2:C110" _
), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:K110")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Selection.Columns.AutoFit
结束子
我希望它看起来像这样:https://imgur.com/a/xPA9T7W
但是我希望所有Mons从ID 1到48000。
答案 0 :(得分:2)
您可以使用一个函数来增加ID以连接到基本URL。如果您要求太快/可能太多次,则站点会受到限制/阻塞。查看文档以获取任何建议。
我展示了如何检索所有内容。我提供了一个1到5个请求的测试用例(取消注释以获取全部请求。注:我给一行代码供您调整,它允许每个x请求增加延迟,以尝试避免节流/阻塞。在发生这种情况之前,这个数字似乎很低。
稍后,您可以考虑将其移到一个类中以保存xmlhttp对象并为其提供诸如getItems之类的方法。示例here。
Option Explicit
Public Sub WriteOutBattleInfo()
Const BASE_URL As String = " https://www.etheremon.com/api/monster/get_data?monster_ids="
Const END_COUNT As Long = 48000
Const BATCH_SIZE As Long = 99
Dim numberOfRequests As Long, i As Long, j As Long, ids As String
Dim headers(), r As Long, json As Object, key As Variant, ws As Worksheet, battleStats As Object
Set ws = ThisWorkbook.Worksheets("Sheet1")
headers = Array("Monster #", "Name", "Total Level", "Perfection", "Catch Number", "HP", "PA", "PD", "SA", "SD", "SPD")
numberOfRequests = Application.WorksheetFunction.RoundDown(END_COUNT / BATCH_SIZE, 0)
ids = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99"
Dim results()
ReDim results(1 To END_COUNT, 1 To 11)
r = 1
With CreateObject("MSXML2.XMLHTTP")
For i = 1 To 5 'numberOfRequests + 1
If i Mod 10 = 0 Then Application.Wait Now + TimeSerial(0, 0, 1)
If i > 1 Then ids = IncrementIds(ids, BATCH_SIZE, END_COUNT)
.Open "GET", BASE_URL & ids, False
.send
Set json = JsonConverter.ParseJson(.responseText)("data")
For Each key In json.keys
results(r, 1) = key
results(r, 2) = json(key)("class_name")
results(r, 3) = json(key)("total_level")
results(r, 4) = json(key)("perfect_rate")
results(r, 5) = json(key)("create_index")
Set battleStats = json(key)("total_battle_stats")
For j = 1 To battleStats.Count
results(r, j + 5) = battleStats.item(j)
Next j
r = r + 1
Next
Next
End With
ws.Cells(1, 1).Resize(1, UBound(headers) + 1) = headers
ws.Cells(2, 1).Resize(UBound(results, 1), UBound(results, 2)) = results
End Sub
Public Function IncrementIds(ByVal ids As String, ByVal BATCH_SIZE As Long, ByVal END_COUNT) As String
Dim i As Long, arrayIds() As String
arrayIds = Split(ids, ",")
For i = LBound(arrayIds) To UBound(arrayIds)
If CLng(arrayIds(i)) + BATCH_SIZE <= END_COUNT Then
arrayIds(i) = arrayIds(i) + BATCH_SIZE
Else
ReDim Preserve arrayIds(0 To i - 1)
Exit For
End If
Next
IncrementIds = Join(arrayIds, ",")
End Function