使用Rvest抓取网页时如何获取完整的href URL
解决rvest获取相对URL转绝对URL并循环抓取数据的问题
没问题,我来帮你搞定这个问题!你遇到的核心问题是获取到的是相对URL,而我们需要把它转换成完整的绝对URL才能正常访问子页面,另外循环的写法也需要调整一下。下面是具体的解决步骤和完整代码:
1. 把相对URL转换成绝对URL
你可以使用httr包中的url_absolute()函数,它能自动帮你把相对路径拼接成完整的URL,比手动拼接更可靠(能处理各种复杂的相对路径场景)。如果还没装这个包,先运行install.packages("httr")安装。
修改你的URL获取代码:
library(rvest) library(httr) # 基础URL,用于拼接相对路径 base_url <- "http://stats.espncricinfo.com" odi_score_url <- read_html('http://stats.espncricinfo.com/ci/engine/records/team/match_results.html?class=2;id=2019;type=year') # 获取相对URL并转成绝对URL urls <- odi_score_url %>% html_nodes('td:nth-child(7) .data-link') %>% html_attr("href") %>% url_absolute(base_url) # 关键一步:转成绝对URL links <- odi_score_url %>% html_nodes('td:nth-child(7) .data-link') %>% html_text() score_df <- data.frame(links = links, urls = urls, stringsAsFactors = FALSE) head(score_df)
现在score_df$urls里就是完整的可直接访问的URL了,比如http://stats.espncricinfo.com/ci/engine/match/1153840.html。
2. 修正循环逻辑并抓取数据
原来的for(i in score_df)是遍历数据框的列,不是行,这会导致错误。我们需要遍历数据框的行索引,逐个访问每个URL并抓取数据,最后把所有结果合并成一个数据框。
这里建议先创建一个空列表来存储每次抓取的结果,最后再转成数据框,这样效率更高:
# 创建空列表存储结果 match_data_list <- list() # 循环遍历每个URL for(i in seq_len(nrow(score_df))) { # 读取当前页面 current_page <- read_html(score_df$urls[i]) # 抓取目标文本 text_data <- current_page %>% html_nodes(".match-detail--item:nth-child(3) span , .match-detail--item:nth-child(3) h4 , .stadium-details+ .match-detail--item span , .stadium-details , .stadium-details+ .match-detail--item h4 , .cscore_score , .cscore_name--long") %>% html_text() # 把当前结果整理成数据框行,并存入列表 # 这里可以根据text_data的结构调整,比如按位置对应字段 match_data_list[[i]] <- data.frame( match_id = score_df$links[i], detail_text = paste(text_data, collapse = "; "), # 或者拆分对应字段 stringsAsFactors = FALSE ) } # 把列表合并成最终的数据框 final_match_df <- do.call(rbind, match_data_list) head(final_match_df)
额外提示
- 如果抓取频率太高可能会被网站反爬,可以在循环里加入
Sys.sleep(1),每次请求后暂停1秒,避免被封禁。 - 你可以根据
text_data的实际结构,把它拆分成更具体的字段(比如球队名称、比分、场地、日期等),而不是合并成一个字符串,这样数据框会更实用。
内容的提问来源于stack exchange,提问作者James Taylor
相关产品推荐
相关产品推荐

