Все началось, как я понял, с этого вопроса: Индекс за пределами диапазона C# XPath. Потом продолжилось здесь, а результатом должен был быть банальный парсинг сайта. Проблема эта не нова. Если поискать по SO, то можно найти кучу вопросов и ответов.
Только ради того, чтоб закончить эпопею с этим сайтом, решил помочь.
Таблица на этом сайте строится динамически с помощью javascript. Потому либо нужено использовать что-то типа Selenium, либо, если не охота париться, просто открываем сайт в браузере, а потом сохраняем страницу в файл html.
А дальше работаем с файлом

Создадим пару классов для хранения этой информации
public class EconomicCalendar
{
public string Title { get; set; }
public List<CalendarRow> Rows { get; } = new List<CalendarRow>();
}
public class CalendarRow
{
public string ID { get; set; }
public string EventAttrId { get; set; }
public string DataEventDatetime { get; set; }
public string FirstLeftTile { get; set; }
public string CountryAbbr { get; set; }
public string CountryRus { get; set; }
public string CountryEng { get; set; }
public string Forecast { get; set; }
public string Previous { get; set; }
public string Alert { get; set; }
public string Volatility { get; set; }
}
Чтобы преобразовать HTML в XML установим такую библ.

Напишем такой подсобный класс
public class HtmlToXmlService
{
/// <summary>
/// Получение экземпляра XDocument на основе html файла
/// </summary>
/// <param name="pathToFile">путь к файлу html</param>
/// <returns>экземпляр XDocument</returns>
public static XDocument GetXDocument(string pathToFile)
{
if (String.IsNullOrEmpty(pathToFile)) throw new ArgumentNullException(nameof(pathToFile));
if (!File.Exists(pathToFile)) throw new ArgumentException("Файл не найден!");
//читаем файл и получаем документ
XDocument result = null;
using (StreamReader sr = File.OpenText(pathToFile))
{
result = FromHtml(sr);
}
//удаление пространства имен
RemoveNamespaces(result);
return result;
}
private static void RemoveNamespaces(XDocument result)
{
//удаление namespaces у элементов
result.Descendants()
.Attributes()
.Where(x => x.IsNamespaceDeclaration)
.Remove();
foreach (var elem in result.Descendants())
elem.Name = elem.Name.LocalName;
//удаление namespaces у атрибутов элементов
foreach (var attr in result.Descendants().Attributes())
{
var elem = attr.Parent;
attr.Remove();
elem.Add(new XAttribute(attr.Name.LocalName, attr.Value));
}
}
private static XDocument FromHtml(TextReader reader)
{
// setup SgmlReader
SgmlReader sgmlReader = new SgmlReader();
sgmlReader.DocType = "HTML";
sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
sgmlReader.CaseFolding = CaseFolding.ToLower;
sgmlReader.InputStream = reader;
return XDocument.Load(sgmlReader);
}
}
В этом классе будем парсить xml с помощью LINQ (может не самым удобным образом..., критика приветствуется)
/// <summary>
/// Обработка страницы сайта полученной с адреса https://ru.investing.com/economic-calendar/
/// </summary>
public class EconomicCalendarService
{
/// <summary>
/// Парсинг файла HTML сохраненной страницы
/// </summary>
/// <param name="pathToHtmlFile">путь к файлу html</param>
/// <returns>экземпляр EconomicCalendar </returns>
public static Task<EconomicCalendar> GetEconomicCalendar(string pathToHtmlFile)
{
if (String.IsNullOrEmpty(pathToHtmlFile)) throw new ArgumentNullException(nameof(pathToHtmlFile));
EconomicCalendar result = new EconomicCalendar();
//получаем из Html файла -> XDocument
XDocument document = HtmlToXmlService.GetXDocument(pathToHtmlFile);
//название таблицы
result.Title = document.Descendants("table")
.Where(table => table.Attributes("id").Any())
.Where(t => t.Attribute("id").Value.StartsWith("economicCalendarData"))
.Descendants("td")
.Where(td => td.Attributes("class").Any())
.Where(td => td.Attribute("class").Value.StartsWith("theDay"))
.First().Value;
//извлекаем строки таблицы
var crs = document.Root.Element("body")
.Descendants("tr")
.Where(tr => tr.Attributes("class").Any())
.Where(tr => tr.Attribute("class").Value.StartsWith("js-event-item"))
.Select(tr => new CalendarRow
{
ID = tr.Attribute("id")?.Value,
EventAttrId = tr.Attribute("event_attr_id")?.Value,
DataEventDatetime = tr.Attribute("data-event-datetime")?.Value,
FirstLeftTile = tr.Descendants("td")
.FirstOrDefault(td => td.Attribute("class").Value.StartsWith("first left"))
?.Value,
CountryAbbr = tr.Descendants("td")
.FirstOrDefault(td => td.Attribute("class").Value.StartsWith("left flagCur"))
?.Value,
CountryRus = tr.Descendants("td")
.Where(td => td.Attribute("class").Value.StartsWith("left flagCur"))
.Select(td => td?.Descendants().First()?.Attribute("title")?.Value)
.FirstOrDefault(),
CountryEng = tr.Descendants("td")
.Where(td => td.Attribute("class").Value.StartsWith("left flagCur"))
.Select(td => td?.Descendants().First()?.Attribute("data-img_key")?.Value)
.FirstOrDefault(),
Forecast = tr.Descendants("td")
.FirstOrDefault(td => td.Attribute("class").Value.StartsWith("fore"))
?.Value,
Previous = tr.Descendants("td")
.Where(td => td.Attribute("class").Value.StartsWith("prev"))
.Select(td => td?.Descendants().First()?.Value)
.FirstOrDefault(),
Alert = tr.Descendants("td")
.Where(td => td.Attribute("class").Value.StartsWith("alert"))
.Select(td => td.Attribute("data-name")?.Value)
.FirstOrDefault(),
Volatility = tr.Descendants("td")
.Where(td => td.Attribute("class").Value.StartsWith("left textNum"))
.Select(td => td.Attribute("title")?.Value)
.FirstOrDefault(),
});
//вносим строки
result.Rows.AddRange(crs);
return Task.FromResult(result);
}
}
Как-то так. Построение граф интерфейса банально, код приводить не буду.
Только как пользоваться написанным выше классом
try
{
EconomicCalendar calendar = await EconomicCalendarService.GetEconomicCalendar(File);
Title = calendar.Title;
Rows = calendar.Rows;
}
catch (Exception ex)
{
_mainWindow.ShowMessage($"Возникла ошибка: {ex.Message}");
}
Пример можно скачать здесь
Время 01:45,Страна JPYи другими полями? При редактировании вопроса видно, что там либо несколько пробелов либо TAB, и вообще очень похоже на CSV – rdorn Jun 16 '18 at 22:55<td>. Вы не хотите слушать, либо это ваши два аккаунта сыграли злую шутку и вы не увидели тот ответ. Сейчас вы делаете полнейший бред! – EvgeniyZ Jun 16 '18 at 22:57После парсинга информации, которая кстати правильно получена, я записываю ее в string- либо не правильно сохраняете, либо вовсе неверно парсите. Текст из вопроса почти не реально нормально прочесть, ибо у него нету четкой структуры (где 1 пробел, где 2, а где то и вовсе 3). Вот вам к примеру разбить я пытался по 3-ем пробелам - результат. Тут либо много костылей изобретать, либо как то регулярками проходиться (и то и то не очень хорошо). – EvgeniyZ Jun 16 '18 at 23:26Parser.cs, строка 69_Text += "Время " + row[0] +- вот все это переделывайте, делайте класс с определёнными полями/свойствами, делайте коллекцию этого класса и в неё все заносите. Сейчас вы делаете совершенно нечитаемые данные. Также, я вам уже сотню раз говорил - вы все прибили гвоздями//tr/td[5]/text(), ну нельзя так, нельзя! Объектов может быть больше 7 или нужный объект может быть смещён на 3 место к примеру, что тогда? – EvgeniyZ Jun 16 '18 at 23:59