Как получить .xml / .csv отчеты из публичного сайта - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь сделать запрос в разделе отчетов общедоступного веб-сайта, в разделе отчетов есть ряд конкретных отчетов, которые следуют примеру, приведенному ниже;

"https:[[web address]/[date][time]"

Однако перед выходом расширения .xml .csv обычно используется временной код выполнения отчета в формате HHMMSS.

.

Кто-нибудь может посоветовать лучший способ получения этих отчетов?

Настроены другие листы (Google Sheets), которые успешно извлекают отчет, когда пользователь вводит определенную дату. У них нет времени публикации отчета в конце, что делает их немного более простыми.

Ожидаемые результаты: пользователь вводит / выбирает дату, выходной файл .csv / .xml появится в Excel / Sheets.

РЕДАКТИРОВАТЬ: мне удалось заставить вышеуказанное работать для файлов .XML, .CSV оказывается более сложным, см. Ниже код, который я могу получить для получения результатов, но не отображаю информацию так же, как файлы .XML.

let
dateFrom = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateFrom"]}[Content][Column1]{0}, "yyyy-MM-dd"),
dateTo = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateTo"]}[Content][Column1]{0}, "yyyy-MM-dd"),
requestParameters = [page="1", sort_by="PublishTime", order_by="DESC", ReportName="ETS Bid File", ResourceName="BidFile_SEM-DA_PWR-MRC-D+1", date_from=dateFrom, date_to=dateTo, page_size="20"],
requestHeaders = [Accept="*/*", Origin="https://www.sem-o.com", Referer="https://www.sem-o.com/market-data/static-reports/index.xml", #"User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"],
json = Json.Document(Web.Contents("https://reports.semopx.com/api/v1/documents/static-reports", [Query=requestParameters, Headers=requestHeaders])),
documentsToRequest = List.Transform(json[items], each [DocumentUri = _[ResourceName]]),
toTable = Table.FromRecords(documentsToRequest, type table [DocumentUri = text]),
csvsOnly = Table.SelectRows(toTable, each Text.EndsWith([DocumentUri], ".csv"))

Заранее спасибо,

Ответы [ 2 ]

0 голосов
/ 03 июня 2019

Это дало мне CSV-файл для отчетов "ETS Bid File" для определенного диапазона дат.

Проблема в том, что файлы CSV, похоже, не имеют обычной структуры, разделенной запятыми. Похоже, они имеют несколько «строк заголовка» по всему файлу (что указывает на то, что в одном документе фактически имеется несколько файлов CSV).

Вам нужно будет изучить оставшееся преобразование для себя (поскольку вы не указали или не показали ожидаемый результат). Из-за нетрадиционного характера файлов CSV может быть лучше использовать Lines.FromBinary или Text.FromBinary вместо Csv.Document функции - и анализировать файл более специализированным / специализированным способом.

let
    dateFrom = Excel.CurrentWorkbook(){[Name = "dateFrom"]}[Content][Column1]{0},
    dateFromStringified = DateTime.ToText(dateFrom, "yyyy-MM-dd"),
    dateTo = Excel.CurrentWorkbook(){[Name = "dateTo"]}[Content][Column1]{0},
    dateToStringified = DateTime.ToText(dateTo, "yyyy-MM-dd"),
    requestParameters = [
        page = "1",
        sort_by = "PublishTime",
        order_by = "DESC",
        name = "BidFile_SEM-DA_PWR-MRC-D+1",
        group = "Market Data",
        date_from = dateFromStringified,
        date_to = dateToStringified,
        page_size = "20"
    ],
    requestHeaders = [
        Accept = "*/*",
        Origin = "https://www.semopx.com",
        Referer = "https://www.semopx.com/market-data/",
        #"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
    ],
    requestOptions = [
        Query = requestParameters,
        Headers = requestHeaders
    ],
    response = Web.Contents("https://reports.semopx.com/api/v1/documents/static-reports", requestOptions),
    json = Json.Document(response),
    documentsToRequest = List.Transform(json[items], each [DocumentUri = Text.Combine({json[resourceBaseUri], _[ResourceName]}, "/")]),
    toTable = Table.FromRecords(documentsToRequest, type table [DocumentUri = text]),
    csvsOnly = Table.SelectRows(toTable, each Text.EndsWith([DocumentUri], ".csv")),
    FetchCsv = (someUri as text) as table =>
        let
            response = Web.Contents(someUri),
            csv = Csv.Document(response, [Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv])
        in csv,
    invokeFunction = Table.AddColumn(csvsOnly, "Document", each FetchCsv([DocumentUri]), type table)
    // Code to complete transformation should go here. Depends on what you want final output to be.
in
    invokeFunction
0 голосов
/ 02 марта 2019

Не знаю, хотите ли вы / хотите, чтобы на этот вопрос ответили, учитывая, что он был задан почти два месяца назад, или если у вас / пользователя есть Power Query для Microsoft Excel.

Приведенный ниже подход в настоящее время работает только для файлов XML, поскольку мои критерии / фильтры поиска возвращали мне только файлы XML. Я не видел, как выглядят CSV-файлы с точки зрения их заголовков, структуры и т. Д. Но добавить поддержку CSV не должно быть слишком сложно (Power Query может нормально обрабатывать CSV-файлы).

Когда вы нажимаете «Поиск» на странице (в браузере), кажется, что он отправляет запрос на определенный URL (с критериями фильтрации со страницы в параметрах запроса) - и ответ сервера содержит, среди другие вещи, имена документов и время публикации, которые можно использовать для запроса документов, которые вы ищете. Таким образом, мы можем повторить этот основной запрос.

Setup / Осуществление

  1. Добавьте два именованных диапазона: dateFrom и dateTo в файл Excel.
  2. Добавьте приведенный ниже код в качестве нового запроса (я делаю это в Excel по: Data > Get Data > From Other Sources > Blank Query > click Advanced Editor in top-left > copy-paste code below > click OK > Click Close & Load). Это должно загрузить к листу.
  3. Для удобства может быть полезно переместить именованные диапазоны на несколько строк над таблицей (просто, чтобы всем можно было управлять с одного листа).

let
    dateFrom = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateFrom"]}[Content][Column1]{0}, "yyyy-MM-dd"),
    dateTo = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateTo"]}[Content][Column1]{0}, "yyyy-MM-dd"),
    requestParameters = [page="1", sort_by="PublishTime", order_by="DESC", name="exchange rate", date_from=dateFrom, date_to=dateTo, page_size="20"],
    requestHeaders = [Accept="*/*", Origin="https://www.sem-o.com", Referer="https://www.sem-o.com/market-data/static-reports/index.xml", #"User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"],
    json = Json.Document(Web.Contents("https://reports.sem-o.com/api/v1/documents/static-reports", [Query=requestParameters, Headers=requestHeaders])),
    documentsToRequest = List.Transform(json[items], each [DocumentUri = _[ResourceName]]),
    toTable = Table.FromRecords(documentsToRequest, type table [DocumentUri = text]),
    getEachDocument = Table.AddColumn(toTable, "Document", each Xml.Tables(Web.Contents(json[resourceBaseUri] & "/" & [DocumentUri]), null, 65001), type table),
    expand = Table.ExpandTableColumn(getEachDocument, "Document", {"PUB_DailyExchangeRate"}, {"PUB_DailyExchangeRate"}),
    expandNested = Table.ExpandTableColumn(expand, "PUB_DailyExchangeRate", {"Attribute:ROW", "Attribute:TradeDate", "Attribute:FromCurrency", "Attribute:ToCurrency", "Attribute:ExchangeRate"}, {"Attribute:ROW", "Attribute:TradeDate", "Attribute:FromCurrency", "Attribute:ToCurrency", "Attribute:ExchangeRate"}),
    changeTypes = Table.TransformColumnTypes(expandNested,{{"Attribute:ROW", Int64.Type}, {"Attribute:TradeDate", type date}, {"Attribute:FromCurrency", type text}, {"Attribute:ToCurrency", type text}, {"Attribute:ExchangeRate", type number}})
in
    changeTypes

Вышеуказанное необходимо выполнить только один раз.

Использование

  1. Введите / введите действительные даты в именованные диапазоны.
  2. Обновите запрос (я могу сделать это в Excel, щелкнув правой кнопкой мыши по загруженной таблице и щелкнув Refresh - или, альтернативно, Data > Refresh All).

Нечто подобное, безусловно, возможно в VBA или Google Apps Script (для Google Sheets), хотя это облегчает задачу, если язык обрабатывает JSON, XML, CSV - изначально или через библиотеки.

Вот как это выглядит для меня. Именованные диапазоны подсвечиваются, под ними загруженная таблица.

Results

Редактировать: CSV файлы :

Для файлов CSV (и только файлов CSV) может работать что-то вроде следующего. Я написал ниже на своем телефоне, так что я не смог проверить его, и отступ грязный / плохой.

let
    dateFrom = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateFrom"]}[Content][Column1]{0}, "yyyy-MM-dd"),
    dateTo = DateTime.ToText(Excel.CurrentWorkbook(){[Name = "dateTo"]}[Content][Column1]{0}, "yyyy-MM-dd"),
    requestParameters = [page="1", sort_by="PublishTime", order_by="DESC", name="exchange rate", date_from=dateFrom, date_to=dateTo, page_size="20"],
    requestHeaders = [Accept="*/*", Origin="https://www.sem-o.com", Referer="https://www.sem-o.com/market-data/static-reports/index.xml", #"User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"],
    json = Json.Document(Web.Contents("https://reports.sem-o.com/api/v1/documents/static-reports", [Query=requestParameters, Headers=requestHeaders])),
    documentsToRequest = List.Transform(json[items], each [DocumentUri = _[ResourceName]]),
    toTable = Table.FromRecords(documentsToRequest, type table [DocumentUri = text]),
csvsOnly = Table.SelectRows(toTable, each Text.EndsWith([DocumentUri], ".csv")),
    getEachDocument = Table.AddColumn(csvsOnly, "Document", each let csvContents = Csv.Document(Web.Contents(json[resourceBaseUri] & "/" & [DocumentUri]), [Delimiter=",", Encoding=65001]),
promoted = Table.PromoteHeaders(csvContents, [PromoteAllScalars=true])
in promoted)
in
    changeTypes

Определенно возможно иметь один фрагмент кода, который может обрабатывать оба типа файлов (CSV или XML), вместо того, чтобы иметь отдельный код для CSV и отдельный код для файлов XML. Я не делал этого выше, так как не смог протестировать / посмотреть, как выглядят CSV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...