Найти в Дзене

Как парсить сайты с гугл-таблицами на практике. Текст + видео

Часто бывает нужно скопировать с какого-либо сайта большой объем данных, и поддерживать эти данные в актуальном состоянии. Делюсь пошаговой инструкцией, как это сделать!
Какое-то время назад я уже публиковал статью о том, как можно парсить данные с помощью гугл таблиц: вот эта статья, и мне теперь приходят вопросы, как это правильно делать. Сложность заключается в подборе правильных параметров
Оглавление

Часто бывает нужно скопировать с какого-либо сайта большой объем данных, и поддерживать эти данные в актуальном состоянии. Делюсь пошаговой инструкцией, как это сделать!

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

Вот и недавно пришел еще один вопрос:

Поэтому, давайте сегодня разберем еще раз, и в деталях, как парсить сайты с помощью google sheets.

Смотрите видео или читайте текст ниже, как вам удобнее!

С чего начнем? Давайте я коротко расскажу о том, что такое XPath.

1. XPath - что это?

XPath расшифровывается как XML Path Language - язык пути для XML, и служет для идентификации узлов и навигации по XML документу (Обычная веб-страница - это входит в подмножество документов XML). Это один из основных стандартов для интернета: с 16 ноября 1999 XPath стал получил рекомендацию W3C (World Wide Web Consortium) - главной организации, занимающейся стандартами в интернет.

Выражения XPath используется во многих языках программирования, включая JavaScript, Java, PHP, Python, С/С++ и многие другие.

Подробно про XPath можно прочитать на этом сайте (Жмите кнопку Next/Следующий вверху). Кстати, сайт можно перевести с помощью гугл-переводчика, и качество перевода отличное.

Доступна отличная шпаргалка по XPath: здесь.

2. Смотрим исходный код веб-страницы

Следующий шаг - нам нужно посмотреть код веб-страницы. Но не весь, от начала и до конца, а то, что касается элементов, которые мы хотим импортировать в таблицу. Жмем правой кнопкой мыши на интересующем элементе и выбираем "Просмотр кода элемента" ("Inspect") (в разных браузерах название этого пункта меню может немного отличаться).

-2

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

Нам для импорта понадобятся:

  1. Элемент div с параметром class="grid__col--xs-6 grid__col--sm-4"
  2. Элемент figure и элемент img под ним
  3. Элемент div с параметром class="product__meta-box"

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

Ну что, подготовительная работа на этом завершилась. Приступим к парсингу.

3. Парсинг сайта в гугл шитс

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

=IMPORTXML("адрес сайта"; "//div[@class=""grid__col--xs-6 grid__col--sm-4""]//figure/span/img/attribute::data-srcset")

Надеюсь, эта формула не испугала вас? В ней говорится, что мы хотим найти элемент div с параметром class="grid__col--xs-6 grid__col--sm-4", и в дочерних элементах найти вложенные друг в друга элементы figure, span и img, и выгрузить в таблицу параметр "data-srcset" элемента img.

-4

Результат пока мало похож на то, что мы ожидали, но это потому, что он в "сыром" виде. Его нужно немного приготовить. Посмотрев на эти данные, мы можем сделать вывод, что здесь указаны ссылки на иллюстрации разных размеров для каждого из товаров. Разделяются запятой, а размер изображения отделен от ссылки символом новой строки. Разобьем все это на отдельные элементы с помощью функции SPLIT. Как аргументы мы укажем нашу импортированную таблицу, символы которые разделяют (запятая и перевод строки. Перевод строки задается с помощью спец-символа с кодом 10). Ввиду того, что у нас IMPORTXML возвращает массив, а функция SPLIT привыкла работать с одной строкой, нужно с помощью ARRAYFORMULA указать, что мы работаем с массивом. Итак, конструируем формулу:

=arrayformula(split(IMPORTXML("адрес сайта"; "//div[@class=""grid__col--xs-6 grid__col--sm-4""]//figure/span/img/attribute::data-srcset");","&char(10);true;true))

