Проверка фото из отзывов на AliExpress
На AliExpress пользователи очень часто оставляют отзывы о товарах. Обычно это рассказы о качестве товаров, личные впечатления об использовании и комментарии о сервисах и сроках доставки.
Но самый большой интерес и пользу представляют фото с распаковкой товаров. Девушки охотно демонстрируют фото себя в купленном нижнем белье, а парни выкладывают фото комплектации покупки.
По фотографии можно сразу увидеть качество товара в реальности. Которое в большинстве случаев очень сильно отличается от того что рекламируется.
Но есть одно «Но». Фото в отзывах ужасно маленького размера и нет галереи, где можно прокликать все фото за один раз.
Пример того, как выглядят фото в отзывах на AliExpress — bit.ly/2C7myX3
Чтобы исправить ситуацию я решил написать свой парсер фото из товаров и сделать плиточный дизайн в стиле Pinterest.
Адрес сайта — alipic.net.
На момент написания статьи доступны следующие фичи:
1. Парсер фото из отзывов по URL товара.
2. Поиск товаров с максимальным рейтингом по ключевому слову.
3. Вывод Топ продаваемых товаров на AliExpress за неделю.
Чтобы понять зачем это все нужно, давайте посмотрим на выдачу комментариев на AliExpress и Alipic — bit.ly/2o1e1Tg
Товар на AliExpress — bit.ly/2nI7v3T
Фото отзывов на Alipic — bit.ly/2j7zoRe
Далее расскажу о технической реализации парсера фото на php.
Страница продукта состоит из двух блоков — bit.ly/2yqVujg
1. Информация о товаре (цена, название, рейтинг, скидка, ссылка на магазин). Реализовано через API AliExpress.
2. Фото отзывов. Реализовано с помощью прямого парсинга с помощью CURL + SimpleDom.
Для получения API нужно зарегистрировать на AliExpress Developer. Проверка акаунта заняла 5 дней.
Парсим фото из отзывов по URL товара.
В API AliExpress нет доступа к фото из отзывов. Потому смотрим откуда Али вытягивает комментарии:
Открываем страницу любого продукта (в примере — bit.ly/2j7zoRe), запускаем девелоперскую консоль и ищем блок с комментарием — bit.ly/2jSjrLW
Как видим, Али подгружает комментарии в <iframe>. Это очень хорошо, так как не нужно будет грузить полностью всю страницу.
Прямой URL коментариев с параметрами: feedback.aliexpress.com/...startValidDate=&i18n=true
Параметры которые важны:
productId — уникальный айдишник каждого товара.
withPictures — включить, выключить комментарии с фото. Значения true,false.
Урлы товара бывают разного формата. Для получения productId из урла используем regexp:
$primary_url = filter_input(INPUT_GET, "url");
if (strpos($primary_url, '//group.') == 0) {
preg_match_all("/(\w+\.\w{2,4})/", $primary_url, $prod_id);
$prod_id[0][2] = str_replace('.html', '', $prod_id[0][2]);
$prod_id[0][2];
$prod_id_url = $prod_id[0][2];
}
$prod_id_url_num = $prod_id_url;
if (strpos($primary_url, '//group.') != 0) {
$prod_id_url_num_1 = explode('-', $primary_url);
$prod_id_url_num = $prod_id_url_num_1[1];
}
if (strpos($primary_url, '/store/') != 0) {
$prod_id_url_num_1 = explode('_', $prod_id_url_num);
$prod_id_url_num = $prod_id_url_num_1[1];
}
После получения productId готовим ссылки для парсинга:
$prod_id_url = "feedback.aliexpress.com/display/productEvaluation.htm?productId=" . $prod_id_url_num . "&ownerMemberId=221794469&companyId=231687423&memberType=seller&startValidDate=&i18n=true&withPictures=true&translate=N&evaStarFilterValue=all+Stars"; $prod_url_api = "http://gw.api.alibaba.com/openapi/param2/2/portals.open/api.getPromotionProductDetail/".$ali_api_key."?fields=originalPrice,salePrice,discount,evaluateScore,volume,storeUrl,productTitle,imageUrl,productUrl,storeName&language=" . $lang . "&productId=" . $prod_id_url_num . "";
Далее нам нужно параллельно загружать API запрос и парсить страницу с комментариями.
Функция параллельного парсинга:
function multi_parser($url) {
$ch = array();
$responce = array();
$mh = curl_multi_init();
for ($i = 0; $i < sizeof($url); $i++) {
$ch[$i] = curl_init($url[$i]);
curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch[$i], CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch[$i], CURLOPT_HEADER, 0);
$agent = "AAPP Application/1.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.4)";
curl_setopt($ch[$i], CURLOPT_URL, $url[$i]);
curl_setopt($ch[$i], CURLOPT_TIMEOUT, 10);
curl_setopt($ch[$i], CURLOPT_MAXREDIRS, 50);
curl_setopt($ch[$i], CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch[$i], CURLOPT_COOKIEFILE, 'cookie.txt');
curl_multi_add_handle($mh, $ch[$i]);
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
//close all and get content as string
for ($i = 0; $i < sizeof($url); $i++) {
curl_multi_remove_handle($mh, $ch[$i]);
$responce[$i] = curl_multi_getcontent($ch[$i]);
}
curl_multi_close($mh);
return array($responce);
}
Получение контента страниц в массив:
$url_compose [0] = $prod_id_url; $url_compose [1] = $prod_url_api; $multi_urls = array_values($url_compose); list($urls) = multi_parser($multi_urls);
Теперь парсим информацию о товаре, которую получили в json формате:
foreach ($json as $key) {
$price_discount = $key->originalPrice;
$price = $key->salePrice;
$discount_rate = $key->discount;
$rate = $key->evaluateScore;
$orders = $key->volume;
$store_title = $key->storeName;
$store_link = $key->storeUrl;
$prod_title = $key->productTitle;
$thumb_src = $key->imageUrl;
break;
}
originalPrice - Цена товара без скидки.
salePrice - Цена товара с учетом скидки.
discount - Скидка.
evaluateScore - Рейтинг магазина.
volume - Количество товаров доступных для продажи.
storeName - Название магазина продавца.
Для парсинга страницы комментариев используем SimpleDom библиотеку и обращаемся к DOM элементам страницы:
$html = str_get_html($urls[0], false, stream_context_create($arrContextOptions));
if ($html) {
foreach ($html->find('input [id="cb-withPictures-filter"] em') as $element) {
$pages = $element->innertext;
$pages = ceil($pages / 10);
$images = $element->innertext;
}
if (!$images) {
$images = 0;
}
foreach ($html->find('p[class="r-score-des"]') as $element) {
$rating = $element->innertext;
}
$urls_list = array();
$pages_left = $pages;
if ($cur_page == '') {
$cur_page = 1;
}
for ($i = $cur_page; $i <= $cur_page; $i++) {
$urls_list[$i] = $prod_id_url . "&page={$i}";
}
$multi_urls = array_values($urls_list);
list($urls) = multi_parser($multi_urls);
$all_ali_img = array();
$n = 0;
for ($i = 0; $i < sizeof($urls); $i++) {
$arrContextOptions = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
),
);
$html = str_get_html($urls[$i], false, stream_context_create($arrContextOptions));
foreach ($html->find('img') as $element) {
$all_ali_img[$n] = $element->src;
$n++;
}
//comments counter
$com_num = 0;
$glob_array = array();
$img_array = array();
$stars_array = array();
$comment_array = array();
$devilery_array = array();
$date_array = array();
$flag_array = array();
foreach ($html->find('div[class=feedback-item]') as $element) {
$img_ar = 0;
$star_ar = 0;
$com_ar = 0;
$delivery_ar = 0;
$date_ar = 0;
$flag_ar = 0;
//img urls
foreach ($element->find('ul[class=util-clearfix] li img') as $img) {
$img_array[$img_ar] = $img->src;
$img_ar++;
}
$glob_array[$com_num][1] = $img_array;
//stars
foreach ($element->find('span[class=star-view] span') as $stars) {
$stars_array[$star_ar] = $stars->style;
$stars_array[$star_ar] = str_replace('width:', '', $stars_array[$star_ar]);
$star_ar++;
}
$glob_array[$com_num][2] = $stars_array;
//comment
foreach ($element->find('dt[class=buyer-feedback] span') as $comment) {
$comment_array[$com_ar] = $comment->innertext;
$com_ar++;
}
$glob_array[$com_num][3] = $comment_array;
//delivery
foreach ($element->find('div[class=user-order-info] span') as $delivery) {
$devilery_array[$delivery_ar] = $delivery->innertext;
$devilery_array[$delivery_ar] = str_replace('Logistics:', '', $devilery_array[$delivery_ar]);
$devilery_array[$delivery_ar] = str_replace('Size:', '', $devilery_array[$delivery_ar]);
$devilery_array[$delivery_ar] = str_replace('Color:', '', $devilery_array[$delivery_ar]);
if ($lang == 'en') {
$devilery_array[$delivery_ar] = str_replace('Доставка', 'Logistics', $devilery_array[$delivery_ar]);
}
$delivery_ar++;
}
$glob_array[$com_num][4] = $devilery_array;
//date
foreach ($element->find('dd[class=r-time]') as $date) {
$date_array[$date_ar] = $date->innertext;
$date_ar++;
}
$glob_array[$com_num][5] = $date_array;
//flag
foreach ($element->find('div[class=user-country] b[class=css_flag]') as $flag) {
$flag_array[$flag_ar] = $flag->innertext;
$flag_ar++;
}
$glob_array[$com_num][6] = $flag_array;
$com_num++;
}
}
$url_valid = 1;
} else {
$url_valid = 0;
}
Для отрисовки фото в стиле Pinterest использовалась библиотека Mansory.JS
Исходный код парсера на github — github.com/...ter/ali_exp_img_parse.php

27 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів