Вот в этой теме начинала обсуждение о поиске модуля для парсинга цен по заранее заданным в поле 'location' ссылкам и их последующей записи в поле 'cost'. В итоге, получился приведённый ниже php-скрипт. Но где-т я накосячила=(( А из-за почти полного незнания php не могу понять, что неправильно=(( Логика работы скрипта следующая: 1. Подключиться к MySQL-базе. 2. Получить значения переменной 'location' из таблицы 'product' (это ссылки, с которых нужно парсить цену). 3. Задать 'location' как ключ . 4. Задать регулярное выражение для парсинга цены. 5. Результат парсинга цены записать в поле 'cost' таблицы 'product' в базе MySQL. 6. Отключиться от MySQL. Этот скрипт будет вызываться из админки по нажатию кнопки "Обновить цены". Код: <?php // Подключаемся к БД $host="localhost"; $user="username"; $password="password"; $db="dbname"; $connection = mysql_connect($host, $user, $password) or die("MySQL сервер недоступен!".mysql_error()); mysql_select_db($db) or die("Нет соединения с БД".mysql_error()); // Формируем и отправляем запрос на извлечение переменных таблицы 'product'. Результат запишется в $result $query = 'SELECT * FROM `product`'; $result = mysql_query($query) or trigger_error(mysql_errno() . ' ' . mysql_error() . ' query: ' . $sql); // проверяем вернулась хотя бы 1 строка или нет if (mysql_num_rows($result) > 0) { // вытаскиваем одну за другой строки, помещаем в $row $ind = 0; while ($row = mysql_fetch_assoc($result)) { // строка вернулась в виде ассоциативного массива echo "model = {$row['location']} <br>"; $dataArr[$row['location']] = ''; // location как ключ в паре ключ/значение. } } else { echo 'Ошибка вывода значений'; } mysql_close($connection); $regex = '|<span class="" id="sku-price">(.*?)</span>|si'; // Задаём регулярное выражение для парсинга цены $success = True; foreach( $dataArr as $key => $value ) { $ch = curl_init (); // инициализация curl_setopt ($ch , CURLOPT_URL , $dataArr[$key]); // адрес страницы для скачивания curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7"); // каким браузером будем прикидываться curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); // нам нужно вывести загруженную страницу в переменную $content = curl_exec($ch); // скачиваем страницу if (False === $content) { // $success = False; // break; continue; // Не вышло в этот раз, ну и фиг с ним } // Задаём регулярное выражение для парсинга цены preg_match($regex, $content, $ok); //$dataArr[$key] = $ok[1]; $resArr[$key] = $ok[1]; } // Если ошибок не было, то массив содержит пары URL/Полученные данные. Их надо запихать обратно в базу if ($success) { $connection = mysql_connect($host, $user, $password) or die("MySQL сервер недоступен!".mysql_error()); mysql_select_db($db) or die("Нет соединения с БД".mysql_error()); // Параметризованный запрос для предотвращения SQL Injection $stmt = $pdo->prepare('UPDATE product SET cost = :cost WHERE location = :location'); // $updTpl = 'UPDATE product SET cost = "%cost" WHERE location = %s'; foreach( $resArr as $key => $value ){ $stmt->execute(array(':cost' => $value, ':location' => $location)); } mysql_close($connection);} else { echo 'Не удалось записать в базу'; // Ошибка записи в базу MySQL } НО! где-то на этапе между парсингом цены и записью полученного значения в базу данных происходит ошибка и в итоге, поле 'cost' не изменяется. Причем, к базе MeSQL подключается совершенно однозначно, значения получает. Также в отдельном файле работает парсинг цены (на конкретной прописанной странице .html, а не на переменной). Привожу пример кода, с которым скрипт без проблем получает значение цены с использованием данного регулярного выражения: Код: <?php $ch = curl_init (); // инициализация curl_setopt ($ch , CURLOPT_URL , 'http://www.sait.com/blablabla.html'); // адрес страницы для скачивания curl_setopt ($ch , CURLOPT_USERAGENT , "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7"); // каким браузером будем прикидываться curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 ); // нам нужно вывести загруженную страницу в переменную $content = curl_exec($ch); // скачиваем страницу $regex = '|<span class="" id="sku-price".*?>(.*?)</span>|si' ; // Задаём регулярное выражение для парсинга цены preg_match($regex, $content, $ok); echo $ok[1]; ?> Помогите, пожалуйста, разобраться!
Хехе, у меня есть такой же скрипт. И кстати говоря, regex не самое лучшее решение. Я юзал Zend_Dom_Query, поскольку это почти полный аналог языка css-селекторов. Соответственно вместо: Код: '|<span class="" id="sku-price".*?>(.*?)</span>|si' Можно писать простой запрос Код: query("span#sku-price") И честно говоря, мне крайне интересует интеграция этого чуда в карточку товара. Вы этим занимаетесь или тоже какое-то отдельное решение?
Спасибо за подсказку! Сейчас попробую изменить... У вас, я так понимаю, работает=) А насчет интеграции пока думаю, над этим. Но почему-то уверена, что всё получится. Как только разберусь с самим скриптом, буду думать дальше --- добавлено: 11 фев 2013 в 12:35 --- Не работает А можете своим скриптом поделиться? Может, проблема всё-таки в другом...
Конечно не работает, я же просто кусочек кода показал для демонстрации того что селекторы проще. Вот кусок кода, который отвечает за получение цены: Код: $html = @file_get_contents($articlesCompetitor->url); if( !$html ) throw new Exception("Отсутствует страница" ); $zdQuery = new Zend_Dom_Query($html); $elements = $zdQuery->query($competitor->selector); if( !count($elements) ) throw new Exception("Отсутствует цена" ); $price = 0; foreach( $elements as $element ) { $price = $this->CleanupPrice( $element->nodeValue ); break; // интересует только первый элемент } но это поможет только знающему. А лично вам, учитывая "А из-за почти полного незнания php не могу понять, что неправильно=((", это врядли пригодится . Если никто из местных не согласится помочь, то жду в личке, обсудим мои корыстные условия.
Вроде слабое место в регулярке $regex = '|<span class="" id="sku-price".*?>(.*?)</span>|si' попробуйте заменить на $regex = '|id="sku-price"(.*?)>(.*?)</span>|si'