2016-10-18 9 views
1

私は多くを検索しましたが、私の問題の良い解決策を見つけることができませんでした。R - JSONストリームの解析に関する問題

私は自分の仕事の一部を自動化しようとしており、私の会社が使用しているサイトからいくつかのデータを削り取っています。 (FYI - 。。TOSは、彼らが誰でもだから私は良いことがあり迷っている場合には掻き取りしたくないを示していないように見えます)

をこれまでのところ、私はこの時に以下のコード

library(devtools) 
library(RSelenium) 
library(XML) 
library(rvest) 
library(stringr) 
library(dplyr) 
library(knitr) 
library(magrittr) 
library(rjson) 
library(stringi) 

#login 
appURL <- 'URL I Am accessing/' 
pJS <- phantom() 
remDr <- remoteDriver(browserName = "phantomjs") 
remDr$open() 
remDr$maxWindowSize() 
remDr$navigate(appURL) 
UN <- remDr$findElement(using = 'xpath', "//*[@id='login-form']/div[2]/div[2]/input") 
UN$sendKeysToElement(list("Username")) 
PW <- remDr$findElement(using = 'xpath', "//*[@id='login-form']/div[2]/div[3]/input") 
PW$sendKeysToElement(list("password", key = "enter")) 

URL <- 'URL of page with data' 
remDr$navigate(URL) 
Sys.sleep(2) 

Source <- remDr$getPageSource()[[1]] 

Text <- read_xml(Source,encoding = "", as_html = F, options = "NOBLANKS") %>% 
    xml_text(trim = T) 

Text <- unlist(Text) 

を持っていますポイントは、私は、JSONを含むテキストの多くを持っていますが、JSONは、このように構成されています

私は必要なJSONは、イベントに関連したJSONで
event: optionCollection 
id: 229 
data: [{JSON}] 

: 

event: pageDescription 
id: 230 
data: [{JSON}] 

: 
event: dataTable.headerRows 

id: 232 
data: [{JSON}] 
: 
event: dataTable.dataRows 
id: 233 
data: [{JSON}] 

:dataTable.headerRowsとdataTable.dataRows。

通常、データの抽出に必要な複数のdataRowsイベントがあります。

誰でもRにこれらを取得する方法についての提案はできますか?

ご意見やご不明な点がございましたら、私にご連絡ください。

ありがとうございます!

*編集 - リクエストごとに現在のライブラリを追加しました。

*編集 - @Parfaitこれは返されるものです。私はコードが動作するはずと思われるので、問題の原因をクリアしておりませんので

$event 
[1] "report.finished" 

$id 
[1] "2277" 

$data 
[1] "{\"status\":1}" 

$event 
[1] "report.finished" 


$id 
[1] "2277" 

$data 
[1] "{\"status\":1}" 

これは一度だけtempfile.txtに表示されます。ここで

は、あなたがあなたの記事で提供されるサンプルの代わりにデータが書き込まTMPFILEです:

https://1drv.ms/t/s!AlEviX19YBNogaZGAHCUCC_ZDEI5OA

+0

を記載してください(例リピートJSONを使用して)すべての ' library() '行を使用して正しく再現することができます。 – Parfait

+0

@Parfaitはライブラリ()を追加しました。 –

+0

が 'Text'のすべてのJSONか' [{JSON}]セクションのちょうどのビットであると私は考えていませんか?それがすべてのJSONでない場合、どのような構造ですか? – SymbolixAU

答えて

1

readLines()と線で文字列のラインを読み、イベントのリストの構築を検討しますidおよびデータの項目です。ここで、データはjson文字列になります。しかし、まず文字列をwriteLines()でファイルにダンプしてください。コロンだけの行はリスト要素の間の区切り文字として使用され、あなたがそれを持っているように表示される必要があります:

writeLines(Text, "tempfile.txt")        # CREATE TEMP FILE 
con <- file("tempfile.txt", open="r")       # OPEN CONNECTION 

datalist <- c() 
while (length(line <- readLines(con, n=1, warn = FALSE)) > 0) {  
    if (grepl("event:", line)==TRUE){ 
    eventitem <- gsub("event: ", "", line)      # EVENT LINE 
    } 
    else if (grepl("id:", line)==TRUE){ 
    iditem <- gsub("id: ", "", line)       # ID LINE 
    } 
    else if (grepl("data:", line)==TRUE){ 
    dataitem <- gsub("data: ", "", line)      # DATA LINE 
    } 
    else if (grepl("^:", line)==TRUE) { 
    # COLON ONLY-LINE (APPENDING NESTED LIST ITEMS) 
    datalist <- c(datalist, list(event=eventitem, id=iditem, data=dataitem)) 
    } 
    else { 
    dataitem <- paste0(dataitem, gsub("data: ", "", line))  # ADD DATA LINES 
    } 
} 

# REMAINING LAST LIST ITEMS 
datalist <- c(datalist, list(event=eventitem, id=iditem, data=dataitem)) 
close(con)              # CLOSE CONNECTION 

unlink("tempfile.txt")           # DELETE TEMP FILE 

出力

$event 
[1] "optionCollection"  
$id 
[1] "229"  
$data 
[1] "[{\"sales\": {\"sales_val\": 22549,\"units_in_stock\": 
    251,\"product_id\": \"0141602\"},\"sales\": {\"sales_val\": 
    22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"},\"sales\": 
    {\"sales_val\": 22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"}}]" 

$event 
[1] "pageDescription"  
$id 
[1] "230"  
$data 
[1] "[{\"sales\": {\"sales_val\": 22549,\"units_in_stock\": 
    251,\"product_id\": \"0141602\"},\"sales\": {\"sales_val\": 
    22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"},\"sales\": 
    {\"sales_val\": 22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"}}]" 

$event 
[1] "dataTable.headerRows"  
$id 
[1] "232"  
$data 
[1] "[{\"sales\": {\"sales_val\": 22549,\"units_in_stock\": 
    251,\"product_id\": \"0141602\"},\"sales\": {\"sales_val\": 
    22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"},\"sales\": 
    {\"sales_val\": 22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"}}]" 

$event 
[1] "dataTable.dataRows"  
$id 
[1] "233"  
$data 
[1] "[{\"sales\": {\"sales_val\": 22549,\"units_in_stock\": 
    251,\"product_id\": \"0141602\"},\"sales\": {\"sales_val\": 
    22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"},\"sales\": 
    {\"sales_val\": 22549,\"units_in_stock\": 251,\"product_id\": \"0141602\"}}]" 
+0

これは素晴らしいですが、うまくいきませんでした。私がリストを返すとき、私はリストからの最後のアイテムを2回だけ得る。 –

+0

問題が見つかりました。コロンのみの状態で、grepl: '(grepl(" ^: "、行)== TRUE)'のドル記号を削除します。恐らく、コロンの後ろにスペースがあります。 – Parfait

+0

優れた答えをありがとう!それがそれを解決しました。 –