Разбирайте отдельные элементы данных из таблиц HTML с помощью C #?

c# html-agility-pack web-scraping

Вопрос

У меня есть этот код в моей основной функции, и я хочу проанализировать только первую строку таблицы (например, 7 ноября 2017 года 73,78 74,00 72,32 72,71 17,245,947).

Я создал узел, который завершает только первую строку, но когда я начинаю отладку, значение узла равно null. Как я могу разобрать эти данные и хранить их, например, в строке или в одиночных переменных. Есть ли способ?

WebClient web = new WebClient();

        string page = web.DownloadString("https://finance.google.com/finance/historical?q=NYSE:C&ei=7O4nV9GdJcHomAG02L_wCw");

        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(page);

        var node = doc.DocumentNode.SelectSingleNode("//*[@id=\"prices\"]/table/tbody/tr[2]");

  List<List<string>> node = doc.DocumentNode.SelectSingleNode("//*[@id=\"prices\"]/table").Descendants("tr").Skip(1).Where(tr => tr.Elements("td").Count() > 1).Select(tr => tr.Elements("td").Select(td=>td.InnerText.Trim()).ToList()).ToList() ;

Принятый ответ

Кажется, что ваша строка XPath выбора имеет ошибки. Поскольку tbody является сгенерированным узлом, он не должен включаться в путь:

//*[@id=\"prices\"]/table/tr[2]

Хотя это должно прочитать значение HtmlAgilityPack попадает в другую проблему с malformed html . Все узлы <tr> и <td> в анализируемом тексте не имеют соответствующих тегов закрытия </tr> или </td> а HtmlAgitilityPack не может выбирать значения из таблицы с неверными строками. Поэтому на первом этапе необходимо выбрать всю таблицу:

//*[@id=\"prices\"]/table

И на следующем шаге либо санируйте HTML, добавив </tr> и </td> закрывающие теги, и повторите парсинг с исправленной таблицей или используйте извлеченную строку для ручного анализа - просто извлеките строки от 10 до 15 из строки таблицы и разделите их на > персонаж. Ниже представлен синтаксический анализ. Код проверен и работает.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace GoogleFinanceDataScraper
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient web = new WebClient();

            string page = web.DownloadString("https://finance.google.com/finance/historical?q=NYSE:C&ei=7O4nV9GdJcHomAG02L_wCw");

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(page);

            var node = doc.DocumentNode.SelectSingleNode("//div[@id='prices']/table");

            string outerHtml = node.OuterHtml;
            List<String> data = new List<string>();
            using(StringReader reader = new StringReader(outerHtml))
            {
                for(int i = 0; ; i++)
                {
                    var line = reader.ReadLine();
                    if (i < 9) continue;
                    else if (i < 15)
                    {
                        var dataRawArray = line.Split(new char[] { '>' });
                        var value = dataRawArray[1];
                        data.Add(value);
                    }
                    else break;
                }
            }

            Console.WriteLine($"{data[0]}, {data[1]}, {data[2]}, {data[3]}, {data[4]}, {data[5]}");
        }
    }
}


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow