2016-10-26 10 views
1

グレイハウンドのバスタイミングに関するHTMLデータを読もうとしています。 An example can be found here.私はテーブルからスケジュールやステータスデータを取得して、主に心配、私は次のコードを実行すると:グレイハウンドからHTMLテーブルを読み込みます。

library(XML) 

url<-"http://bustracker.greyhound.com/routes/4511/I/Chicago_Amtrak_IL-Cincinnati_OH/4511/10-26-2016" 
greyhound<-readHTMLTable(url) 

greyhound<-greyhound[[2]] 

これは、単に、次の表を生成します。

enter image description here

私は」

答えて

1

readHTMLTableを使用してデータを取得することはできません。なぜなら、結果はjavascriptスクリプトとして送信されるからです。そのスクリプトを選択して解析し、適切な情報を抽出する必要があります。

彼女がこれを行うソリューション、:

  1. JSONデータが含まれているJavaScriptのスクリプトは正規表現
  2. を使用してスクリプトからJSONデータをRにJSONデータを解析抽出エキスリスト
  3. は、コードが多分SHに見える

(ここではdata.table)テーブルになったリストをリシェイプそれは本当にコンパクトです(それを作るのに1時間かかります)!

library(XML) 
library(httr) 
library(jsonlite) 
library(data.table) 
dc <- htmlParse(GET(url)) 
script <- xpathSApply(dc,"//script/text()",xmlValue)[[5]] 

res <- strsplit(script,"stopArray.push({",fixed=TRUE)[[1]][-1] 
dcast(point~name,data=rbindlist(Map(function(x,y){ 
         x <- paste('{',sub(');|);.*docum.*',"",x)) 
         dx <- unlist(fromJSON(x)) 
         data.frame(point=y,name=names(dx),value=dx) 
        },res,seq_along(res)) 
,fill=TRUE)[name!="polyline"]) 

テーブル結果:@agstudyノートとして

point category direction  id    lat     linkName    lon 
1:  1  2  empty 562310 41.878589630127   Chicago_Amtrak_IL -87.6398544311523 
2:  2  2  empty 560252 41.8748474121094     Chicago_IL -87.6435165405273 
3:  3  1  empty 561627 41.7223281860352 Chicago_95th_&_Dan_Ryan_IL -87.6247329711914 
4:  4  2  empty 260337 41.6039199829102     Gary_IN -87.3386917114258 
5:  5  1  empty 260447 40.4209785461426    Lafayette_e_IN -86.8942031860352 
6:  6  2  empty 260392 39.7617835998535   Indianapolis_IN -86.161018371582 
7:  7  2  empty 250305 39.1079406738281    Cincinnati_OH -84.5041427612305 
               name     shortName ticketName 
1:  Chicago Amtrak: 225 S Canal St, IL 60606   Chicago Amtrak, IL  CHD 
2:   Chicago: 630 W Harrison St, IL 60607     Chicago, IL  CHD 
3: Chicago 95th & Dan Ryan: 14 W 95th St, IL 60628 Chicago 95th & Dan Ryan, IL  CHD 
4:     Gary: 100 W 4th Ave, IN 46402     Gary, IN  GRY 
5:   Lafayette (e): 401 N 3rd St, IN 47901   Lafayette (e), IN  XIN 
6:  Indianapolis: 350 S Illinois St, IN 46225   Indianapolis, IN  IND 
7:   Cincinnati: 1005 Gilbert Ave, OH 45202    Cincinnati, OH  CIN 
+0

ありがとうございました。私は間違っていたところを多く説明しました。また、@Michael Griffithsから、stopArray自体がデータをどのように格納しているのかがわかります。そこからGreyhoundウェブサイトがテーブルの値の大部分(停止名や住所など)にどのように入力されているかがわかります。 ソースコードを見ると、ウェブサイトがスケジュールとステータスのタイミングをどこから取得したのか正確に特定するのに問題があります。 – sdr1975

0

