Отправить строку SQL через POST с пакетом httr в R - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь загрузить файл с этого сайта https://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=289. Форма на этом сайте генерирует ссылку POST, которая отправляет запрос на их сервер, чтобы создать временный файл, хранящийся здесь https://transtats.bts.gov/ftproot/TranStatsData/.

Что касается данных формы, я вижу следующее:

UserTableName: DB1BCoupon
DBShortName: 
RawDataTable: T_DB1B_COUPON
sqlstr: +SELECT+ORIGIN_AIRPORT_ID%2CORIGIN_AIRPORT_SEQ_ID%2CORIGIN_CITY_MARKET_ID%2CDEST_AIRPORT_ID%2CDEST_AIRPORT_SEQ_ID%2CDEST_CITY_MARKET_ID+FROM++T_DB1B_COUPON+WHERE+Quarter+%3D1+AND+YEAR%3D2017
varlist: ORIGIN_AIRPORT_ID%2CORIGIN_AIRPORT_SEQ_ID%2CORIGIN_CITY_MARKET_ID%2CDEST_AIRPORT_ID%2CDEST_AIRPORT_SEQ_ID%2CDEST_CITY_MARKET_ID

На основании вышеизложенного и с пакетом httr я пробовал следующее:

library(httr)

web <- https://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=289

POST(web, body = "+SELECT+ORIGIN_AIRPORT_ID%2CORIGIN_AIRPORT_SEQ_ID%2CORIGIN_CITY_MARKET_ID%2CDEST_AIRPORT_ID%2CDEST_AIRPORT_SEQ_ID%2CDEST_CITY_MARKET_ID+FROM++T_DB1B_COUPON+WHERE+Quarter+%3D1+AND+YEAR%3D2017", encode = "form")

Теперь я ожидаю получить заголовок ответа со следующей информацией:

Location: https://transtats.bts.gov/ftproot/TranStatsData/847324776_T_DB1B_COUPON.zip

Однако по какой-то причине я не могу этого получить.Я уверен, что код для POST неверен, но я не уверен, где и что я делаю неправильно.

1 Ответ

0 голосов
/ 14 октября 2018

Лучше поздно, чем никогда (для ответа)?

То, что POST является сверхсложным, и сайт перенаправляет его после обработки на другой GET, чтобы получить содержимое ZIP.

enter image description here

Щелкните правой кнопкой мыши строку POST и выберите «Копировать как cURL».После этого вообще не модифицируйте буфер обмена, затем используйте curlconverter, чтобы превратить его в функцию R:

library(curlconverter)

straighten() %>% make_req() -> tmp # it automagically uses the clipboard contents

Нажмите «вставить» в вашей ОС, и вы получитеболее длинная версия этого:

httr::POST(
  url = "https://www.transtats.bts.gov/DownLoad_Table.asp",
  httr::add_headers(
    Referer = "https://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=289"
  ),
  body = list(
    UserTableName = "DB1BCoupon",
    DBShortName = "", 
    RawDataTable = "T_DB1B_COUPON",
    sqlstr = " SELECT ORIGIN_AIRPORT_ID,ORIGIN_AIRPORT_SEQ_ID,ORIGIN_CITY_MARKET_ID,DEST_AIRPORT_ID,DEST_AIRPORT_SEQ_ID,DEST_CITY_MARKET_ID FROM T_DB1B_COUPON WHERE Quarter=1 AND YEAR=2018",
    varlist = "ORIGIN_AIRPORT_ID,ORIGIN_AIRPORT_SEQ_ID,ORIGIN_CITY_MARKET_ID,DEST_AIRPORT_ID,DEST_AIRPORT_SEQ_ID,DEST_CITY_MARKET_ID",
    grouplist = "", suml = "",
    sumRegion = "", filter1 = "title=",
    filter2 = "title=", geo = "All\xa0",
    time = "Q+1", timename = "Quarter",
    GEOGRAPHY = "All", XYEAR = "2018",
    FREQUENCY = "1", 
    VarDesc = "ItinID", VarType = "Num", 
    VarDesc = "MktID", VarType = "Num", 
    VarDesc = "SeqNum", VarType = "Num", 
    VarDesc = "Coupons", VarType = "Num", 
    VarDesc = "Year", VarType = "Num", VarName = "ORIGIN_AIRPORT_ID", 
    VarDesc = "OriginAirportID", VarType = "Num", VarName = "ORIGIN_AIRPORT_SEQ_ID", 
    VarDesc = "OriginAirportSeqID", VarType = "Num", VarName = "ORIGIN_CITY_MARKET_ID", 
    VarDesc = "OriginCityMarketID", VarType = "Num", 
    VarDesc = "Quarter", VarType = "Num", 
    VarDesc = "Origin", VarType = "Char", 
    VarDesc = "OriginCountry", VarType = "Char", 
    VarDesc = "OriginStateFips", VarType = "Char", 
    VarDesc = "OriginState", VarType = "Char", 
    VarDesc = "OriginStateName", VarType = "Char", 
    VarDesc = "OriginWac", VarType = "Num", VarName = "DEST_AIRPORT_ID", 
    VarDesc = "DestAirportID", VarType = "Num", VarName = "DEST_AIRPORT_SEQ_ID", 
    VarDesc = "DestAirportSeqID", VarType = "Num", VarName = "DEST_CITY_MARKET_ID", 
    VarDesc = "DestCityMarketID", VarType = "Num", 
    VarDesc = "Dest", VarType = "Char", 
    VarDesc = "DestCountry", VarType = "Char", 
    VarDesc = "DestStateFips", VarType = "Char", 
    VarDesc = "DestState", VarType = "Char", 
    VarDesc = "DestStateName", VarType = "Char", 
    VarDesc = "DestWac", VarType = "Num", 
    VarDesc = "Break", VarType = "Char", 
    VarDesc = "CouponType", VarType = "Char", 
    VarDesc = "TkCarrier", VarType = "Char", 
    VarDesc = "OpCarrier", VarType = "Char", 
    VarDesc = "RPCarrier", VarType = "Char", 
    VarDesc = "Passengers", VarType = "Num", 
    VarDesc = "FareClass", VarType = "Char", 
    VarDesc = "Distance", VarType = "Num", 
    VarDesc = "DistanceGroup", VarType = "Num", 
    VarDesc = "Gateway", VarType = "Num", 
    VarDesc = "ItinGeoType", VarType = "Num", 
    VarDesc = "CouponGeoType", VarType = "Num"
  ), 
  encode = "form",
  query = list(
    Table_ID = "289",
    Has_Group = "0", 
    Is_Zipped = "0"
  )
) -> res

(да, даже длиннее , чем было)

Параметр sqlstr содержит запрос SQL, и яне уверен, сколько из этого POST "требуется" или нет, но это "сработало для меня"

res определенно велико и содержит двоичные данные zip'd:

res
## Response [https://transtats.bts.gov/ftproot/TranStatsData/351117019_T_DB1B_COUPON.zip]
##   Date: 2018-10-14 02:18
##   Status: 200
##   Content-Type: application/x-zip-compressed
##   Size: 14.6 MB
## <BINARY BODY>

Мы можем сохранить его на диск и убедиться, что он действителен:

(save_to <- file.path("~/Data", basename(grep("\\.zip", unlist(res$all_headers), value=TRUE))))
## [1] "~/Data/351117019_T_DB1B_COUPON.zip"

writeBin(httr::content(res, as="raw"), save_to)

unzip(save_to, list = TRUE)
##                          Name    Length                Date
## 1 351117019_T_DB1B_COUPON.csv 378311108 2018-10-13 22:18:00
...