R语言使用rvest包搭配嵌套for循环爬取天气数据出现HTTP 502错误如何解决
代码原生问题修正
- 冗余重复请求:同一个页面的
read_html(link)被放在了内层遍历num的循环里,等于单个链接要重复发起8次请求,既拖慢爬取速度,又会因短时间高频触发服务器反爬机制,导致返回HTTP 502。正确逻辑是每个链接仅读取1次页面对象,再基于固定页面遍历所有日期节点。 - 循环范围不匹配:你需要采集7天数据,当前
for (num in 0:7)会遍历0到7共8个节点,若实际不存在num7的DOM节点,会导致选择器匹配异常。需根据实际DOM节点编号调整范围,若节点仅为num0到num3则用0:3,若为7天对应num0到num6则用0:6。 - 冗余操作:
link = paste(Links[index])属于无效冗余步骤,Links本身为字符向量,可直接取元素使用,无需额外拼接。 - 数据未持久化:循环中对
DayOfWeek/Conditions的赋值都是临时变量,程序运行结束后不会留存任何采集结果,需要提前初始化空存储对象,每次循环将结果追加保存。
HTTP 502报错处理方案
HTTP 502属于服务器网关临时错误,针对当前批量爬取场景,绝大多数情况是请求频率过高、请求特征被识别为爬虫导致,可按以下优先级处理:
- 设置请求间隔:每完成1个链接的爬取后暂停1-2秒,避免短时间高频请求触发封禁
- 自定义请求头:给
read_html添加模拟浏览器的请求参数,避免被服务器直接识别为爬虫 - 加重试机制:遇到502等临时报错时自动重试2-3次,不要遇错直接终止批量任务
- 加异常捕获:单个链接爬取失败时自动跳过并记录报错,不要中断整个采集流程
优化后可运行的代码模板
library(rvest) library(tidyverse) # 初始化空结果存储表 weather_res <- tibble( link = character(), node_num = integer(), DayOfWeek = character(), Conditions = character() ) # 模拟浏览器的请求头配置 req_header <- httr::add_headers( `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ) Links <- # 替换为你实际的1440个链接向量 for (index in seq_along(Links)) { current_link <- Links[index] # 异常捕获,单链接失败不影响整体流程 tryCatch({ # 每个链接仅发起1次请求 page <- read_html(current_link, config = req_header) # 遍历对应日期节点,根据实际DOM编号调整范围 for (num in 0:6) { node_date <- paste0(".num", num, " .date") node_conditions <- paste0(".num", num, " .cond span") DayOfWeek <- page %>% html_nodes(node_date) %>% html_text(trim = TRUE) Conditions <- page %>% html_nodes(node_conditions) %>% html_text(trim = TRUE) # 追加当前采集结果到总表 weather_res <- weather_res %>% add_row( link = current_link, node_num = num, DayOfWeek = DayOfWeek, Conditions = Conditions ) } # 设置请求间隔,降低触发反爬概率 Sys.sleep(1.5) }, error = function(e) { message(paste("爬取失败,跳过链接:", current_link, " 报错:", e$message)) }) } # 导出采集结果 write.csv(weather_res, "weather_data.csv", row.names = FALSE)
若添加间隔、模拟请求后仍频繁返回502,可适当拉长请求间隔,或检查是否需要携带登录后的cookie才能正常访问页面。
内容的提问来源于stack exchange,提问作者CaptainMuu
相关产品推荐
相关产品推荐

