Здравствуйте. Помогите, пожалуйста, я запускаю свой парсер по крон, забираю им некоторую информацию с сайта моего поставщика и обрабатываю ее. Парсер запускается-то всего на 500 страниц товаров, у меня таких аж 8000 тысяч, но даже на 500 артикулов парсер съедает все ресурсы и приводит сервер в нерабочее состояние, к нему не подключится по ssh и все сайты отдают 500-сотые ошибки. Я понимаю, что скорее всего дело в том, что мой парсер не оптимизирован, так как сама я не разбираюсь в этом пока что, прошу совета, что тут следует переписать? Парсер сначала авторизуется на сайте поставщика, потому что только так видны остатки, а потом от имени авторизованного пользователя собирает информацию. Как соберет формирует запрос на обновление базы данных, запросы скидывает в массив, только в конце работы делается одно подключение к БД и выполняется запрос на обновление. У меня 1 Гб ОЗУ на сервере.
ini_set('max_execution_time', '10000');
set_time_limit(0);
ini_set('memory_limit', '768M');
ignore_user_abort(true);
require_once 'vendor/autoload.php';
require_once 'phpquery/phpQuery/phpQuery.php';
//УРЛ для выполнения авторизации
$url_auth = 'http://...';
//Заданный мною массив, где ключ это артикул товара, а значение его product_id в моем магазине
$massiv = [
"артикул поставщика" => "мой product_id",
...
]
//Объявляю массивы, которые могут быть заполнены впоследствии.
$existart = []; $existartstatus = []; $existartstatus2 = []; $notupdated = [];
//Создаю файлы, в которые буду записывать нужные мне значения по ходу работы
$file_result = 'not_added.txt'; if (file_exists($file_result)) unlink($file_result);
$file_result2 = 'empty.txt'; if (file_exists($file_result2)) unlink($file_result2);
$file_result3 = 'not_updated.txt'; if (file_exists($file_result3)) unlink($file_result3);
//Данная функция будет вызываться для парсинга каждой отдельной страницы товара для того, что авторизованным забрать содержимое страницы
function get_content($url) {
$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_HEADER, 0);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)");
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, array(
'login' => '###',
'pass' => '###',
));
curl_setopt ($ch, CURLOPT_COOKIEJAR, __DIR__ . '/cook.txt');
curl_setopt ($ch, CURLOPT_COOKIEFILE, __DIR__ . '/cook.txt');
curl_setopt ($ch, CURLOPT_TIMEOUT, 3000);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 300);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
$merged = "это массив со ссылками на карточки товаров, по которым нужно пройтись"
//Главная функция, отрабатывающая для каждой ссылки
function foreach_parser() {
global $merged; global $massiv; global $existart; global $existartstatus; global $existartstatus2; global $notupdated; global $file_result; global $file_result2; global $file_result3;
foreach ($merged as $page){
$file = get_content($page);
$doc = phpQuery::newDocument($file);
$doc = pq($doc);
$art = $doc->find('#r div.x div.xx div.xxx')->text();
$art = str_replace("/"," ",$art);
$art = trim($art);
/* Тут еще выполняется несколько операций по нахождению значений и их обработки. Определяются переменные $stock, $status и прочие */
//Проверяю содержится ли в моем заранее заданном массиве элемент с ключом, равным данному артикулу, если да, то для него забирается его значение
if (isset($massiv[$art])) {
if ($status == "Preorder") {
$value = $massiv[$art];
$existart[] = "WHEN product_id = ".$value." THEN ".$stock;
$existartstatus[] = "WHEN product_id = ".$value." THEN 'Под заказ'";
$existartstatus2[] = "WHEN product_id = ".$value." THEN 24";
} else {
$value = $massiv[$art];
$existart[] = "WHEN product_id = ".$value." THEN ".$stock;
}
$value2 = $massiv[$art];
$notupdated[] = $value2;
} else {
//Элемента массива с таким ключом не найдено, значит записываем данный артикул в файлик
$message = $art.PHP_EOL;
file_put_contents($file_result, $message, FILE_APPEND);
}
echo $art." обработан! ";
$i++;
}
//Если мои массивы заполнились каким-то данными, тогда я сливаю их элементы в единую строку
if($existart) {$existart_oneline = implode(" ", $existart);}
if($existartstatus) {$existartstatus_oneline = implode(" ", $existartstatus);}
if($existartstatus2) {$existartstatus2_oneline = implode(" ", $existartstatus2);}
$massiv_onlyid = implode(",", $massiv);
//Сравниваю изначально заданный мною массив с полученным в результате парсинга массивом для того, чтобы найти те товары, которые у меня в массиве (на сайте) есть, а в процессе работы парсинга не были задействованы, так я понимаю, какие остатки у меня не обновились.
$mas_notupdated = array_diff($massiv, $notupdated);
if ($mas_notupdated) { $mas_notupdated_txt = implode('`', $mas_notupdated); file_put_contents($file_result3, $mas_notupdated_txt); }
//Подключаюсь к базе данных и выполняю запросы на обновление остатков и при необходимости других полей
$linkmysql = mysqli_connect('localhost', 'xxx', 'xxx', 'xxx');
if (!$linkmysql) {
$sqlconnecterror = "Ошибка: Невозможно установить соединение с MySQL.";
exit;
}
if ($linkmysql) {
if($existart) {
Первый запрос на обновление информации
}
if($existartstatus) {
Второй запрос на обновление информации
}
mysqli_close($linkmysql);
}
phpQuery::unloadDocuments();
}
$data = get_content($url_auth);
foreach_parser();
Парсер грузит оперативку до 99,9% и всё, дальше ничего не работает. Я поставила ему memory_limit', '512M', но он все равно забирает всю оперативную память. Как ему не позволять забирать все ресурсы?