Как распарсить html таблицу

Kreola

Client
Регистрация
31.07.2015
Сообщения
44
Благодарностей
3
Баллы
8
Приветствую!
Ребят помогите пожалуйста понять как правильно распарсивать таблицу в переменные.
Имеем вот такую таблицу.
http://www.aircraftspruce.com/catalog/appages/fairing.php

Нужно распарсить ее в csv таблицу. Вопрос как?
Может есть где-то видео?.
Спасибо заранее.
 

rostonix

Известная личность
Регистрация
23.12.2011
Сообщения
29 067
Благодарностей
5 714
Баллы
113
Регулярками )
Сначала таблиwe целиком спарсить, потом спарсить каждую строку и сложить в список значений. Потом брать построчно из списка и парсить каждое значение из списка уже на 5 колонок с данными

http://zennolab.com/wiki/ru:creating-a-regular-expressions
 

Kreola

Client
Регистрация
31.07.2015
Сообщения
44
Благодарностей
3
Баллы
8
А можно более реальный пример?. С регулярками я то нормально вроде, но вот с логикой зенки пока что туго.
 

surr

Новичок
Регистрация
09.10.2014
Сообщения
15
Благодарностей
14
Баллы
3
Парсить регулярками таблицы с переменным количеством строк/столбцов, да ещё с болдами и линками внутри ячеек - полная жесть:-)
Кури мануалы xPath, пиши сниппеты, самый верный способ.

Вот тебе готовое решение, раскомментировал как мог. Будет работать на любых таблицах с этого сайта, независимо от количества строк, столбцов и прочего. Если по ссылке не окажется таблички с запчастями, то просто прекратит выполнение сниппета. НО проект подключен с xlsx-табличке (должна лежать в одной папке с файлом-проекта). Я виндовод, csv никогда не использовал, сходу подрубить не смог. Вылезает какой-то геморрой с записью и разделителями для этого формата, ковыряться лень, поэтому подключил экселевскую табличку. По аналогии сам разберёшься с csv, если действительно нужно. Файл готового проекта в аттаче.

Код:
// Чистим куки.
instance.ClearCookie();

// Загружаем страницу с нужной нам таблицей.
Tab tab = instance.ActiveTab;
if ((tab.IsVoid) || (tab.IsNull)) return -1;
if (tab.IsBusy) tab.WaitDownloading();
tab.Navigate("http://www.aircraftspruce.com/catalog/appages/fairing.php", "");
if (tab.IsBusy) tab.WaitDownloading();

// Подключаем таблицу в которую будем сливать все спарсенные данные.
// Таблица должна быть смонтирована в проект. Файл таблицы должен быть создан заранее и находиться
// в одной директории с файлом проекта.
IZennoTable tableXLS = project.Tables["aircraftTable"];

// Проверяем имеется ли на странице интересующая нас таблица. В случае, если таблицы нет дальнейшее
// выполнение сниппета (кода) будет прекращено, управление будет передано на следующий блок проекта.
if (tab.FindElementByXPath("//table[@id=\"popup_table\"]", 0).IsVoid)
{
    return "Таблица с доп. деталями отсутствует";
}

// Считаем количество актуальных строк в таблице.
// Заголовок таблицы не учитываем.
int rowsCount = tab.FindElementsByXPath("//table[@id=\"popup_table\"]/tbody/tr").Count;

// Считаем количество столбцов с актуальной информацией в таблице.
// Т.к. количество столбцов у таблиц на разных страницах является переменным, критерием отбора делаем заголовок.
// Учитываем все столбцы с первой позиции, пока не поймаем столбец с заголовком "Buy". Начиная с него все последующие
// столбцы не содержат никакой информации, предполагают только кол-во единиц товара и подсчёт промежуточной суммы.
// Заголовки сразу пишем в результирующую таблицу.
int columnsCount;
int i = 1;

do
{
    string tableHeader = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/thead/tr/td[{0}]", i),0).InnerHtml.Trim();
    if (tableHeader == "Buy") break;
    tableXLS.SetCell(i - 1, 0, tableHeader);
    i++;
}
while (tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/thead/tr/td[{0}]", i),0).InnerHtml.Trim() != "Buy");

columnsCount = i;

// Теперь, зная количество столбцов и строк в таблице из которых нам надо спарсить инфу, по очереди обходим каждую ячейку.
for (int w = 1; w <= rowsCount; )
{
    for (int y = 1; y <= columnsCount; )
    {
        string value;
        // В каждой ячейке надо делать проверку на входящие элементы, т.к. в некоторых таблицах попадаются ячейки с гиперссылками
        // которые при парсинге будут взяты целой строкой вместе со всеми тегами. Кроме того ячейки с ценой так же имеют текст,
        // завёрнутый в тег болд.
        if (tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).GetChildren(false).Count == 0)
        {
            value = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).InnerHtml;
        }
        else
        {
            value = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).FirstChild.InnerHtml;
        }
        // Пишем каждое значение в результирующую таблицу.
        tableXLS.SetCell(y - 1, w, value);
        y++;
    }
    w++;
}
return "Таблица обработана";
 