、データがHTMLへをレンダリングされます。サーバーから直接HTML経由で配信されることはありません。したがって、(a)レンダリングされたコンテンツを擦るためにRSeleniumのようなものを使用するか、または(b)データを含む<script>タグからデータを抽出することができます。

@ agstudyの仕事について説明するために、データは一連のstopArray.push()コマンド(多くの)スクリプトタグの1つに含まれていることがわかりました。たとえば:

stopArray.push({ 
    "id" : "562310", 
    "name" : "Chicago Amtrak: 225 S Canal St, IL 60606", 
    "shortName" : "Chicago Amtrak, IL", 
    "ticketName" : "CHD", 
    "category" : 2, 
    "linkName" : "Chicago_Amtrak_IL", 
    "direction" : "empty", 
    "lat" : 41.87858963012695, 
    "lon" : -87.63985443115234, 
    "polyline" : "elr~Fnb|[email protected]@[email protected][email protected][email protected]`[email protected]`CCzBC~BE|CEdCA^[email protected]" 
}); 

さて、これは各関数呼び出しの内部に含まれるjsonデータです。私は誰かが機械可読フォーマットでデータをフォーマットする作業に踏み込んだとしても、それを感謝しなければならないと思う傾向があります。次のようにこの問題への

tidyverseアプローチがある:

  1. rvestパッケージを使用してページをダウンロードしてください。
  2. 文字url =を含むscriptタグをすべて検索するxpath式を使用して、使用する適切なscriptタグを特定します。
  3. 正規表現を使用して、各stopArray.push()コール内のすべてを引き出します。
  4. (a)各ブロックをカンマで区切って、(b)[]で文字列を囲んでjsonのリストを示すように、結果のオブジェクトの書式設定を修正します。
  5. jsonlite::fromJSONを使用してdata.frameに変換してください。

最後に近いpolyline列は、あまりにも大きすぎるため適切ではないため、非表示にします。

library(tidyverse) 
library(rvest) 
library(stringr) 
library(jsonlite) 

url <- "http://bustracker.greyhound.com/routes/4511/I/Chicago_Amtrak_IL-Cincinnati_OH/4511/10-26-2016" 
page <- read_html(url) 

page %>% 
    html_nodes(xpath = '//script[contains(text(), "url = ")]') %>% 
    html_text() %>% 
    str_extract_all(regex("(?<=stopArray.push\\().+?(?=\\);)", multiline = T, dotall = T), F) %>% 
    unlist() %>% 
    paste(collapse = ",") %>% 
    sprintf("[%s]", .) %>% 
    fromJSON() %>% 
    select(-polyline) %>% 
    head() 
#>  id           name 
#> 1 562310  Chicago Amtrak: 225 S Canal St, IL 60606 
#> 2 560252   Chicago: 630 W Harrison St, IL 60607 
#> 3 561627 Chicago 95th & Dan Ryan: 14 W 95th St, IL 60628 
#> 4 260337     Gary: 100 W 4th Ave, IN 46402 
#> 5 260447   Lafayette (e): 401 N 3rd St, IN 47901 
#> 6 260392  Indianapolis: 350 S Illinois St, IN 46225 
#>      shortName ticketName category 
#> 1   Chicago Amtrak, IL  CHD  2 
#> 2     Chicago, IL  CHD  2 
#> 3 Chicago 95th & Dan Ryan, IL  CHD  1 
#> 4     Gary, IN  GRY  2 
#> 5   Lafayette (e), IN  XIN  1 
#> 6   Indianapolis, IN  IND  2 
#>      linkName direction  lat  lon 
#> 1   Chicago_Amtrak_IL  empty 41.87859 -87.63985 
#> 2     Chicago_IL  empty 41.87485 -87.64352 
#> 3 Chicago_95th_&_Dan_Ryan_IL  empty 41.72233 -87.62473 
#> 4     Gary_IN  empty 41.60392 -87.33869 
#> 5    Lafayette_e_IN  empty 40.42098 -86.89420 
#> 6   Indianapolis_IN  empty 39.76178 -86.16102 
関連する問題