2017-10-15 11 views
0

これは、a prior threadまでのフォローアップです。コードは1つの値に対して素晴らしいですが、1つ以上の値を渡そうとすると次のエラーが出ます。関数の長さに基づいてエラーが発生します。 vapply(要素、エンコード、文字(1))で エラー: 値でなければならない長さ1、 しかしFUN(X [1])結果は、ここrvest送信フォームで複数の値を渡す方法

長さ3であるコードのサンプルです。ほとんどの場合、私はオブジェクトに名前を付けてそのようにすることができました。

library(httr) 
library(rvest) 
library(dplyr) 

b<-c('48127','48180','49504') 

POST(
url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl", 
body = list(zipcode = b), 
encode = "form" 
) -> res 

フォームに値を挿入するためのループが行くための正しい方法だろうかと思いまして?しかし私のループ・ライティング・スキルはまだ開発中であり、どこに置くのかは分かりません。さらに、私はループを呼び出すときに行ごとに出力されません、それは単にnullの結果を返します。ここ

#d isn't listed in the above code as it returns null  
d<-for(i in 1:3){nrow(b)} 

答えて

0

Bの各要素について、複数のPOSTリクエストを

library(httr) 
library(rvest) 
b <- c('48127','48180','49504') 

を送信するためのアプローチは、各要素のための今すぐ適切なPOSTリクエスト

res <- lapply(b, function(x){ 
    res <- POST(
    url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl", 
    body = list(zipcode = x), 
    encode = "form" 
) 
    res <- read_html(content(res, as="raw")) 
}) 

を送信する機能を実行ありますリストres hrbrmstrで説明されている解析手順を実行する必要があります。How can I Scrape a CGI-Bin with rvest and R?

library(tidyverse) 

彼は王様だから、私はhrbrmstrのコードを使用します。あなたにはすでに明らかです。ここでは、resリストの各要素でそれを実行しているだけです。

res_list = lapply(res, function(x){ 
    rows <- html_nodes(x, "table[width='300'] > tr > td") 
    ret <- data_frame(
    record = !is.na(html_attr(rows, "bgcolor")), 
    text = html_text(rows, trim=TRUE) 
    ) %>% 
    mutate(record = cumsum(record)) %>% 
    filter(text != "") %>% 
    group_by(record) %>% 
    summarise(x = paste0(text, collapse="|")) %>% 
    separate(x, c("store", "address1", "city_state_zip", "phone_and_or_distance"), sep="\\|", extra="merge") 
    return(ret) 
} 
) 

またはmap

purrrから
res %>% 
    map(function(x){ 
    rows <- html_nodes(x, "table[width='300'] > tr > td") 
    data_frame(
     record = !is.na(html_attr(rows, "bgcolor")), 
     text = html_text(rows, trim=TRUE) 
    ) %>% 
     mutate(record = cumsum(record)) %>% 
     filter(text != "") %>% 
     group_by(record) %>% 
     summarise(x = paste0(text, collapse="|")) %>% 
     separate(x, c("store", "address1", "city_state_zip", "phone_and_or_distance"), 
       sep="\\|", extra="merge") -> ret 
    return(ret) 
    } 
) 

を使用して、あなたは、データフレームでこれを希望の場合:

res_df <- data.frame(do.call(rbind, res_list), #rbinds list elements 
        b = rep(b, times = unlist(lapply(res_list, length)))) #names the rows according to elements in b 
+0

この作品は幻想的にうまくいきましたが、今ではループのどこで間違っているのか理解しています。 Webブラウザ用の開発者用ツールの推奨読書は?より高度なRに役立つものもありますか?私はSAMSとSwirlのライブラリから学んだが、私は多くのことが欠けているように感じる。 – Turbogoon

+0

@Turbogoonはスクラップしたデータを解析するためには 'xpath'と' regex'を学ぶのが有益でしょう。どんなプログラミング言語でも普遍的ですので、次に何をするにしてもよく時間を費やしています。ブラウザの要求に何が含まれているかを知るために(これをRでエミュレートすることができます)、Burpsuiteが便利になるかもしれません。どのRユーザーも 'apply'グループの関数に慣れるべきです。最新のデータクリーンアップアプローチのほとんどは、一部またはすべての 'tidyverse'ライブラリを利用しています。 'filter'、' group_by'、 'summarises'、' map'、 'separate'、' mutate'のような関数はすべて 'tidyverse'の一部です。 – missuse

+0

追加のリソースをありがとう。私はxpathと正規表現を読み上げます。私は整頓に慣れていますが、私はまだ苦労しています。私は〜90日間Rを使っていました。私の以前のクリーニング方法はSQLであり、なぜtidyverseがより効率的であるかが分かります。私は本当に本当にそれを感謝します! – Turbogoon

0

あなたは以下のようにポスト内の値を置くことができ、

b<-c('48127','48180','49504') 

    for(i in 1:length(b)) { 

    POST(
    url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl", 
    body = list(zipcode =b[i]), 
    encode = "form" 
    ) -> res 

    # YOUR CODES HERE (for getting content of the page etc.) 

    } 

しかし、すべての異なる郵便番号の値は "res"の値が異なるので、コメントした領域の中に残りのコードを置く必要があります。それ以外の場合は、最後の値のみを取得します。

関連する問題