Вложения

MAD_EVAL

Новичок
Регистрация
10.09.2018
Сообщения
4
Благодарностей
0
Баллы
1
Парсить регулярками таблицы с переменным количеством строк/столбцов, да ещё с болдами и линками внутри ячеек - полная жесть:-)
Кури мануалы xPath, пиши сниппеты, самый верный способ.

Вот тебе готовое решение, раскомментировал как мог. Будет работать на любых таблицах с этого сайта, независимо от количества строк, столбцов и прочего. Если по ссылке не окажется таблички с запчастями, то просто прекратит выполнение сниппета. НО проект подключен с xlsx-табличке (должна лежать в одной папке с файлом-проекта). Я виндовод, csv никогда не использовал, сходу подрубить не смог. Вылезает какой-то геморрой с записью и разделителями для этого формата, ковыряться лень, поэтому подключил экселевскую табличку. По аналогии сам разберёшься с csv, если действительно нужно. Файл готового проекта в аттаче.

Код:
// Чистим куки.
instance.ClearCookie();

// Загружаем страницу с нужной нам таблицей.
Tab tab = instance.ActiveTab;
if ((tab.IsVoid) || (tab.IsNull)) return -1;
if (tab.IsBusy) tab.WaitDownloading();
tab.Navigate("http://www.aircraftspruce.com/catalog/appages/fairing.php", "");
if (tab.IsBusy) tab.WaitDownloading();

// Подключаем таблицу в которую будем сливать все спарсенные данные.
// Таблица должна быть смонтирована в проект. Файл таблицы должен быть создан заранее и находиться
// в одной директории с файлом проекта.
IZennoTable tableXLS = project.Tables["aircraftTable"];

// Проверяем имеется ли на странице интересующая нас таблица. В случае, если таблицы нет дальнейшее
// выполнение сниппета (кода) будет прекращено, управление будет передано на следующий блок проекта.
if (tab.FindElementByXPath("//table[@id=\"popup_table\"]", 0).IsVoid)
{
    return "Таблица с доп. деталями отсутствует";
}

// Считаем количество актуальных строк в таблице.
// Заголовок таблицы не учитываем.
int rowsCount = tab.FindElementsByXPath("//table[@id=\"popup_table\"]/tbody/tr").Count;

// Считаем количество столбцов с актуальной информацией в таблице.
// Т.к. количество столбцов у таблиц на разных страницах является переменным, критерием отбора делаем заголовок.
// Учитываем все столбцы с первой позиции, пока не поймаем столбец с заголовком "Buy". Начиная с него все последующие
// столбцы не содержат никакой информации, предполагают только кол-во единиц товара и подсчёт промежуточной суммы.
// Заголовки сразу пишем в результирующую таблицу.
int columnsCount;
int i = 1;

do
{
    string tableHeader = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/thead/tr/td[{0}]", i),0).InnerHtml.Trim();
    if (tableHeader == "Buy") break;
    tableXLS.SetCell(i - 1, 0, tableHeader);
    i++;
}
while (tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/thead/tr/td[{0}]", i),0).InnerHtml.Trim() != "Buy");

columnsCount = i;

// Теперь, зная количество столбцов и строк в таблице из которых нам надо спарсить инфу, по очереди обходим каждую ячейку.
for (int w = 1; w <= rowsCount; )
{
    for (int y = 1; y <= columnsCount; )
    {
        string value;
        // В каждой ячейке надо делать проверку на входящие элементы, т.к. в некоторых таблицах попадаются ячейки с гиперссылками
        // которые при парсинге будут взяты целой строкой вместе со всеми тегами. Кроме того ячейки с ценой так же имеют текст,
        // завёрнутый в тег болд.
        if (tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).GetChildren(false).Count == 0)
        {
            value = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).InnerHtml;
        }
        else
        {
            value = tab.FindElementByXPath(String.Format("//table[@id=\"popup_table\"]/tbody/tr[{0}]/td[{1}]", w, y),0).FirstChild.InnerHtml;
        }
        // Пишем каждое значение в результирующую таблицу.
        tableXLS.SetCell(y - 1, w, value);
        y++;
    }
    w++;
}
return "Таблица обработана";
Я выражаю Вам огромную благодарность. Ваш качественный пример помог реализовать мою задачу.
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)