【问题标题】:Parsing JSONP files using R使用 R 解析 JSONP 文件
【发布时间】:2016-01-29 16:54:56
【问题描述】:

这里是 JSON 新手。您能否帮助使用 R 解析 JSON 文件。我确实尝试过 jsonlite 和 rjson,但不断出现错误。

以下是通过api检索到的数据。

data <- GET("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")

JSON 看起来像这样:

/**/_cb_findItemsByKeywords({
   "findItemsByKeywordsResponse":[
      {
         "ack":[
            "Success"
         ],
         "version":[
            "1.13.0"
         ],
         "timestamp":[
            "2016-01-29T16:36:25.984Z"
         ],
         "searchResult":[
            {
               "@count":"1",
               "item":[
                  {
                     "itemId":[
                        "371533364795"
                     ],
                     "title":[
                        "Harry Potter: Complete 8-Film Collection (DVD, 2011, 8-Disc Set)"
                     ],
                     "globalId":[
                        "EBAY-US"
                     ],
                     "primaryCategory":[
                        {
                           "categoryId":[
                              "617"
                           ],
                           "categoryName":[
                              "DVDs & Blu-ray Discs"
                           ]
                        }
                     ],
                     "galleryURL":[
                        "http:\/\/thumbs4.ebaystatic.com\/m\/mn5Agt0HFD89L7_-lqfrZZw\/140.jpg"
                     ],
                     "viewItemURL":[
                        "http:\/\/www.ebay.com\/itm\/Harry-Potter-Complete-8-Film-Collection-DVD-2011-8-Disc-Set-\/371533364795"
                     ],
                     "productId":[
                        {
                           "@type":"ReferenceID",
                           "__value__":"110258144"
                        }
                     ],
                     "paymentMethod":[
                        "PayPal"
                     ],
                     "autoPay":[
                        "false"
                     ],
                     "postalCode":[
                        "60131"
                     ],
                     "location":[
                        "Franklin Park,IL,USA"
                     ],
                     "country":[
                        "US"
                     ],
                     "shippingInfo":[
                        {
                           "shippingServiceCost":[
                              {
                                 "@currencyId":"USD",
                                 "__value__":"0.0"
                              }
                           ],
                           "shippingType":[
                              "FlatDomesticCalculatedInternational"
                           ],
                           "shipToLocations":[
                              "US",
                              "CA",
                              "GB",
                              "AU",
                              "AT",
                              "BE",
                              "FR",
                              "DE",
                              "IT",
                              "JP",
                              "ES",
                              "TW",
                              "NL",
                              "CN",
                              "HK",
                              "MX",
                              "DK",
                              "RO",
                              "SK",
                              "BG",
                              "CZ",
                              "FI",
                              "HU",
                              "LV",
                              "LT",
                              "MT",
                              "EE",
                              "GR",
                              "PT",
                              "CY",
                              "SI",
                              "SE",
                              "KR",
                              "ID",
                              "ZA",
                              "TH",
                              "IE",
                              "PL",
                              "RU",
                              "IL"
                           ],
                           "expeditedShipping":[
                              "false"
                           ],
                           "oneDayShippingAvailable":[
                              "false"
                           ],
                           "handlingTime":[
                              "1"
                           ]
                        }
                     ],
                     "sellingStatus":[
                        {
                           "currentPrice":[
                              {
                                 "@currencyId":"USD",
                                 "__value__":"26.95"
                              }
                           ],
                           "convertedCurrentPrice":[
                              {
                                 "@currencyId":"USD",
                                 "__value__":"26.95"
                              }
                           ],
                           "sellingState":[
                              "Active"
                           ],
                           "timeLeft":[
                              "P16DT3H12M6S"
                           ]
                        }
                     ],
                     "listingInfo":[
                        {
                           "bestOfferEnabled":[
                              "false"
                           ],
                           "buyItNowAvailable":[
                              "false"
                           ],
                           "startTime":[
                              "2016-01-15T19:43:31.000Z"
                           ],
                           "endTime":[
                              "2016-02-14T19:48:31.000Z"
                           ],
                           "listingType":[
                              "StoreInventory"
                           ],
                           "gift":[
                              "false"
                           ]
                        }
                     ],
                     "returnsAccepted":[
                        "true"
                     ],
                     "condition":[
                        {
                           "conditionId":[
                              "1000"
                           ],
                           "conditionDisplayName":[
                              "Brand New"
                           ]
                        }
                     ],
                     "isMultiVariationListing":[
                        "false"
                     ],
                     "topRatedListing":[
                        "true"
                     ]
                  }
               ]
            }
         ],
         "paginationOutput":[
            {
               "pageNumber":[
                  "1"
               ],
               "entriesPerPage":[
                  "1"
               ],
               "totalPages":[
                  "138112"
               ],
               "totalEntries":[
                  "138112"
               ]
            }
         ],
         "itemSearchURL":[
            "http:\/\/www.ebay.com\/sch\/i.html?_nkw=harry+potter&_ddo=1&_ipg=1&_pgn=1"
         ]
      }
   ]
})

