В ходе длительных манипуляци процесс переноса был разбит на несколько составляющих частей:
- Для начала выгрузил каталог товаров в xlsx-файл
- Далее написал скрипт, позволяющий прочитать данные из полученного файла. Для этого воспользовался библиотекой PhpExcel, которая позволяет достаточно успешно работать с Excel-файлами. Написал функцию перебора всех строк полученного excel-файла. Данные из файла перевел в массив функцией библиотеки
toArray. - Дальше полученный массив с данными с помощью ajax-отправки данных запустил в обработку.
Вот обработка и оказалась очень интересной. Мне нужно было перенести более 9 тыс. товаров, вместе с ценами, всеми характеристиками, изображениями. Т.е. аяксом мы передавали вводную информацию по каждому товару, а дальше начиналась обработка.
Обработка каждой конкретной страницы сводилась к манипуляциям с dom-структурой карточки товара. Для этого была использована библиотека PhpQuery.
Сначала нужно считать весь текст со страницы в строковую переменную.
function GetCurlData($url)
{
$altUrl = '/' . str_replace('/', '_', substr($url, 1));
if (file_exists($this->uploadFolder . $url))
{
return file_get_contents($this->uploadFolder . $url);
} elseif (file_exists($this->uploadFolder . $altUrl))
{
return file_get_contents($this->uploadFolder . $altUrl);
} else
{
$sourceFileHeaders = @get_headers($this->domain . $url);
if(preg_match("|200|", $sourceFileHeaders[0])){
$linkData = file_get_contents($this->domain . $url);
if (strlen($linkData) > 0)
{
file_put_contents($this->uploadFolder . $altUrl, $linkData);
return $linkData;
} else
{
return false;
}
} else {
echo 'ERROR WITH URL: ',$this->domain . $url;
}
}
}
Основной фишкой тут является сохранение полученного тела страницы в локальный файл, чтобы не сердить администратора сервера-донора частыми запросами (я раза с 10 построил полную структуру получения всех данных со страницы).
Дальше - проводим инициализацию библиотеки phpquery:
require_once $_SERVER['DOCUMENT_ROOT'] . '/some_path/phpQuery-onefile.php';
И строим объект PhpQuery для дальнейшей работы:
$pageDoc = phpQuery::newDocument($pageData);
Дальше проходим по dom-структуре и получаем нужные данные, которые объединяем в одно целое и сохраняем в базу данных.
Пример кода с обработкой dom-данных для получения текста с подробным описанием товара.
$description = $pageDoc->find('div.tab-info div.description');
foreach ($description->find('img') as $image)
{
$image = pq($image);
$src = $image->attr('data-bx-image');
if (strlen($src) > 0)
{
$image->removeAttr('data-bx-image');
} else
{
$src = $image->attr('src');
}
$src = $this->GetForeignImage($src, md5($url) . '-');
$image->attr('src', $src);
}
foreach ($description->find('a') as $link)
{
$link = pq($link);
$link->attr('target', '_blank');
}
$description = $description->html();
if(strlen($description)>0) $this->SaveToDB($description,$toID);
Данный код получает описание карточки товара, в описании вытягивает все изображения и сохраняет эти изображения локально со сменой ссылок на изображения в тексте описания. Также всем ссылкам добавлено открытие в новой вкладке (или можно их тут вообще удалить, или произвести кукую-то обработку). Функция обработки изображений, имеет вид:
function GetForeignImage($url,$hash=''){
if(strlen($url)<=0) return $url;
if(strpos($url,'http://')!==false || strpos($url,'https://')!==false){
$image = file_get_contents($url);
} else {
$image = file_get_contents($this->domain.$url);
}
$imageName = pathinfo($url);
$imageName = current(explode('?', $imageName['basename']));
$hash = '/'.$hash;
if (!file_exists($this->imagesFolder . $hash.$imageName))
file_put_contents($this->imagesFolder . $hash.$imageName, $image);
return $this->localImagesFolder.$hash.$imageName;
}
Вот такой вот вышел интересный скрипт, но при обработке столкнулся с проблемой - сервер сайта-донора таки заблокировал обращения с нового сервера:( - просто все страницы стали отдавать капчу, которую нужно ввести:( Решением стало получение данных через прокси. Об этом читайте в следующей статье!
