Требуется помощь по PHP

12
-
На сайте с 14.12.2011
Offline
14
2541

Здравствуйте.

Есть скрипт который парсит все товары продавца по его ид в системе digiseller.ru.

При 700 наименований товара данный код выполняется более 1й минуты.

Возможно ли как-нибудь снизить время выполнение этого скрипта?

$sellerID = '162527';	//ИД продавца, для примера


function _GD($address, $xml){
$ch = curl_init($address);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$result=curl_exec($ch);
curl_close($ch);
return $result;
}

//Группы товаров
$xml='<digiseller.request>'
.'<id_seller>'.$sellerID.'</id_seller>'
.'<order></order>'
.'</digiseller.request>';
$answer = _GD("http://shop.digiseller.ru/xml/personal_groups.asp", $xml); $xmlres = simplexml_load_string($answer);

$groups = array();
foreach($xmlres->rows->row as $row){
$groups[] = $row->id_group;
}

//id товаров из всех групп
$items = array();
foreach($groups as $group){
$xml='<digiseller.request>'
.'<id_group>'.$group.'</id_group>'
.'<page>1</page>'
.'<rows>999</rows>'
.'<currency>RUR</currency>'
.'<order>name</order>'
.'</digiseller.request>';
$answer = _GD("http://shop.digiseller.ru/xml/personal_goods.asp", $xml);
$xmlres = simplexml_load_string($answer);
foreach($xmlres->rows->row as $row){
$items[] = $row->id_goods;
}
}

$itm = array_unique($items); //Т.к в разных группах может повторяться один и тот же товар- чистим дубли

//Информация о товарах
foreach($itm as $item){
$xml='<digiseller.request>'
.'<id_goods>'.$item.'</id_goods>'
.'</digiseller.request>';
$answer = _GD("http://shop.digiseller.ru/xml/personal_goods_info.asp", $xml);
$xmlres = simplexml_load_string($answer);
echo $xmlres->id_goods.' :: '.$xmlres->price_goods->wmr.' руб. :: '.$xmlres->type_goods.' :: '.$xmlres->name_goods.'<br>';
}
Lord Maverik
На сайте с 15.04.2003
Offline
471
#1

Чем вас скорость не устраивает? 10 запросов в секунду.

Можете пойти другим путем, парсите digiseller не в прямом эфире. Типа как бот Яндекса. Пропарсили, сохранили в базу. Завершили один обход, пошли по новой. Повесите на крон и все. Можно в несколько потоков делать.

Пока digiseller не забанит ваш ip :)

Ну а потом уже с базы выводите все что нужно.

RedMall.Ru (https://redmall.ru) - Товары из Китая (Таобао, Tmall) с проверкой качества, скидка для форумчан 7% Партнерская программа 2 уровня: 5% + 5%. Подробнее. (https://redmall.ru/about/partner/)
-
На сайте с 14.12.2011
Offline
14
#2

Это нужно для работы продавца со своим товаром.

Т.е ввел продавец свой ID - выводим ему информацию о его товарах.

Поэтому важна скорость и вариант с кроном не подходит...

Я PHP только начинаю изучать, знаю не много. Думал что можно это более грамотно составить и ускорить весь процесс.

Если с увеличением скорости не получится, может можно через яваскрипт подгружать результат выполнения этого скрипта? Было бы неплохо, если во время работы скрипта выводилась картинка(loader), а после выполнения - результат.

Lord Maverik
На сайте с 15.04.2003
Offline
471
#3
-Ilnur-:
может можно через яваскрипт подгружать результат выполнения этого скрипта? Было бы неплохо, если во время работы скрипта выводилась картинка(loader), а после выполнения - результат.

Конечно можно и так. Сложностей нет. Можете использовать jquery для этого.

vlasoff
На сайте с 31.08.2007
Offline
101
#4

Используйте curl_multi

[Удален]
#5

Можно использовать другой язык, поддерживающий потоки.

В php все таки эмуляция потоков

-
На сайте с 14.12.2011
Offline
14
#6
vlasoff:
Используйте curl_multi

Сделал. Скорость раз в 5-7 увеличилась(в общем то это и устраивает), но теперь не хочет обрабатывать более 400-450 товаров - выскакивает "502 Bad Gateway".

С этим что-нибудь можно сделать:)?

dma84
На сайте с 21.04.2009
Offline
168
#7
-Ilnur-:
Сделал. Скорость раз в 5-7 увеличилась(в общем то это и устраивает), но теперь не хочет обрабатывать более 400-450 товаров - выскакивает "502 Bad Gateway".
С этим что-нибудь можно сделать:)?

Ну правильно выскакивает, ограничивайте количество одновременных потоков

Тут у товарища та же проблема

-
На сайте с 14.12.2011
Offline
14
#8

Запустил скрипт на другом хостинге- грузится, ошибок не вылазит.

dma84:
ограничивайте количество одновременных потоков

Каким образом можно ограничить, не подскажите?

dma84
На сайте с 21.04.2009
Offline
168
#9
-Ilnur-:
Каким образом можно ограничить, не подскажите?

У вас потоки создаются в цикле, правильно? Я не знаю как у Curl, но на неблокируемых сокетах я открывал N потоков, а не все сразу, если количество открытых потоков меньше, чем мне надо, то в том же цикле открывал новый поток.

Во многих примерах в сети народ открывает сразу все потоки в одном цикле. Обычно Curl держит до 100 потоков и жрёт много памяти. Вам же нужно контролировать количество одновременно открытых потоков

-
На сайте с 14.12.2011
Offline
14
#10

Пытался понять как это сделать, но так ничего на ум не пришло...

dma84, если знаете, подскажите как в этом коде ограничить количество одновременно открытых потоков.

	$curls = array();

$result = array();
$mh = curl_multi_init();
foreach ($ids as $id => $p){
$curls[$id] = curl_init();
curl_setopt($curls[$id], CURLOPT_URL, $url);
curl_setopt($curls[$id], CURLOPT_HEADER, 0);
curl_setopt($curls[$id], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curls[$id], CURLOPT_POST, 1);
curl_setopt($curls[$id], CURLOPT_POSTFIELDS, $p);
curl_multi_add_handle($mh, $curls[$id]);
}
$running = null;
do{
curl_multi_exec($mh, $running);
}
while($running > 0);
foreach($curls as $id => $content){
$result[$id] = curl_multi_getcontent($content);
curl_multi_remove_handle($mh, $content);
}
curl_multi_close($mh);
return $result;
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий