Собираем данные с XLS, XLSX и CSV файлов

Сегодня в платформу Diggernaut была добавлена поддержка файлов в формате XLS, XLSX и CSV. Схема поддержки реализована в том же формате как и у других поддерживаемых типов файлов. Вы загружаете в диггер файл, используя команду walk, диггер получает файл, определяет его тип и конвертирует его в XML. Далее вы можете ходить по DOM структуре, извлекать нужные данные и формировать свой набор данных.

Рассмотрим на примере, как это работает. Для этого мы поместили 3 файла в нашу песочницу:
https://www.diggernaut.com/sandbox/sample.csv — CSV файл с данными
https://www.diggernaut.com/sandbox/sample.xls — XLS файл с данными (бинарная версия)
https://www.diggernaut.com/sandbox/sample.xlsx — XLSX файл с данными (XML версия)

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

---
config:
    debug: 2
    agent: Firefox
do:
- walk:
    to: https://www.diggernaut.com/sandbox/sample.csv
    do:

Если мы запустим диггер в режиме отладки, то в логе мы увидим следующий исходный код XML страницы с данными

<html>
<head></head>
<body>
    <doc>
        <sheet name="default">
            <row class="1">
                <column class="1">First</column>
                <column class="2">Last</column>
                <column class="3">Pcode</column>
                <column class="4">Political Party</column>
            </row>
            <row class="2">
                <column class="1">Smith</column>
                <column class="2">Fred</column>
                <column class="3">A</column>
                <column class="4">Democratic</column>
            </row>
            <row class="3">
                <column class="1">Robbins</column>
                <column class="2">Terry</column>
                <column class="3">1</column>
                <column class="4">Green</column>
            </row>
            <row class="4">
                <column class="1">O'Neill</column>
                <column class="2">Susan</column>
                <column class="3">B</column>
                <column class="4">Republican</column>
            </row>
            <row class="5">
                <column class="1">Parker</column>
                <column class="2">Scott</column>
                <column class="3">D</column>
                <column class="4">American Independent</column>
            </row>
            <row class="6">
                <column class="1">Perkins</column>
                <column class="2">Ralph</column>
                <column class="3">D</column>
                <column class="4">American Independent</column>
            </row>
            <row class="7">
                <column class="1">Talbot</column>
                <column class="2">Angie</column>
                <column class="3">7</column>
                <column class="4">Middle Class Pty</column>
            </row>
        </sheet>
    </doc>
</body>
</html>

Так как в CSV только один лист, то элемент sheet в результирующей структуре только один. В XLS/XLSX файлах листов может быть много, и все они будут находиться в соответсвующих элементах sheet. Парсить такую структуру достаточно легко, проходим по листам, затем по строкам row и забираем данные из колонок column. Значения в классах соответствуют номеру строк и столбцов в оригинальном файле.

Давайте теперь посмотрим, как будет сконвертирован XLS ресурс:

---
config:
    debug: 2
    agent: Firefox
do:
- walk:
    to: https://www.diggernaut.com/sandbox/sample.xls
        do:

Получим следующий исходный код:

