首页 > 解决方案 > RVest:抓取访问受限的网站文本

问题描述

我目前正在使用 rvest 抓取一个新闻网站。刮板正在工作,但在新闻网站上,我只能有限地访问那里列出的独家文章。因此,我需要一个工作循环,当遇到某些选择器不可用的情况时,它不会停止。

最重要的是,我找不到合适的选择器来抓取整个文本。希望你能帮助我解决我的问题。

library(rvest)
sz_webp <- read_html ("https://www.sueddeutsche.de/news?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&all%5B%5D=time")

# TITLE

title <- sz_webp %>% 
  html_nodes("a em") %>%   
  html_text()

df <- data.frame(title)

# TIME

time <- sz_webp %>% 
  html_nodes("div time") %>%   
  html_text() 

df$time <- time

url <- sz_webp %>% 
  html_nodes("a") %>% html_attr('href')

url <- url[which(regexpr('https://www.sueddeutsche.de/', url) >= 1)]
N <- 58
n_url <- tail(url, -N)

n_url <- head(n_url,-17)

View(n_url)

df$url <- n_url

# LOOP THAT DOESNT WORK (not the right selector and it cancels when facing the problem)

results_df <- lapply(n_url, function(u) { 
  message(u) 

  aktuellerlink <- read_html(u) # liest die jeweilige URL ein

  text <- aktuellerlink %>% # liest das Baujahr aus
    html_nodes("div p") %>%
    html_text()

  } %>%

bind_rows()
)
df$text <- results_df

View(df)

提前非常感谢。

标签: htmlrweb-scrapingrvest

解决方案


我对网站不熟悉。我也看不懂德语。就我看到您的代码而言,您正在尝试使用sz_webp. 然后,对于每个 url,您尝试抓取文本。我认为您可以通过关注链接中的特定部分来改进您的代码。如果您查看源页面,您可以识别位置。你有你需要刮的特定位置。

livrary(rvest)
library(tidyverse)

map_dfc(.x = c("em.entrylist__title", "time.entrylist__time"),
        .f = function(x) {read_html("https://www.sueddeutsche.de/news?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&all%5B%5D=time") %>% 
                          html_nodes(x) %>% 
                          html_text()}) %>% 
bind_cols(url = read_html("https://www.sueddeutsche.de/news?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&all%5B%5D=time") %>% 
                html_nodes("a.entrylist__link") %>% 
                html_attr("href")) %>% 
setNames(nm = c("title", "time", "url")) -> temp

temp看起来像这样。如果你愿意,你需要清理time。它仍然很乱。

   title                                       time              url                                                                  
   <chr>                                       <chr>             <chr>                                                                
 1 "Immer mehr Corona-Infektionen in China"    "\n    13:23\n"   https://www.sueddeutsche.de/politik/immer-mehr-corona-infektionen-in~
 2 "US-Amerikaner an Corona-Virus gestorben"   "\n    08:59\n"   https://www.sueddeutsche.de/panorama/virus-infektion-us-amerikaner-a~
 3 "Frau eines weiteren Webasto-Mitarbeiters ~ "\n    07.02.202~ https://www.sueddeutsche.de/bayern/coronavirus-bayern-newsblog-muenc~
 4 "Digitale Revolte"                          "\n    07.02.202~ https://www.sueddeutsche.de/politik/china-digitale-revolte-1.4788941 
 5 "Nachrichten kompakt - die Übersicht für E~ "\n    07.02.202~ https://www.sueddeutsche.de/politik/nachrichten-thueringen-kemmerich~
 6 "\"Ich würde mir wünschen, dass die Mensch~ "\n    07.02.202~ https://www.sueddeutsche.de/wirtschaft/webasto-coronavirus-bayern-in~
 7 "Deutschland will weitere Bürger zurückhol~ "\n    07.02.202~ https://www.sueddeutsche.de/politik/coronavirus-deutschland-will-wei~
 8 "Peking wird wegenzur \"Geisterstadt\""     "\n    07.02.202~ https://www.sueddeutsche.de/panorama/angst-vor-corona-peking-wird-we~
 9 "Was bedeutet die Corona-Epidemie für Chin~ "\n    07.02.202~ https://www.sueddeutsche.de/politik/coronavirus-wuhan-li-wenliang-1.~
10 "Virus des Widerstands"                     "\n    07.02.202~ https://www.sueddeutsche.de/politik/china-coronavirus-arzt-1.4788564 

然后,对于每个 URL,您要抓取文本。我不确定这个网页是如何工作的。但是我检查了一些,发现每个链接表面上可以有多篇文章。是对的吗?内容停留在div.sz-article__body. 你必须进一步选择<p>sz-teaser__summary上课。然后,您可以抓取您可能正在寻找的内容。在这里,我循环了三个链接。第一个不提供任何文本。也许这就是您正在谈论的那个;不可访问的内容。我希望这足以让你取得进一步的进步。

map_df(.x = temp$url[1:3],
       .f = function(x){tibble(url = x,
                        text = read_html(x) %>% 
                                html_nodes("div.sz-article__body") %>% 
                                html_nodes("p:not(.sz-teaser__summary)") %>% 
                                html_text() %>% 
                                list
                        )}) %>% 
unnest(text) -> foo

foo

   url                                                        text                                                                    
   <chr>                                                      <chr>                                                                   
 1 https://www.sueddeutsche.de/panorama/virus-infektion-us-a~ "In Wuhan ist ein Amerikaner an einer Corona-Infektion gestorben. Wie d~
 2 https://www.sueddeutsche.de/panorama/virus-infektion-us-a~ "Auch ein Japaner starb nach Einschätzung des Tokioter Außenministerium~
 3 https://www.sueddeutsche.de/panorama/virus-infektion-us-a~ "Bisher sind außerhalb Festland-Chinas zwei Todesfälle infolge einer Co~
 4 https://www.sueddeutsche.de/panorama/virus-infektion-us-a~ "Damit könnte sie in Kürze die weltweit offiziell registrierten 774 Tod~
 5 https://www.sueddeutsche.de/panorama/virus-infektion-us-a~ "Coronavirus"                                                           
 6 https://www.sueddeutsche.de/bayern/coronavirus-bayern-new~ "Freitag, 7. Februar, 19.37 Uhr In Bayern gibt es einen weiteren Corona~
 7 https://www.sueddeutsche.de/bayern/coronavirus-bayern-new~ "Freitag, 7. Februar, 18.19 Uhr: Der Coronavirus-Ausbruch hat den bayer~
 8 https://www.sueddeutsche.de/bayern/coronavirus-bayern-new~ "Freitag, 7. Februar, 15.05 Uhr: Der Verdacht, der bayerische Coronavir~
 9 https://www.sueddeutsche.de/bayern/coronavirus-bayern-new~ "Die bayerischen Fälle gehen alle auf betriebsinterne Schulungen in der~
10 https://www.sueddeutsche.de/bayern/coronavirus-bayern-new~ "Donnerstag, 6. Februar, 13.35 Uhr: In Bayern hat sich eine weitere Fra~

推荐阅读