使用rvest抓取ITU数据中心指标下载链接的技术问题咨询
核心原因
你直接用rvest爬静态页拿不到数据,是因为这个指标页是JavaScript动态渲染的:所有指标名称、ID这些数据不会写在首次请求返回的HTML源码里,而是页面加载完成后,前端再向后端发异步请求拉取数据,最后渲染到页面上。你读初始静态HTML,自然找不到动态生成的链接。
实现方案
完全不用暴力遍历10万+ID,直接抓页面调用的后端数据接口就行,请求量极小,也不会给服务器造成多余压力:
- 打开目标页面按F12调出开发者工具,切到「网络」面板,筛选
Fetch/XHR类型请求,刷新页面就能看到前端拉取全量指标列表的接口 - 这个接口会直接返回所有指标的元信息:包括指标数字ID、
isCollection字段(就是你说的URL里的YYY参数,取值true/false)、指标全称,根本不需要解析HTML节点 - 拿到这些元数据之后,直接按你已经发现的URL规则拼接下载链接,和名称一一对应就能直接生成需要的数据框。
可直接运行的R代码
library(httr) library(tidyverse) # 直接请求指标列表接口,跳过HTML解析步骤 resp <- GET( "https://api.datahub.itu.int/v2/indicators", query = list( page = 1, pageSize = 20000, # 调大单页条数,尽量一次拉完全量,减少请求次数 `$orderby` = "name asc" ) ) # 解析返回的JSON结构 raw_data <- content(resp, as = "parsed")$items # 整理成结构化数据框,拼接下载链接 final_df <- map_dfr(raw_data, function(item){ is_collection <- ifelse(!is.null(item$isCollection) && item$isCollection, "true", "false") tibble( indicator_id = item$id, indicator_name = item$name, is_collection = is_collection, download_url = paste0("https://api.datahub.itu.int/v2/data/download/byid/", item$id, "/iscollection/", is_collection) ) }) # 若接口返回的总条数大于单页pageSize,加个简单循环拉取剩余分页即可,总请求量最多几十次
补充说明
- 请求时不要开高并发,每次请求间隔1秒左右就完全不会给站点造成访问压力
- 如果接口提示权限校验失败,直接从浏览器网络面板里复制对应请求的请求头,加到GET请求的
add_headers()参数里就行,公开指标数据不需要登录就能访问 - 别用无头浏览器、rvest硬爬渲染后的页面,这类方案比直接调接口效率低几十倍,还容易被站点反爬拦截。
内容的提问来源于stack exchange,提问作者thehand0
相关产品推荐
相关产品推荐