<html>
<head></head>
<body>
    <doc>
        <sheet name="Voters">
            <row class="1">
                <column class="1">First</column>
                <column class="2">Last</column>
                <column class="3">Pcode</column>
                <column class="4">Political Party</column>
            </row>
            <row class="2">
                <column class="1">Smith</column>
                <column class="2">Fred</column>
                <column class="3">A</column>
            </row>
            <row class="3">
                <column class="1">Robbins</column>
                <column class="2">Terry</column>
                <column class="3">1</column>
            </row>
            <row class="4">
                <column class="1">O'Neill</column>
                <column class="2">Susan</column>
                <column class="3">B</column>
            </row>
            <row class="5">
                <column class="1">Parker</column>
                <column class="2">Scott</column>
                <column class="3">D</column>
            </row>
            <row class="6">
                <column class="1">Perkins</column>
                <column class="2">Ralph</column>
                <column class="3">D</column>
            </row>
            <row class="7">
                <column class="1">Talbot</column>
                <column class="2">Angie</column>
                <column class="3">7</column>
            </row>
        </sheet>
        <sheet name="Party Codes">
            <row class="1">
                <column class="1">PARTY CODE</column>
                <column class="2">NAME</column>
            </row>
            <row class="2">
                <column class="1">1</column>
                <column class="2">Green</column>
            </row>
            <row class="3">
                <column class="1">2</column>
                <column class="2">Reform</column>
            </row>
            <row class="4">
                <column class="1">3</column>
                <column class="2">Whig</column>
            </row>
            <row class="5">
                <column class="1">4</column>
                <column class="2">Islamic Political Party of America</column>
            </row>
            <row class="6">
                <column class="1">5</column>
                <column class="2">Rock & Roll</column>
            </row>
            <row class="7">
                <column class="1">6</column>
                <column class="2">Natural Law</column>
            </row>
            <row class="8">
                <column class="1">7</column>
                <column class="2">Middle Class Pty</column>
            </row>
            <row class="9">
                <column class="1">8</column>
                <column class="2">Humanist</column>
            </row>
            <row class="10">
                <column class="1">9</column>
                <column class="2">Pragmatic</column>
            </row>
            <row class="11">
                <column class="1">10</column>
                <column class="2">Conscious American African Party</column>
            </row>
            <row class="12">
                <column class="1">11</column>
                <column class="2">Parliament Party</column>
            </row>
            <row class="13">
                <column class="1">12</column>
                <column class="2">United Conscious Builders of the Dream Party</column>
            </row>
            <row class="14">
                <column class="1">13</column>
                <column class="2">The Egalitarian Party</column>
            </row>
            <row class="15">
                <column class="1">14</column>
                <column class="2">The Humanitarian Party</column>
            </row>
            <row class="16">
                <column class="1">15</column>
                <column class="2">Scientifically Evolving University Party</column>
            </row>
            <row class="17">
                <column class="1">16</column>
                <column class="2">God, Truth & Love Party</column>
            </row>
            <row class="18">
                <column class="1">17</column>
                <column class="2">Superhappy Party</column>
            </row>
            <row class="19">
                <column class="1">18</column>
                <column class="2">Working Families Party</column>
            </row>
            <row class="20">
                <column class="1">A</column>
                <column class="2">Democratic</column>
            </row>
            <row class="21">
                <column class="1">B</column>
                <column class="2">Republican</column>
            </row>
            <row class="22">
                <column class="1">C</column>
                <column class="2">Decline to State</column>
            </row>
            <row class="23">
                <column class="1">D</column>
                <column class="2">American Independent</column>
            </row>
            <row class="24">
                <column class="1">E</column>
                <column class="2">Citizen Party</column>
            </row>
            <row class="25">
                <column class="1">F</column>
                <column class="2">Communist</column>
            </row>
            <row class="26">
                <column class="1">G</column>
                <column class="2">Conservative</column>
            </row>
            <row class="27">
                <column class="1">H</column>
                <column class="2">Environmentalist</column>
            </row>
            <row class="28">
                <column class="1">I</column>
                <column class="2">Ind. Progressive</column>
            </row>
            <row class="29">
                <column class="1">J</column>
                <column class="2">Liberal</column>
            </row>
            <row class="30">
                <column class="1">K</column>
                <column class="2">Peace & Freedom</column>
            </row>
            <row class="31">
                <column class="1">L</column>
                <column class="2">Prohibition</column>
            </row>
            <row class="32">
                <column class="1">M</column>
                <column class="2">New Economy</column>
            </row>
            <row class="33">
                <column class="1">N</column>
                <column class="2">Socialist</column>
            </row>
            <row class="34">
                <column class="1">O</column>
                <column class="2">Socialist Labor</column>
            </row>
            <row class="35">
                <column class="1">P</column>
                <column class="2">Pot Party</column>
            </row>
            <row class="36">
                <column class="1">Q</column>
                <column class="2">Libertarian</column>
            </row>
            <row class="37">
                <column class="1">R</column>
                <column class="2">Amer. Natl. Socialist</column>
            </row>
            <row class="38">
                <column class="1">S</column>
                <column class="2">Poor People’s Party</column>
            </row>
            <row class="39">
                <column class="1">T</column>
                <column class="2">Free</column>
            </row>
            <row class="40">
                <column class="1">U</column>
                <column class="2">National</column>
            </row>
            <row class="41">
                <column class="1">V</column>
                <column class="2">Constitution Party</column>
            </row>
            <row class="42">
                <column class="1">W</column>
                <column class="2">Vision</column>
            </row>
            <row class="43">
                <column class="1">X</column>
                <column class="2">Puritan</column>
            </row>
            <row class="44">
                <column class="1">Y</column>
                <column class="2">Federal</column>
            </row>
            <row class="45">
                <column class="1">Z</column>
                <column class="2">Misc.</column>
            </row>
            <row class="46">
                <column class="1"></column>
                <column class="2"></column>
            </row>
        </sheet>
    </doc>
</body>
</html>

Как вы видите, в этом файле мы имеем 2 листа, а в остальном принципиально такую же структуру как и в случае с CSV. Если мы загрузим XLSX, то получим точно такой же результат как и с XLS, поэтому мы опустим этот момент.

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

Михаил Сисин: Со-основатель облачного сервиса по сбору информации и парсингу сайтов Diggernaut. Работает в области сбора и анализа данных, а также разработки систем искусственного интеллекта и машинного обучения  более десяти лет.
Related Post

This website uses cookies.