【问题讨论】:

    标签: json r jsonp jsonlite


    【解决方案1】:

    问题是您的数据不是json,而是JavaScript,确切地说是jsonp。如果你只想解析 JSON 数据,你必须去掉填充回调函数。

    req <- httr::GET("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=YOUR-APP-123456&GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")
    txt <- content(req, "text")
    json <- sub("/**/_cb_findItemsByKeywords(", "", txt, fixed = TRUE)
    json <- sub(")$", "", json)
    mydata <- jsonlite::fromJSON(json)
    

    额外功劳:或者,您可以使用实际的 JavaScript 引擎来解析 JavaScript:

    library(V8)
    ctx <- V8::v8()
    ctx$eval("var out;")
    ctx$eval("function _cb_findItemsByKeywords(x){out = x;}")
    ctx$source("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=YOUR-APP-123456&GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")
    mydata <- ctx$get("out")
    

    【讨论】:

    • 这很有帮助。非常感谢。
    • 找到了一个关于 JSONP 的附加信息的链接。 stackoverflow.com/questions/2067472/…
    • 能否请您澄清一下“$”在第二个 json 语句中的含义。我了解您正在尝试删除最后的“)”,但不确定 $ 的用法。请澄清。 json
    • 由于 mydata 的输出是一个列表。我试过 mydata2 中的 itemId 和 title 字段
    【解决方案2】:

    首先,您的 json 文件似乎有一点问题。它应该从左括号“[”开始。

    我删除了它之前的文本,并尝试了这段代码,效果很好:

    library(rjson)
    obj <- fromJSON(file = "v2.json")
    

    这会在obj 中返回一个列表,其中包含 v2.json 的内容。

    已编辑:包括功能齐全的解决方案:

    library(rjson)
    library(stringr)
    obj <- read.table("v2.json", sep = "\n", stringsAsFactors = FALSE, quote = "")
    
    # Gets the first line with the string "[" ("\\" for scape)
    firstline <- grep("\\[", obj[,1])[1]
    
    # Gets the position of the string "[" in the line
    fpos <- which(strsplit(obj[firstline, 1], "")[[1]] == "[")
    
    # Gets the last line with the string "]"
    lastline <- grep("\\]", obj[,1])
    lastline <- lastline[length(lastline)]
    
    # Gets the position of the string "]" in the line
    lpos <- which(strsplit(obj[lastline, 1], "")[[1]] == "]")
    
    # Changes the lines with the first "[" and the last "]" to keep the text
    # between both (after "[" and before "]") if there is any.
    obj[firstline, 1] <- str_sub(obj[firstline, 1], fpos)
    obj[lastline, 1] <- str_sub(obj[lastline, 1], 1, lpos)
    
    obj2 <- data.frame(obj[firstline:lastline, 1])
    write.table(obj2, "v3.json", row.names = FALSE, col.names = FALSE, quote = FALSE)
    
    obj3 <- fromJSON(file = "v3.json")
    

    【讨论】:

    • 嗨 Fernando - 这是通过 API 返回的数据。我也许可以使用 gsub 并删除第一个方格 [ 之前的初始字符,但是我还需要删除末尾的 2 个大括号 '})'。
    • 是的,我认为gsub() 与查找字符“[”和“]”位置的函数相结合将非常适合(也许像which(strsplit(line, "")[[1]] == "[") 这样的东西会起作用)。
    • 谢谢费尔南多。请您帮忙解释一下您提供的声明。
    • 我犯了一个错误。不是gsub(),我在想“stringr”函数str_sub()。我用完整的解决方案编辑了答案以解释我的意思。
    • @费尔南多。感谢费尔南多的详细解释。但是,当我运行代码时,我仍然遇到错误。注意:我使用的 .JSON 文件包含未格式化的文本 - 我已将其附加到我的问题中。请检查。
    猜你喜欢
    • 2012-03-16
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2013-05-20
    • 2023-02-18
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多