web-dev-qa-db-ja.com

複数のページにわたるRWebスクレイピング

私は特定のワインを検索し、その種類の地元のワインのリストを返すためのWebスクレイピングプログラムに取り組んでいます。私が抱えている問題は、複数ページの結果です。以下のコードは、私が取り組んでいるものの基本的な例です

url2 <- "http://www.winemag.com/?s=washington+merlot&search_type=reviews"
htmlpage2 <- read_html(url2)
names2 <- html_nodes(htmlpage2, ".review-listing .title")
Wines2 <- html_text(names2)

この特定の検索では、39ページの結果があります。 URLが http://www.winemag.com/?s=washington%20merlot&drink_type=wine&page=2 に変更されることは知っていますが、返されたすべてのページでコードをループさせる簡単な方法はありますか? 39ページすべての結果を1つのリストにまとめますか?私はすべてのURLを手動で実行できることを知っていますが、それはやり過ぎのようです。

8
Jamie Leigh

すべての情報を_data.frame_として必要な場合は、purrr::map_df()でも同様のことができます。

_library(rvest)
library(purrr)

url_base <- "http://www.winemag.com/?s=washington merlot&drink_type=wine&page=%d"

map_df(1:39, function(i) {

  # simple but effective progress indicator
  cat(".")

  pg <- read_html(sprintf(url_base, i))

  data.frame(wine=html_text(html_nodes(pg, ".review-listing .title")),
             excerpt=html_text(html_nodes(pg, "div.excerpt")),
             rating=gsub(" Points", "", html_text(html_nodes(pg, "span.rating"))),
             appellation=html_text(html_nodes(pg, "span.appellation")),
             price=gsub("\\$", "", html_text(html_nodes(pg, "span.price"))),
             stringsAsFactors=FALSE)

}) -> wines

dplyr::glimpse(wines)
## Observations: 1,170
## Variables: 5
## $ wine        (chr) "Charles Smith 2012 Royal City Syrah (Columbia Valley (WA)...
## $ excerpt     (chr) "Green olive, green stem and fresh herb aromas are at the ...
## $ rating      (chr) "96", "95", "94", "93", "93", "93", "93", "93", "93", "93"...
## $ appellation (chr) "Columbia Valley", "Columbia Valley", "Columbia Valley", "...
## $ price       (chr) "140", "70", "70", "20", "70", "40", "135", "50", "60", "3...
_
16
hrbrmstr

URLのベクトル全体でlapplyできます。これは、ベースURLをシーケンスに貼り付けることで作成できます。

library(rvest)

wines <- lapply(paste0('http://www.winemag.com/?s=washington%20merlot&drink_type=wine&page=', 1:39),
                function(url){
                    url %>% read_html() %>% 
                        html_nodes(".review-listing .title") %>% 
                        html_text()
                })

結果は、各ページの要素を含むリストで返されます。

8
alistaire