R使用rvest、RSelenium爬取需Cookie同意的derstandard站点报错求解
问题核心原因梳理
- 直接用
rvest的read_html请求页面时,请求未携带cookie同意标识,网站仅返回cookie弹窗页面,无新闻列表内容 - 原有提取链接的CSS选择器写错:
href属性在.teaser-inner下的a标签上,直接给.teaser-inner提取属性拿不到链接 - RSelenium代码的错误:误将无iframe的弹窗内容切到iframe查找,且未加页面加载等待、使用的绝对Xpath稳定性差
方案1:轻量无浏览器方案(推荐,爬取速度快)
不需要启动浏览器渲染,直接在请求中携带同意后的cookie即可:
- 手动打开目标页面,同意cookie弹窗后,按F12打开开发者工具→网络标签,刷新页面后找到第一个对目标站点的请求,复制请求头中的
Cookie整串值 - 用
httr包携带cookie发起请求,再传给rvest解析即可,示例代码:
library(httr) library(rvest) library(tidyverse) # 替换为你自己复制的cookie字符串 consent_cookie <- "复制的cookie内容" # 原有提取正文的函数可以保留 get_text <- function(headline_links) { article_page <- GET(headline_links, add_headers(Cookie = consent_cookie)) %>% read_html() text_article <- article_page %>% html_nodes('.article-body p') %>% html_text() %>% paste( collapse = " ") # 每次请求停1秒避免被封 Sys.sleep(1) return(text_article) } date <-seq.Date(as.Date("2011/12/01"), as.Date("2012/06/30"), by = 1 ) date <-format(date, "%Y/%m/%d") # 这里不需要转strptime,直接格式化即可 Newspaper <- "der standard" articles_standard <- data.frame() for (page_date in date) { link <- paste0("https://www.derstandard.at/international/", page_date) # 带cookie请求列表页 page <- GET(link, add_headers(Cookie = consent_cookie)) %>% read_html() # 修正选择器,取teaser-inner下的a标签的href headline_links <- page %>% html_nodes('.teaser-inner a') %>% html_attr("href") # 补全链接域名 headline_links <- paste0("https://www.derstandard.at", headline_links) if(length(headline_links)>0){ text_all <- sapply(headline_links, FUN = get_text, USE.NAMES = F) text_all <- data.frame(text = text_all, url = headline_links, stringsAsFactors = F) articles_standard <- rbind(articles_standard, data.frame(Newspaper, text_all, stringsAsFactors = F)) } # 每次翻页停2秒 Sys.sleep(2) }
方案2:修正后的RSelenium方案
如果需要模拟浏览器操作,修正原有代码的错误即可:
library(RSelenium) library(rvest) # 启动火狐驱动 driver <- rsDriver(port = 1333L, browser = "firefox") remote_driver <- driver[["client"]] remote_driver$maxWindowSize() # 先打开一次页面同意cookie,后续请求会自动携带cookie remote_driver$navigate("https://www.derstandard.at/international/2011/12/01") # 等待弹窗加载 Sys.sleep(3) # 点击同意按钮,用稳定的css选择器 tryCatch({ accept_btn <- remote_driver$findElement(using = "css", value = "button.sp_choice_type_11") accept_btn$clickElement() Sys.sleep(2) }, error = function(e) { print("未检测到cookie弹窗,跳过点击") }) # 后续爬取逻辑 date <-seq.Date(as.Date("2011/12/01"), as.Date("2012/06/30"), by = 1 ) date <-format(date, "%Y/%m/%d") Newspaper <- "der standard" articles_standard <- data.frame() for (page_date in date) { link <- paste0("https://www.derstandard.at/international/", page_date) remote_driver$navigate(link) Sys.sleep(2) # 获取页面源码解析 page <- remote_driver$getPageSource()[[1]] %>% read_html() headline_links <- page %>% html_nodes('.teaser-inner a') %>% html_attr("href") headline_links <- paste0("https://www.derstandard.at", headline_links) if(length(headline_links)>0){ text_all <- sapply(headline_links, function(url){ remote_driver$navigate(url) Sys.sleep(1) remote_driver$getPageSource()[[1]] %>% read_html() %>% html_nodes('.article-body p') %>% html_text() %>% paste( collapse = " ") }, USE.NAMES = F) text_all <- data.frame(text = text_all, url = headline_links, stringsAsFactors = F) articles_standard <- rbind(articles_standard, data.frame(Newspaper, text_all, stringsAsFactors = F)) } } # 爬取结束关闭驱动 remote_driver$close() driver$server$stop()
注意事项
- 爬取时控制请求频率,避免短时间内大量请求被站点封禁IP
- cookie有效期一般比较长,如果后续出现爬不到内容的情况,重新复制一次最新的cookie即可
内容的提问来源于stack exchange,提问作者manuk
相关产品推荐
相关产品推荐

