Как автоматически выводить онлайн HTML-таблицы с использованием C # - PullRequest
6 голосов
/ 14 февраля 2012

Ладно, если говорить кратко:

У меня есть несколько разных веб-сайтов с таблицами, которые содержат информацию, которую я хотел бы запросить "local".

Я искал возможности, и у меня естьнекоторые идеи сам.

  1. В Excel я нашел функцию, с помощью которой я могу перейти на веб-страницу и скопировать данные из таблицы.Проблема в том, что это происходит только один раз.Данные в таблицах будут обновляться каждую неделю, поэтому мне нужно, чтобы Excel обновлялся автоматически каждый раз, когда я открываю свою программу.

  2. Я мог бы использовать сканер, но тогда мне пришлось бы писатьРазное решение для каждой таблицы и способ ее сохранения.

У меня есть право на базу данных MySQL, содержащую много информации, которая мне нужна в моей программе, поэтому, если любое решение требуетбаза данных, которая полностью приемлема.

О моей программе: Будет написана на C #, сначала как локальная программа, а затем как проект MVC.Предложения для обоих проектов очень приветствуются, и если вам нужна дополнительная информация, просто прокомментируйте, и я постараюсь описать ее еще немного.:)

РЕДАКТИРОВАТЬ!1

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

Таблица 2 Таблица 3

КакВы можете видеть, что много футбольных данных показывают по-разному, поэтому мне нужно знать, какой способ для меня лучше всего собирать, потому что я считаю, что проще создать базу данных с такими знаниями.

Ответы [ 6 ]

7 голосов
/ 22 февраля 2012

Андерс, в Excel есть встроенный способ извлечения данных, и вы должны сделать это один раз.В следующий раз вам нужно просто обновить запрос.Пожалуйста, смотрите эту ссылку.

html разбор показателей Cricinfo

FOLLOWUP

Попробуйте посмотреть на этой странице: soccernet.espn.go.com/stats/_/league/eng.1/… Есть 3 таблицы, но кажется, что Excel их обнаруживает.:( - Андерс Гернер 7 минут назад

На этом конкретном веб-сайте, если вы просматриваете источник, вы увидите, что таблица не имеет идентификатора. Все триУ таблицы один и тот же класс "tablehead". Если вы хотите, в событии открытия рабочей книги выполните цикл по всем таблицам и извлеките данные. Ваша работа упрощается, поскольку все 3 таблицы имеют один и тот же класс.

В качестве альтернативы вы также можете сделать это

В Excel нажмите Файл | Открыть и в диалоговом окне введите непосредственно URL, который вы упомянули ниже.заметит, что Excel аккуратно складывает данные :)

На самом деле вы можете написать небольшой макрос / код, который открывает временную рабочую книгу, а затем открывает URL, а затем просто извлекает таблицы из временной рабочей книги в вашу рабочую книгу.,По моим оценкам, при хорошем интернет-соединении весь процесс не должен занимать более 15 секунд для завершения

1 голос
/ 21 февраля 2012

вы можете использовать visual web ripper , у них есть API, который вы можете использовать из .NET, и вы можете создать шаблон, используя их конструктор для извлечения нужных вам данных, его очень легко использовать, мой Компания использовала его для получения отзывов с сайтов, даже с поиском и поиском.

1 голос
/ 14 февраля 2012

Если я просто читаю информацию на веб-странице, я нахожу HtmlAgilityPack чрезвычайно полезным.Это позволяет с помощью LINQ легко находить определенные теги с идентифицирующей информацией, а затем легко перемещаться по суб-тегам.Таким образом, вы можете найти тег

и захватить свойство Text, чтобы найти содержимое ячейки.
0 голосов
/ 26 февраля 2012

Вот пример кода с использованием пакета HtmlAgilityPack:

using System;
using System.Collections.Generic;
using System.Web;
using System.Xml.XPath;

using HtmlAgilityPack;

namespace TableRipper
{
    class Program
    {
        static List<string> SerializeColumnSet(XPathNodeIterator columnSet)
        {
            List<string> serialized = new List<string>();

            while (columnSet.MoveNext())
            {
                string value = HttpUtility.HtmlDecode(columnSet.Current.Value.ToString().Trim());

                if (value.Contains(",") || value.Contains("\""))
                {
                    value = string.Concat('"', value.Replace("\"", "\"\""), '"');
                }

                serialized.Add(value);
            }

            return serialized;
        }

