Парсинг сайтів-магазинів
Розділимо парсинг (скрапінг) сайтів на дві підзадачі.
- Сам парсинг – пошук даних, які нам цікаві на сторінках.
- Осмислення отриманих даних.
Спочатку опишемо додатки:
- Парсер «постійної» інформації про товари із сайту. Цей парсер запускатиметься рідко (виключно для перевірки наявності нових товарів), розбиратиме сторінки та витягуватиме з них інформацію про товар: найменування, фотографії, властивості.
- Парсер умовно змінної інформації. Ця програма буде запускатися часто і автоматично, розбиратиме сторінки сайту для пошуку цін і наявності на складі для оновлення цієї інформації в БД (ми його розглядати не будемо, тут немає нічого незвичайного).
- Адмінка, структурування даних. Ця програма буде запускатися після парсера «постійної» інформації і дозволяє адміну розібрати/структурувати отримані дані.
Отже, поговоримо про парсерів
Методів парсингу багато, це й регулярні висловлювання та банальний пошук підрядка. Всі ці способи мають одну велику ваду – при невеликих змінах на сайті необхідно правити сам парсер. Для себе особисто (пишу під .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 значень. З додаванням нових товарів це число збільшується, що не може не тішити.
Після всіх цих маніпуляцій ми отримуємо БД із структурованою інформацією про товари. А пошук по цій БД – тривіальне завдання.