使用rvest爬取议会演讲时,如何基于姓名筛选对应内容?
问题分析
你当前代码的核心问题是:在筛选演讲的lapply匿名函数中,你引用了整个df$name_surname向量,导致每次处理某一行的HTML内容时,都会用所有三个议员的姓名去匹配,而不是仅用当前行对应的议员姓名,这就导致筛选结果不符合预期。
解决方案
要实现“每行对应筛选该行议员的演讲”,需要同时遍历text_html和name_surname两列,确保每个HTML内容对应到正确的筛选关键词。可以用mapply(基础R)或者purrr::map2(tidyverse风格)来实现。
基础R版本(mapply)
library(rvest) library(stringr) df <- structure(list(name_surname = c("FERDINANDO ADORNATO", "FERDINANDO ADORNATO", "LUCIANO AGOSTINI"), text = c("http://documenti.camera.it/apps/commonServices/getDocumento.ashx?idlegislatura=16&sezione=assemblea&tipoDoc=stenografico&idSeduta=0019&nomefile=stenografico&ancora=sed0019.stenografico.tit00030.sub00060.int00020#sed0019.stenografico.tit00030.sub00060.int00020", "http://documenti.camera.it/apps/commonServices/getDocumento.ashx?idlegislatura=16&sezione=assemblea&tipoDoc=stenografico&idSeduta=0019&nomefile=stenografico&ancora=sed0019.stenografico.tit00030.sub00060.int00120#sed0019.stenografico.tit00030.sub00060.int00120", "http://documenti.camera.it/apps/commonServices/getDocumento.ashx?idlegislatura=16&sezione=assemblea&tipoDoc=stenografico&idSeduta=0041&nomefile=stenografico&ancora=sed0041.stenografico.tit00020.sub00010.int01320#sed0041.stenografico.tit00020.sub00010.int01320" )), row.names = c(NA, 3L), class = "data.frame") # 读取HTML内容 df$text_html <- lapply(df$text, read_html) # 获取所有演讲 df$text_final <- lapply(df$text_html, function(x) { html_nodes(x, '.intervento') %>% html_text(trim = TRUE) }) # 正确筛选对应议员的演讲:用mapply同时匹配每行的html和姓名 df$text_final2 <- mapply(function(html, name) { interventi <- html_nodes(html, '.intervento') %>% html_text(trim = TRUE) str_subset(interventi, paste0("^", name)) }, html = df$text_html, name = df$name_surname, SIMPLIFY = FALSE)
tidyverse风格版本(purrr::map2)
如果你习惯用tidyverse工具,可以用purrr::map2,代码更简洁直观:
library(rvest) library(stringr) library(purrr) # (前面的df定义和读取HTML步骤同上) df$text_final2 <- map2(df$text_html, df$name_surname, function(html, name) { html %>% html_nodes('.intervento') %>% html_text(trim = TRUE) %>% str_subset(paste0("^", name)) })
关键修正点
- 替换
lapply为mapply/map2,让每个HTML内容与对应行的议员姓名一一对应 - 在筛选时,仅使用当前行的
name_surname值作为匹配前缀,确保只提取该议员的演讲内容
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

