Как решить проблемы интерполяции строк и доработать код чтобы работала пагинация при парсинге данных в php?
Еще раз здравствуйте друзья и коллеги. Все хорошего дня и замечательного здоровья. Помогите разобраться уже 2 день пытаюсь с чатом ГПТ на перелом найти решение простого вопроса.
Суть такая есть скрипт который должен брать код страницы интернет магазина проиводить выборку тегов с соотвествующим классом и брать их содержимое, заносить в свойства обьекта, который создаем уже в середине кода.
<?php global $postCount; include_once 'db.php'; include_once 'simple_html_dom.php'; function curlGetPage($url, $referer = 'https://google.com/') { $ch = curl_init(); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); $response = curl_exec($ch); return $response; } function parseAndInsertData($html) { global $db; foreach ($html->find('*[class="col-6 col-lg-4 col-xl-3 us-item"]') as $element) { $img = $element->find('*[class="img-fluid oct-lazy"]',0); $link = $element->find('.us-module-img a', 0); $priceElem = $element->find('*[class="us-module-price-actual"]',0); $price = $priceElem->plaintext; $priceJIS = float($price); $post = [ 'img' => $img->src, 'title' => $img->alt, 'link' => $link->href, 'price' => $price, ]; $priceN = isset($post['price']) ? floatval($post['price']) : 0; // Используем подготовленные запросы для избежания SQL инъекций $priceCH = floatval($price); $db->query("INSERT IGNORE INTO posts (`title`, `img`, `link`, `price`) VALUES('{$post['title']}', '{$post['img']}', '{$post['link']}', {$priceN})"); echo "Step cycle" . PHP_EOL; $price = $priceElem->plaintext; echo "Original price: " . $price . PHP_EOL; $priceCH = floatval($price); echo "Parsed price: " . $priceN . PHP_EOL; } } //$page = curlGetPage('https://optitrade.dp.ua/zaryadni-prystroyi'); //$html = str_get_html($page); $url = 'https://***/zaryadni-prystroyi?page=1'; $page = curlGetPage($url); $html = str_get_html($page); // Parse and insert data from the first page parseAndInsertData($html); $pagenavi = $html->find('.pagination'); $pageCount = count($pagenavi); $postCount = 0; for ($i = 2; $i <= $pageCount; $i++) { // Set the correct referer for pagination $referer = "https://***/zaryadni-prystroyi/?page=$i"; // Fetch the page content $page = curlGetPage($referer, $referer); $html = str_get_html($page); // Parse and insert data from the current page parseAndInsertData($html); usleep(1500000); // Optionally, you can add a limit to the number of pages to parse if ($i > 100) { break; } } ?> |
<?php global $postCount; include_once 'db.php'; include_once 'simple_html_dom.php'; function curlGetPage($url, $referer = 'https://google.com/') { $ch = curl_init(); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); $response = curl_exec($ch); return $response; } function parseAndInsertData($html) { global $db; foreach ($html->find('*[class="col-6 col-lg-4 col-xl-3 us-item"]') as $element) { $img = $element->find('*[class="img-fluid oct-lazy"]',0); $link = $element->find('.us-module-img a', 0); $priceElem = $element->find('*[class="us-module-price-actual"]',0); $price = $priceElem->plaintext; $priceJIS = float($price); $post = [ 'img' => $img->src, 'title' => $img->alt, 'link' => $link->href, 'price' => $price, ]; $priceN = isset($post['price']) ? floatval($post['price']) : 0; // Используем подготовленные запросы для избежания SQL инъекций $priceCH = floatval($price); $db->query("INSERT IGNORE INTO posts (`title`, `img`, `link`, `price`) VALUES('{$post['title']}', '{$post['img']}', '{$post['link']}', {$priceN})"); echo "Step cycle" . PHP_EOL; $price = $priceElem->plaintext; echo "Original price: " . $price . PHP_EOL; $priceCH = floatval($price); echo "Parsed price: " . $priceN . PHP_EOL; } } //$page = curlGetPage('https://optitrade.dp.ua/zaryadni-prystroyi'); //$html = str_get_html($page); $url = 'https://***/zaryadni-prystroyi?page=1'; $page = curlGetPage($url); $html = str_get_html($page); // Parse and insert data from the first page parseAndInsertData($html); $pagenavi = $html->find('.pagination'); $pageCount = count($pagenavi); $postCount = 0; for ($i = 2; $i <= $pageCount; $i++) { // Set the correct referer for pagination $referer = "https://***/zaryadni-prystroyi/?page=$i"; // Fetch the page content $page = curlGetPage($referer, $referer); $html = str_get_html($page); // Parse and insert data from the current page parseAndInsertData($html); usleep(1500000); // Optionally, you can add a limit to the number of pages to parse if ($i > 100) { break; } } ?>
Вопрос вот в чем как изменить код и значения переменных в которые есть обьекты?
$priceElem = $element->find('*[class="us-module-price-actual"]',0);
$price = $priceElem->plaintext;
$priceJIS = float($price);
Почему в запросе $db в базу данных попадает пустое значение 0 в поле `price`.
Дополнительно:
Чтобы решить проблему с пагинайией нужно:
1. Получить или сгенерировать ссылки на страницы (у вас там ссылки однотипные, можно получить послнднюю, а все остальные перебрать через for).
2. Обработать каждую страницу
Что такое интерполяция строк?
В моем случае я подозреваю что в строках с обьектами и его свойства тип данных string который нужно перевести к типо float- но нигде в отладке немогу найти как и почему в переменной вначале есть $price, а затем куда-то пропадает. В строчке где priceN содержимое уже = 0. Куда пропадает вообще значение из $price в ввиду неравенство между типами данных (там строка єто я понимаю) но почему не срабатівает метод floatval($post['price']) к такому приведению и переводу типизации данных. В строках 35, 43, 46 например где указано.:
$priceN = isset($post['price']) ? floatval($post['price']) : 0;
Интерполя́ция, интерполи́рование (от лат. inter–polis — «разглаженный, подновлённый, обновлённый; преобразованный») — в вычислительной математике нахождение неизвестных промежуточных значений некоторой функции, по имеющемуся дискретному набору её известных значений, определенным способом. Термин «интерполяция» впервые употребил Джон Валлис в своём трактате «Арифметика бесконечных» (1656).
Я думаю, он срабатывает.
isset у вас всегда срабатывает, значит и floatval всегда будет применятся.
Ну и да, для floatval вернуть ноль - нормальное поведение, если у него на входе мусор.
Вы бы под отладчиком посмотрели, ну или хоть echo натыкайте.
Я смотрю в отладчике уже 2 часа. Клацаю туда сюда step over доклацал до того что у меня щас уже шиза начнеться. $price = "$5.90" а вот уже $priceCH и $priceN все по нулям уже в отладке везде на разных брейкпоинтах... Даже закоментил щас // $priceJIS = float($price);
Я вам сейчас покажу даже точное место вашего тупняка: https://ideone.com/PusAbT
Мусор на входе - мусор на выходе!
https://www.php.net/manual/ru/function.ltrim.php
Ответы:
тобы решить проблему с пустым значением 0 в поле price, вы можете изменить способ преобразования строки $price в число. Вместо float($price), я предлагаю использовать функцию str_replace() для удаления всех нечисловых символов из строки, а затем преобразовать результат в число.
$price = $priceElem->plaintext; $priceCleaned = str_replace(',', '.', preg_replace('/[^0-9,.]/', '', $price)); $priceN = floatval($priceCleaned); |
$price = $priceElem->plaintext; $priceCleaned = str_replace(',', '.', preg_replace('/[^0-9,.]/', '', $price)); $priceN = floatval($priceCleaned);
Таким образом, $priceN будет содержать корректное числовое значение price, которое можно использовать для вставки в базу данных.
После этого, вы можете использовать $priceN в вашем запросе вместо $priceCH
$db->query("INSERT IGNORE INTO posts (`title`, `img`, `link`, `price`) VALUES('{$post['title']}', '{$post['img']}', '{$post['link']}', {$priceN})"); |
$db->query("INSERT IGNORE INTO posts (`title`, `img`, `link`, `price`) VALUES('{$post['title']}', '{$post['img']}', '{$post['link']}', {$priceN})");
Это должно решить проблему с пустым значением 0 и корректно передавать числовое значение price в базу данных.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для решения проблемы интерполяции строк и обеспечения правильной работы пагинации при парсинге данных в PHP, вам необходимо использовать двойные кавычки внутри строки для подстановки переменных значений.
Например, если у вас есть строка, в которой вы хотите вставить значение переменной, вы можете сделать это следующим образом:
$name = "John"; echo "Привет, $name!";
Это позволит интерпретатору PHP правильно обработать переменную $name и вставить ее значение в строку.
Что касается работы с пагинацией при парсинге данных, вам необходимо учитывать размер страницы (сколько элементов вы хотите отобразить на одной странице) и текущий номер страницы.
Вы можете использовать GET параметры в URL для передачи номера страницы, например:
$page = isset($_GET['page']) ? $_GET['page'] : 1; $perPage = 10; $offset = ($page - 1) * $perPage; // Здесь вы можете выполнить запрос к базе данных или другую логику для получения данных с учетом пагинации // Далее вы можете отобразить данные на странице с учетом пагинации
Таким образом, вы сможете правильно обрабатывать пагинацию и отображать данные в соответствии с выбранной страницей. Не забудьте также добавить ссылки на другие страницы для навигации между страницами.
Надеюсь, данное объяснение поможет вам решить проблемы интерполяции строк и настроить работу пагинации при парсинге данных в PHP. Если у вас возникнут дополнительные вопросы, не стесняйтесь их задавать!