Проверка фото из отзывов на 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 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів