Как анализировать табличные данные со страницы CNB C Markets? - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть программа, которую я пишу, которая принимает пользовательский ввод для подключения к сайту, загружает его html в текст и извлекает данные из таблицы два раза в день. Я понимаю, что код не будет подходить всем размерам для любой страницы (я, скорее всего, "запишу" URL-адрес в код, как только он заработает). В настоящее время моя проблема заключается в том, что мой анализатор jsoup неправильно читает табличные данные. Я не уверен, что мои селекторы элементов слишком универсальны c? Таблица выглядит так, как будто она в стандартном формате table / tr / td, но мой массив строк заполнен размером 0. Если бы кто-то мог помочь мне отладить мой синтаксический анализатор и, возможно, дать несколько советов о том, где искать, чтобы он получал данные молча два раза в день Я был бы очень признателен! Нет ошибок времени выполнения / компиляции, просто необходимо исправить вывод.

Исходный сайт: https://www.cnbc.com/us-markets/ Исходный код таблицы (фрагмент):

<table class="BasicTable-table"><thead class="BasicTable-tableHeading BasicTable-tableHeadingSortable"><tr><th class="BasicTable-textData"><span>SYMBOL <span class="icon-sort undefined"></span></span></th><th class="BasicTable-numData"><span>PRICE <span class="icon-sort undefined"></span></span></th><th class="BasicTable-numData">

Мой код:

public class StockScraper {

public static void main(String[] args) {
    Scanner input = new Scanner (System.in);
    System.out.println("Enter the complete url (including http://) of the site you would like to parse:");
    String html = input.nextLine();
    try {
        Document doc = Jsoup.connect(html).get();
        System.out.printf("Title: %s", doc.title());
        //Try to print site content
        System.out.println("");
        System.out.println("Writing html contents to 'html.txt'...");
        //Save html contents to text file
        PrintWriter outputfile = new PrintWriter("html.txt");
        outputfile.print(doc.outerHtml());
        outputfile.close();

        //Select stock data you want to retrieve
        System.out.println("Enter the name of the stock you want to check");
        String name = input.nextLine();

        //Pull data from CNBC Markets
        Element table = doc.select("table").get(0);
        Elements rows = table.select("tr");
        System.out.println(rows.size());
        for(int i = 1; i < rows.size(); i++) {
            Element rowx = rows.get(i);
            Elements col = rows.select("td");
            if(col.get(0).equals(name)) {
                System.out.println("I worked!");
                System.out.println(col.get(1));
            }
        }
} catch (IOException e) {
        e.printStackTrace();
    }
}

1 Ответ

1 голос
/ 07 апреля 2020

Проблема здесь в том, что этот сайт является динамической c страницей, которая загружает контент после первоначальной загрузки страницы браузером. Jsoup не будет достаточно, чтобы поцарапать страницы, как это. У вас есть пара вариантов:

1) Используйте инструмент, который имитирует браузер и выполняет все необходимые вызовы API. Варианты выбора - Selenium WebDriver или HTMLUnit.

2) Определите вызовы API, которые вас интересуют на этом сайте, и просто вызовите эти API напрямую, чтобы получить документ JSON, который вы можете проанализировать. Вы можете увидеть подробности API, открыв инструменты разработчика в вашем браузере, а затем перейдите на вкладку Сеть. Для этого сайта пример будет следующим, который включает в себя котировки акций для DJI:

https://quote.cnbc.com/quote-html-webservice/quote.htm?noform=1&partnerId=2&fund=1&exthrs=0&output=json&symbolType=issue&symbols=599362|579435|593933|49020635|49031016|5093160|617254|601065&requestMethod=extended

Returns:

ExtendedQuoteResult: {
  xmlns: "http://quote.cnbc.com/services/MultiQuote/2006",
  ExtendedQuote: [{
    QuickQuote: {
      symbol: ".DJI",
      code: "0",
      curmktstatus: "REG_MKT",
      FundamentalData: {
      yrlodate: "2020-03-23",
      yrloprice: "18213.65",
      yrhidate: "2020-02-12",
      yrhiprice: "29568.57"
    },
    mappedSymbol: {
      xsi:nil: "true"
    },
    source: "Exchange",
    cnbcId: "599362",
    prev_prev_closing: "21413.44",
    high: "22783.45",
    low: "21693.63",
    provider: "CNBC Quote Cache",
    streamable: "0",
    last_time: "2020-04-06T17:16:28.000-0400",
    countryCode: "US",
    previous_day_closing: "21052.53",
    altName: "Dow Industrials",
    reg_last_time: "2020-04-06T17:16:28.000-0400",
    last_time_msec: "1586207788000",
    altSymbol: ".DJI",
    change_pct: "7.73",
    providerSymbol: ".DJI",
    assetSubType: "Index",
    comments: "RIC",
    last: "22679.99",
    issue_id: "599362",
    cacheServed: "false",
    responseTime: "Mon Apr 06 19:12:09 EDT 2020",
    change: "1627.46",
    timeZone: "EDT",
    onAirName: "Dow Industrials",
    symbolType: "issue",
    assetType: "INDEX",
    volume: "614200990",
    fullVolume: "614200990",
    realTime: "true",
    name: "Dow Jones Industrial Average",
    quoteDesc: { },
    exchange: "Dow Jones Global Indexes",
    shortName: "DJIA",
    cachedTime: "Mon Apr 06 19:12:09 EDT 2020",
    currencyCode: "USD",
    open: "21693.63"
  }
}
...
...