        static List<List<string>> RipTable(string url, string xpath, bool includeHeaders = true)
        {
            HtmlWeb web = new HtmlWeb();
            HtmlDocument document = web.Load(url);
            XPathNavigator navigator = document.CreateNavigator();
            XPathNodeIterator tableElementSet = navigator.Select(xpath);
            List<List<string>> table = new List<List<string>>();

            if (tableElementSet.MoveNext())
            {
                XPathNavigator tableElement = tableElementSet.Current;
                XPathNavigator tableBodyElement = tableElement.SelectSingleNode("tbody") ?? tableElement;
                XPathNodeIterator tableRowSet = tableBodyElement.Select("tr");
                bool hasRows = tableRowSet.MoveNext();

                if (hasRows)
                {
                    if (includeHeaders)
                    {
                        XPathNavigator tableHeadElement = tableElement.SelectSingleNode("thead");
                        XPathNodeIterator tableHeadColumnSet = null;

                        if (tableHeadElement != null)
                        {
                            tableHeadColumnSet = tableHeadElement.Select("tr/th");
                        }
                        else if ((tableHeadColumnSet = tableRowSet.Current.Select("th")).Count > 0)
                        {
                            hasRows = tableRowSet.MoveNext();
                        }

                        if (tableHeadColumnSet != null)
                        {
                            table.Add(SerializeColumnSet(tableHeadColumnSet));
                        }
                    }

                    if (hasRows)
                    {
                        do
                        {
                            table.Add(SerializeColumnSet(tableRowSet.Current.Select("td")));
                        }
                        while (tableRowSet.MoveNext());
                    }
                }
            }

            return table;
        }

        static void Main(string[] args)
        {
            foreach (List<string> row in RipTable(args[0], args[1]))
            {
                Console.WriteLine(string.Join(",", row));
            }
        }
    }
}

Проверено по:

http://www.msn.com "// table [@ summary = 'Market Update']"

http://www.worldclimate.com/cgi-bin/data.pl?ref=N48W121+2200+450672C "// table [1]"

Это далеко от совершенства, например, оно не будет обрабатывать colspan или rowspan, но это начало.

0 голосов
/ 25 февраля 2012

Вы можете использовать Selenium (для автоматического веб-тестирования).Это чрезвычайно полезный инструмент.Его API позволит вам выполнять такие вещи, как поиск в конкретной таблице с помощью XPath, CSS или DOM.

Вы можете управлять Selenium с помощью «дистанционного управления» на множестве разных языков.См. http://seleniumhq.org/projects/remote-control/

См., Например, C #: http://www.theautomatedtester.co.uk/tutorials/selenium/selenium_csharp_nunit.htm

См. StackoverFlow для некоторых примеров: Как получить текст в столбце таблицы с помощью Selenium RC?

0 голосов
/ 25 февраля 2012

Мой подход заключается в том, чтобы использовать инструмент для создания RSS-канала для каждого URL-адреса, содержащего данные вашей таблицы, а затем отображать данные в вашем пользовательском интерфейсе (будь то WPF, WinForms или asp.net).Таким образом, вы можете легко настроить дополнительные «каналы», когда вы найдете / приобретете новый веб-сайт для извлечения данных, и ваша работа будет состоять в том, чтобы нормализовать новый сайт в вашем стандартном формате RSS-канала (настраивается одним из этих инструментов), иВы даже можете настроить свой пользовательский интерфейс так, чтобы он получал дополнительный канал в зависимости от настроек конфигурации, поэтому нет необходимости перекомпилировать его при добавлении нового сайта.

Вы можете сохранить данные канала в БД или просто отображать их в режиме реального времени, а также автоматически выполнять регулярное кэширование / обновление данных.Я думаю, что основная предпосылка этого подхода состоит в том, чтобы стандартизировать различные форматы таблиц каждого сайта в один общий формат (rss или другой), а затем беспокоиться только о потреблении одного стандартного формата в вашем приложении.Этот подход может быть настроен в библиотеке классов, которая представляет данные в общем формате, и затем эта библиотека классов может использоваться как вашим приложением C #, так и вашим веб-приложением.

Редактировать: вот ссылка на хорошийинформация о нескольких инструментах, которые можно использовать для создания RSS-канала с любого веб-сайта: http://profy.com/2007/09/30/7-tools-to-make-an-rss-feed-of-any-website/

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