この問題と解決方法を明確にするために、次のように書き直して、関数と解決策を一例として底部に残しました。ヘルプのJohn Colemanにもう一度感謝します!ファンクションスローエラーはベクトルに適用されますが、1つの要素には適用されません
問題:私はこのエラーを投げ、URLのベクトルを1つのURLを渡すときに働いていたデータ掻き取り機能を作成しますが、ない:
Error in data.frame(address, recipename, prept, cookt, calories, protein, : arguments imply differing number of rows: 1, 14, 0
をそれはURLの一部がIだったことが判明スクラップしようとすると、指示セクションに別のタグがありました。これにより、xpathSApply
のスクラップが発生し、長さ0のリストが返され、rbindに渡されたときにエラーが発生しました。
問題の特定は、エラーが発生したページを見つけてそのページのHTML構造を調べるまで、各URLを実行するだけの問題でした。ここで
は、私はもともと書いた関数である:
f4fscrape <- function(url) {
#Create an empty dataframe
df <- data.frame(matrix(ncol = 11, nrow = 0))
colnames <- c('address', 'recipename', 'prept', 'cookt',
'calories', 'protein', 'carbs', 'fat',
'servings', 'ingredients', 'instructions')
colnames(df) <- paste(colnames)
#check for the recipe url in dataframe already,
#only carry on if not present
for (i in length(url))
if (url[i] %in% df$url) { next }
else {
#parse url as html
doc2 <-htmlTreeParse(url[i], useInternalNodes = TRUE)
#define the root node
top2 <- xmlRoot(doc2)
#scrape relevant data
address <- url[i]
recipename <- xpathSApply(top2[[2]], "//h1[@class='fn']", xmlValue)
prept <- xpathSApply(top2[[2]], "//span[@class='prT']", xmlValue)
cookt <- xpathSApply(top2[[2]], "//span[@class='ckT']", xmlValue)
calories <- xpathSApply(top2[[2]], "//span[@class='clrs']", xmlValue)
protein <- xpathSApply(top2[[2]], "//span[@class='prtn']", xmlValue)
carbs <- xpathSApply(top2[[2]], "//span[@class='crbs']", xmlValue)
fat <- xpathSApply(top2[[2]], "//span[@class='fat']", xmlValue)
servings <- xpathSApply(top2[[2]], "//span[@class='yld']", xmlValue)
ingredients <- xpathSApply(top2[[2]], "//span[@class='ingredient']", xmlValue)
instructions <- xpathSApply(top2[[2]], "//ol[@class='methodOL']", xmlValue)
#create a data.frame of the url and relevant data.
result <- data.frame(address, recipename, prept, cookt,
calories, protein, carbs, fat,
servings, list(ingredients), instructions)
#rename the tricky column
colnames(result)[10] <- 'ingredients'
#bind data to existing df
df <- rbind(df, result)
}
#return df
df
}
そして、ここでは、ソリューションです - 次のように私は単純に、条件を追加しました:
instructions <- xpathSApply(top2[[2]], "//ol[@class='methodOL']", xmlValue)
if (length(instructions) == 0) {
instructions <- xpathSApply(top2[[2]], "//ul[@class='b-list m-circle instrs']", xmlValue)}
注 - データスクレーピングで返される行の数は、各レシピの成分が異なるため、URLごとに異なります。 1つのセルにすべての成分を保存して、問題を解決する方法があれば、それはどうやって解決するのか、行の数が実際には問題になるかどうかはわかりません。 – ogriofac
いくつかの位置に「NA」をプレースホルダとして挿入する必要があるように聞こえます。 –
@ JohnColemanは、問題がrbindの行数に等しくないことを意味していますか? NAを挿入するように設定する方法がわからないのですが、rbindヘルプページに1つあるとは思われません。どのようにこれにアプローチする上の任意のアイデア?コメントありがとう! – ogriofac