-5

Результат уже больше похож на таблицу. Давайте вместо ссылок поставим картинки. Еще раз поменяем формулу:

С помощью функции index оставим только 7 столбец (ссылки на среднюю по размеру картинку), допишем к нему в начале "http:", чтобы была правильная ссылка. Также обратим внимание, что ссылка заканчивается лишним пробелом или каким-то другим спец-символом; удалим его с помощью функции trim. И все это используем как аргумент функции image:

=arrayformula(image(trim("http:"&index(split(IMPORTXML("адрес сайта";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//figure/span/img/attribute::data-srcset");","&char(10);true;true);;7))))

-6

Увиличем еще высоту строк. Первый столбец нашей таблицы готов, дальше будет проще.

Во второй колонке мы напишем новую формулу. Точно так же мы будем искать элемент div с параметром class="grid__col--xs-6 grid__col--sm-4" и извлекать весь текст в элементе div с параметром class="product__meta-box":

=IMPORTXML("https://tavid.ee/ru/serebro/serebryanye-monety/";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//div[@class=""product__meta-box""]")

Добавим все-таки в верхней строчке заголовки.

-7

Видно, что скопировалось все что нам было нужно, и осталось это немного причесать, и из сырого вида привести в требуемый для таблицы. Колонка "Название" уже в требуемом виде. Напишем формулу в F2:

=iferror(arrayformula(REGEXEXTRACT(C2:C;"Мы продаем 1\+([\s\S]*)€"));"")

Этой формулой мы извлекаем из данных в столбце C все, что находится между словами "Мы продаем 1+" и знаком евро.

Кстати, про регулярные выражения у меня уже была статья. Почитайте, если интересно!

Аналогичная формула для ячейки G2:

=iferror(arrayformula(REGEXEXTRACT(D2:D;"Мы продаем 100\+([\s\S]*)€"));"")

И такая же для H2, с единственным отличием, что данные "мы покупаем" у нас отображаются вразнобой, то в столбце D то в столбце E:

=iferror(arrayformula(if(E2:E="";REGEXEXTRACT(D2:D;"Мы покупаем([\s\S]*)€");REGEXEXTRACT(E2:E;"Мы покупаем([\s\S]*)€"))))

Любуемся результатом:

-8

Два маленьких, финальных штриха. Скрываем колонки C:E. Обращаем внимание, что на исходном сайте отображается две страницы с товарами, и страницы подгружаются динамически.

Попробуем загрузить вторую страницу, добавив параметр page=2 в эдресной строке, как это делается на многих других сайтах. Фокус сработал. На скриншоте видно, что браузер перешел на страницу /page/2.

-9

Теперь нужно аналогичным образом вытянуть данные и по второй ссылке - дописать аналогичную формулу в конце таблицы, или воспользоваться массивом - вместо каждой формулы IMPORTXML подставить конструкцию:

={ <формула для первой ссылки> ; <формула для второй ссылки> }

Т.е. у нас получится такая формула для картинок:

=arrayformula(image(trim("http:"&index(split({IMPORTXML("адрес сайта";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//figure/span/img/attribute::data-srcset");IMPORTXML("адрес сайта/page/2";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//figure/span/img/attribute::data-srcset")};","&char(10);true;true);;7))))

И аналогично, формула для столбца B:

={IMPORTXML("адрес сайта";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//div[@class=""product__meta-box""]"); IMPORTXML("адрес сайта/page/2";"//div[@class=""grid__col--xs-6 grid__col--sm-4""]//div[@class=""product__meta-box""]")}

И вот, готовый результат - таблица из 41 строк:

-10

Саму таблицу вы можете найти по ссылке: https://docs.google.com/spreadsheets/d/1CIOfVun1Q3HTSsqU8Btsuc86K2LyBb4gavZu6qmPHd0/edit

Буду рад вашим вопросам или рекомендациям, как улучшить этот метод :-)