Парсинг інтернет-магазинів

Розділимо парсинг (скрапінг) сайтів на дві підзадачі.

  1. Сам парсинг – пошук даних, які нам цікаві на сторінках.
  2. Осмислення отриманих даних.

Спочатку опишемо додатки:

  1. Парсер «постійної» інформації про товари із сайту. Цей парсер запускатиметься рідко (виключно для перевірки наявності нових товарів), розбиратиме сторінки та витягуватиме з них інформацію про товар: найменування, фотографії, властивості.
  2. Парсер умовно змінної інформації. Ця програма буде запускатися часто і автоматично, розбиратиме сторінки сайту для пошуку цін і наявності на складі для оновлення цієї інформації в БД (ми його розглядати не будемо, тут немає нічого незвичайного).
  3. Адмінка, структурування даних. Ця програма буде запускатися після парсера «постійної» інформації і дозволяє адміну розібрати/структурувати отримані дані.

Отже, поговоримо про парсерів

Методів парсингу багато, це й регулярні висловлювання та банальний пошук підрядка. Всі ці способи мають одну велику ваду – при невеликих змінах на сайті необхідно правити сам парсер. Для себе особисто (пишу під .net на c#) зупинився на бібліотеці HtmlAgilityPack, опис, наприклад, на Хабрі. Що вона дає - вона читає HTML (навіть багато не валідні документи) і будує DOM дерево. А далі входить у справу вся міць XPATH запитів. При правильно написаних запитах XPATH немає необхідності правити парсер при змінах на сайті.

Приклад: Для орієнтації в DOM часто використовуються класи, але ще частіше мінорні зміни в дизайні сайту виконуються додаванням відповідних класів до елементів (було class=”productInfo” сталоclass=”productInfo clearfix”). Тому в XPATH краще написати:

Так, це може позначитися на продуктивності, але не сильно. Універсальність коду – важливіше.

Так само при орієнтації в дереві за допомогою id елементів я, як правило, використовую "//" (тобто пошук по всьому піддереву), замість "/" (пошук тільки серед дочірніх елементів). Це рятує в ситуаціях, коли дизайнер обгортає будь-які теги (як правило, для фіксації будь-якого бага відображення):

Наступне питання – «що парсити?»

Парсити нам потрібно основну інформацію про товари: найменування, фотографія та, найголовніше, список властивостей. Отримані дані ми зберігатимемо у БД із примітивною структурою:

парсинг

Тобто. Для кожного товару буде список пар значень: назва властивості (propertyName) та її значення (propertyValue). Припустимо ми написали парсер, розібрали всі дані із сайту і хочемо тепер створити БД та сайт для пошуку товарів за параметрами. Для цього нам потрібно структурувати дані.

Структурування даних

Створимо ще пару таблиць БД для зберігання структурованих даних.

властивостей

Dict_Property - довідник властивостей (колір, розмір, вага і т.д., тобто всі властивості за якими ми потім будемо шукати) Product_Property - значення цих властивостей у конкретного товару.

Невелика «хитрість» - поле FloatValue - для числових якостей, формується за допомогою спроби конвертації поля Value у float:

Воно буде потрібно для пошуку (наприклад: поле «вага», запит від 100 до 300 грам, пошук текстового поля «Value» буде повільний і не правильний, а по floatValue – швидкий і коректний).

Тепер все готове для того, щоб почати структурувати дані.

Практика показала, що навіть найгірше оформлені китайські магазининамагаються уніфікувати опис товарів. Приклад: сайт dx.com, розпарено1267товарів. Усього вони49398властивостей. Якщо згрупуємо за назвою отримаємо всього580значень, що в принципі небагато.

Згрупуємо властивості за назвами та за значеннями, отримаємо табличку (властивість, значення, скільки разів зустрічається) та відсортуємо їх за частотою появи.

Всю таблицю наводити сенсу немає, відзначимо кілька моментів:

  • Перші 100 рядків таблиці (найбільш поширені значення властивостей) покривають близько 35-40% всіх значень властивостей.
  • Дуже багато властивостей і значень, що відрізняються один від одного тільки регістром або пробілами/друкарськими помилками.
  • Цифрові дані – як правило в одному форматі – наприклад, вага, габарити, обсяг оперативної пам'яті.

Для структурування даних напишемо додаток до створення «правил парсингу». Введемо 2 типи правил:

  • Точне співпадіння. Наприклад: властивість "Color", значення "Black"
  • Збіг за регулярним виразом. Наприклад: властивість Weight, значення (?\d*\.?\d+)g

До кожного правила визначимо набір властивостей, які потрібно додати товару. Як це виглядає на практиці:

інтернет-магазинів

Цим правилом ми «структуруємо» близько 90% значень для поля Weight, решта 10% через правила точних відповідностей:

значень

Для сайту "PandaWill", якщо властивість "GPS" дорівнює "Yes, built in" - додати властивість GPS зі значенням GPS, аналогічно для значень "Yes", "No", "N/A"

Звичайно зустрічаються властивості для яких доводиться створювати безліч правил, наприклад, дозвіл екрана. Для якихось товарів воно названо "Display":

парсинг

А для якихось "Screen resolution":

даних

Трохи статистики: у моємуУ цьому випадку створено близько 7000 правил для структурування даних, які додали трохи менше 50000 значень властивостей. Тобто. одне правило - 7 значень. З додаванням нових товарів це число збільшується, що не може не тішити.

Після всіх цих маніпуляцій ми отримуємо БД із структурованою інформацією про товари. А пошук по цій БД – тривіальне завдання.