使用R的rvest包爬取在线新闻数据遇到报错问题求助
R爬虫代码问题排查与修复方案
运行前请先安装所有依赖包:install.packages(c("rvest", "xml2", "dplyr", "stringr", "httr", "readr", "purrr"))
1 单页爬取代码问题(仅返回9条结果)
问题原因
- 未设置浏览器请求头,网站反爬机制识别到爬虫请求后仅返回部分页面内容
- CSS选择器匹配范围有误,仅命中了页面顶部分类模块的新闻,未覆盖全页所有存档新闻
- 冗余代码:重复加载
rvest库,不影响运行但不符合规范
修复代码
library(rvest) library(xml2) library(dplyr) library(stringr) library(httr) # 模拟浏览器请求头绕过基础反爬 headers <- c( "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" ) url <- 'https://en.trend.az/archive/2021-11-03' html <- read_html(url, add_headers(.headers=headers)) # 更换匹配全页新闻标题的CSS选择器 headline_html <- html_nodes(html,'.article-item .article-title') headline <- str_trim(html_text(headline_html)) # 此时输出长度和SelectorGadget检测结果一致 length(headline)
2 批量循环爬取代码问题(报错x must be a string of length 1)
问题原因
- for循环遍历对象写错:
for(i in 'rchdate')是遍历字符串"rchdate",而非你生成的日期向量arch_date - 拼接URL时使用了全部日期向量,生成的
url_fonq是多元素向量,read_html一次只能读取1个URL - 缺失
stringr库加载,str_c、str_trim函数无法正常调用 date、time、cat、row_number等变量未定义就写入数据框
修复代码
library(rvest) library(xml2) library(dplyr) library(stringr) library(httr) headers <- c( "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" ) all_df <- data.frame() arch_date <- seq(as.Date("2021-11-03"), as.Date("2021-11-13"), by="days") # 遍历日期向量 for(i in 1:length(arch_date)){ # 单次仅拼接1个日期的URL current_date <- arch_date[i] url_fonq <- str_c('https://en.trend.az', "/archive/", current_date) webpage_fonq <- read_html(url_fonq, add_headers(.headers=headers)) # 提取各字段 headline <- str_trim(html_text(html_nodes(webpage_fonq,'.article-item .article-title'))) time <- str_trim(html_text(html_nodes(webpage_fonq,'.article-item .article-date'))) cat <- str_trim(html_text(html_nodes(webpage_fonq,'.article-item .article-category'))) # 生成单页数据框 fonq.df <- data.frame( Num = 1:length(headline), Date = rep(current_date, length(headline)), Time = time, Title = headline, Category = cat ) all_df <- bind_rows(all_df, fonq.df) # 加1秒延迟避免触发频率限制 Sys.sleep(1) }
3 DataCamp参考代码问题(报错object '_tmp_' not found)
问题原因
- 变量名拼写错误:定义的是
combine_data,后续调用写成了combined_data,管道操作找不到临时对象就抛出_tmp_不存在的错误 get_time函数未给出定义,调用时无法执行- 保存的文件名为
Trend.AZ.tsv,读取时写为Trend.AZ,缺失后缀 - 最后调用
tail时用了未定义的amz_tbl,实际生成的变量是trend_az_tbl
修复核心代码
library(purrr) library(readr) # 补充定义get_time函数 get_time <- function(html){ html %>% html_nodes('.article-item .article-date') %>% html_text() %>% str_trim() %>% unlist() } get_headline <- function(html){ html %>% html_nodes('.article-item .article-title') %>% html_text() %>% str_trim() %>% unlist() } get_data_table <- function(html, company_name){ headline <- get_headline(html) time <- get_time(html) # 修正变量名 combine_data <- tibble(Abstract = headline, Date = time) combine_data %>% mutate(Trend.AZ = company_name) %>% select(Trend.AZ, Abstract, Date) } get_data_from_url <- function(url, company_name){ headers <- c( "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" ) html <- read_html(url, add_headers(.headers=headers)) get_data_table(html, company_name) } scrape_write_table <- function(url, company_name){ base_url <- "https://en.trend.az" arch_date <- seq(as.Date("2021-10-01"), as.Date("2021-11-01"), by="days") list_of_url <- str_c(base_url, "/archive/", arch_date) list_of_url %>% map_dfr(get_data_from_url, company_name) %>% write_tsv(str_c(company_name,'.tsv')) } scrape_write_table(url, 'Trend.AZ') # 读取文件修正后缀,tail调用修正变量名 trend_az_tbl <- read_tsv('Trend.AZ.tsv') tail(trend_az_tbl, 11)
内容的提问来源于stack exchange,提问作者Eugene Bu
相关产品推荐
相关产品推荐

