You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升嵌套for循环实现的网页爬虫执行速度?

公交数据爬虫性能优化请求

这段R代码用于爬取某交通公司网页,可获取各起讫城市间的公交线路及运营公司信息并整理为表格。代码功能正常,但需处理约650个城市的组合查询,运行3小时仅完成不足5%的任务,恳请提供性能优化方案。

library(RCurl)
library(jsonlite)
library(rjson)
library(dplyr)

# 加载城市列表
cidades <- jsonlite::fromJSON("Listas Cidades Artesp.json")
empresasXlinhas <- data.frame()

# RCURL参数配置
headers = c(
  "Accept" = "application/json, text/javascript, */*; q=0.01",
  "Accept-Language" = "en-US,en;q=0.9",
  "Connection" = "keep-alive",
  "Content-Type" = "application/x-www-form-urlencoded; charset=UTF-8",
  "Cookie" = "__RequestVerificationToken_L1RyYW5zcG9ydGVDb2xldGl2bw2=tY-yKlWmbZvAJzMHmITkohPiIos5XkjDBwf1ZBfP_bYWdXJMBF2Qw3z_B-LRVo0kXjdnHqDqsbZ04Zij_PM-wAf4DWVKfnQskOhqo4ANSRc1",
  "Origin" = "http://extranet.artesp.sp.gov.br",
  "Referer" = "http://extranet.artesp.sp.gov.br/TransporteColetivo/OrigemDestino?fbclid=IwAR3_hZwajHk_iyU085S1LDTqLCOYLHIZ5K825XgPGcB4tMI0EuCJpQNrJHM",
  "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
  "X-Requested-With" = "XMLHttpRequest"
)

# 网页爬取逻辑
for (x in cidades$Codigo){
  for (y in cidades$Codigo){
    
    if (x != y){
      params = paste("origem=",x,"&destino=",y,"&__RequestVerificationToken=Z-wXmGOb9pnQbmkfcQXmChT-6uc3YfGjftHwK4HnC9SDCaKmzIafo7AI3lChBY6YDBHdpT_X98mSHGAr_YrTNgKiepKxKraGu7p6PI7dV4g1", sep ="")
      res <- postForm("http://extranet.artesp.sp.gov.br/TransporteColetivo/OrigemDestino/GetGrid", .opts=list(postfields = params, httpheader = headers, followlocation = TRUE), style = "httppost")
      if (res != "[]"){
        print(paste(x,y))
        empresa <- jsonlite::fromJSON(res)[[2]]
        empresa <- empresa %>% mutate(cod_origem = x, cod_destino = y)
        empresasXlinhas <- rbind(empresasXlinhas, empresa)
        
      }
    }
  }
}

核心优化方案

1. 并行化请求(最关键提速点)

  • 使用future+furrr或parallel包,将所有有效城市组合的请求任务拆分到多个CPU核心并行执行,彻底消除单线程串行等待HTTP响应的时间浪费。
  • 实现思路:先生成所有x≠y的城市组合,再用future_map批量处理每个组合的请求与数据解析。

2. 替换循环中的rbind操作

  • 循环内反复rbind会频繁复制整个数据框,数据量越大效率越低。改为用列表存储每个请求返回的empresa数据,最后通过dplyr::bind_rows()一次性合并,能大幅提升数据拼接效率。

3. 优化HTTP请求工具与配置

  • 替换RCurl为更高效的httr2或httr包,这类现代HTTP工具性能更优,API设计更简洁。
  • 启用HTTP连接复用,设置合理的超时参数,避免每次请求都重新建立TCP连接。
  • 验证硬编码的__RequestVerificationToken是否长期有效,若存在失效风险,需添加动态获取逻辑。

4. 减少重复请求量

  • 若城市间线路数据是双向对称的(即x到y与y到x的线路信息一致),可只请求一半的城市组合,后续直接复制反向数据,减少50%的请求量。

5. 预处理城市组合

  • 提前生成所有有效(x,y)对并过滤掉x=y的无效组合,避免循环内反复判断,示例代码:
    city_pairs <- expand.grid(x = cidades$Codigo, y = cidades$Codigo) %>% filter(x != y)
    

6. 添加错误重试机制

  • 网络请求偶尔会失败,用purrr::insistently添加自动重试逻辑,避免个别请求失败中断整个流程,降低人工干预成本。

7. 分批处理并保存中间结果

  • 每处理完一批请求就将结果写入本地文件(如readr::write_csv),既避免程序崩溃导致数据丢失,也能减少内存占用。

内容的提问来源于stack exchange,提问作者L3A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:16:09