Power Query M语言实现REST API分页循环获取数据求助
如何用Power Query M循环获取分页REST API的全部记录
我刚好碰到过类似的场景,这种分页API的批量获取在Power Query里可以通过定义复用的分页函数+生成页码列表+批量请求合并来实现,给你一套完整的解决方案和代码:
问题回顾
你需要从一个REST API拉取约4万条记录,API每次最多返回10条数据,不支持skip/count/top参数,但返回结果包含totalCount/page/pageSize字段,返回示例如下:
"data": { "totalCount": 6705, "page": 1, "pageSize": 10, "list":[] }
你已经写出了基础的请求代码,但不知道如何实现循环拉取所有页的逻辑。
解决方案思路
- 封装分页请求函数:把单页的API请求逻辑封装成可复用的函数,接收页码作为参数
- 获取总页数:先调用一次API拿到
totalCount,计算出需要请求的总页数(向上取整totalCount/pageSize) - 批量请求所有页:生成从1到总页数的页码列表,对每个页码调用分页函数
- 合并结果:把所有页返回的
list数据合并成一个完整的数据集
完整Power Query M代码
let // 1. 定义获取单页数据的函数,接收pageNumber参数 getPage = (pageNumber as number) => let Source = Json.Document( Web.Contents( "https://api.somedummy.com/api/v2/Account", [ RelativePath ="Search", Headers = [ ApiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx", Authorization = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #"Content-Type" = "application/json" ], // 在请求体中加入page参数,指定要获取的页码 Content= Json.FromValue( [key="status", operator="EqualTo", value="Active", resultType="Full", page=pageNumber] ) ] ) ), // 提取当前页的list数据 pageData = Source[data][list] in pageData, // 2. 获取第一页数据,拿到totalCount和pageSize firstPageResponse = getPage(1), totalCount = Json.Document(Web.Contents("https://api.somedummy.com/api/v2/Account",[RelativePath ="Search",Headers=[ApiKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx",Authorization="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",#"Content-Type"="application/json"],Content=Json.FromValue([key="status",operator="EqualTo",value="Active",resultType="Full",page=1])]))[data][totalCount], pageSize = 10, // 也可以从firstPageResponse的源数据里提取,这里写固定值更直观 totalPages = Number.RoundUp(totalCount / pageSize), // 3. 生成所有需要请求的页码列表 pageNumbers = {1..totalPages}, // 4. 对每个页码调用getPage函数,获取所有页的数据 allPagesList = List.Transform(pageNumbers, each getPage(_)), // 5. 合并所有页的list数据为一个大列表,再转成表格 combinedList = List.Union(allPagesList), finalTable = Table.FromList(combinedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error) in finalTable
代码说明
getPage函数:负责单页请求,把页码作为参数传入请求体,返回当前页的list数据- 总页数计算:用
Number.RoundUp确保最后一页即使不足10条也会被请求 - 批量请求:
List.Transform会遍历所有页码,调用getPage获取每一页数据 - 结果合并:
List.Union把所有页的列表合并成一个大列表,最后转成表格方便后续处理
如果API有请求频率限制,你可以在getPage函数里加入延迟逻辑,比如添加#"Delay" = Function.InvokeAfter(() => null, #duration(0,0,0,1))(延迟1秒)来避免触发限流。
内容的提问来源于stack exchange,提问作者gujjar
相关产品推荐
相关产品推荐

