IPB

Здравствуйте, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> Как сделать Парсер на PHP
t800
сообщение 04 Mar 2017, 10:18 (Сообщение отредактировал t800 - 05 Mar 2017, 11:16)
Сообщение #1

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




У нас в городе есть компьютерный магазин. Заведует им дядя Стёпа. Этот магазин все знают и там покупают компьютеры. А так как теперь эра интернета, то у этого магазина тоже появился интернет магазин , через который тоже можно будет покупать. Но он пока пустой, так как он не заполнен, а так как дяде Стёпе некогда его заполнять (потому что в офисе дел полно), то он поручил мне эту задачу.

И теперь мне нужно заполнить магазин на VirtualMart3 такими же товарами как на другом сайте (из другого города) где стоит Битрикс. Я уже создал категории, начинаю добавлять к ним картинки, но с товарами сложности потому что в ручную это делать замучаешься, ибо товаров на другом магазине около 1000, и даже больше. И каждый нужно перенести и не только название и цену (и еще ее при этом умножить на разные проценты) да ещё и описания картинки в придачу. Я их уже третий день вечером после школы переношу и понял, что в ручную переносить это будет долго. Недельки 3 где-то, и мне захотелось попробовать написать скрипт чтобы автоматом перенести товары как это надо, потому что вручную заполнять оно как-то очень скучно.

Ну и у меня вопрос а как сделать такой пасер?


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 04 Mar 2017, 15:55 (Сообщение отредактировал feanor - 04 Mar 2017, 15:55)
Сообщение #2

laughed as one fey
Сообщений: 12 166
Спасибо сказали: 20581 раз




Скачиваешь страницы магазина, разбираешь при помощи XPath (на худой конец - регулярных выражений, но xpath удобнее, потому что отладчик хрома).

(буквально пару дней назад на работе была такая задача, только еще надо было еще давать аналитикам заполнять окно фильтров на сайте. Почти три дня промудохался, блин.)


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 04 Mar 2017, 16:39 (Сообщение отредактировал t800 - 04 Mar 2017, 16:40)
Сообщение #3

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Цитата(feanor @ 04 Mar 2017, 18:55) *
Скачиваешь страницы магазина, разбираешь при помощи XPath (на худой конец - регулярных выражений, но xpath удобнее, потому что отладчик хрома).


Сейчас попгулил про XPath если правильно понял через XPath в Mozilla надо смотреть откуда что надо брать.
Ну вот я взял любой странице название товара, описание и название картинки, куда это потом сохранять в текстовый файлик? А каких брать с разных страниц и так чтоб они не перепутались? Или это без разницы в каком порядке их брать? А тогда как их вставлять в новый сайт чтобы товар их нужнного раздела был в нужнм разделе . Делать провеку по названию раздела в файлике а потом вставлять товар и скачивать картинку что по ссылке для этого раздела из файлика?


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 05 Mar 2017, 00:25
Сообщение #4

laughed as one fey
Сообщений: 12 166
Спасибо сказали: 20581 раз




Как бы, тебе виднее.

Без конкретики я не могу ничего сказать по тому, как его лучше обносить; вставка - и вовсе отдельная задача, я с VirtualMart 3, чем бы оно не было, не работал.
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 05 Mar 2017, 03:58 (Сообщение отредактировал t800 - 03 Apr 2017, 00:01)
Сообщение #5

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Так ну я нагулил какой-то скрип который вроде бы умеет парсить товары из оzоn и яндек-маркет в VirtualMart я его поставил и запустил и вроде что-то делает правда скрипту 5 лет так что наверное поэтому он ничего с оzона спарсить не может, но оно мне вроде и надо мне же надо переделать чтоб он парсил с того сайта с которо мне сказали товары взять.

Прото я посмотрел тот его модуль которы вроде для оzоn

Вот его код:

Код
<?php
    @unlink('stop.txt');
    ob_end_clean();
    require_once("config.php");
    mysql_connect($host,$login,$password);
    mysql_selectdb($database);

    #$mainstop = true;

        require_once("includes.php");

        echo "<b>".$_['menu']." OZON</b><br /><br />";

        $mass=$_GET['url'];
        
        $parse = new ozonparse();
        $parse->sleep = $_GET['sleep'];
        $parse->proxy = $_GET['proxy'];
        $parse->key = $_GET['key'];
        $parse->noimg = $_GET['noimg'];
        $parse->ceil = $_GET['ceil'];
        $parse->_ = $_;

    if(!empty($_GET['file'])) {
        $file = file_get_contents("files/".$_GET['file']);
        $strs = explode("\n",$file);
        foreach($strs as $str) {
            if(!empty($str)) {
                $_strs[] = strtolower(trim($str));
            }
        }
        
        $parse->strs = $_strs;

    }

foreach ($mass as $url)
{
$url = str_replace("%%","&",$url);
$parse->parse_list($url,$_GET['num']);
}
        



    # require_once("footer.php");
?>


И что-то не вижу а где тут назначаются поля которы надо парсить

Посмотрел код модуля который для яндекс а он почти и не отличается.


Код
<?php
    require_once("config.php");
    @unlink('stop.txt');
    mysql_connect($host,$login,$password);
    mysql_selectdb($database);
    require_once("includes.php");
    
$cou['213']='Москва';
$cou['2']='Санкт-Петербург';
$cou['65']='Новосибирск';
$cou['54']='Екатеринбург';
$cou['51']='Самара';
$cou['66']='Омск';
$cou['43']='Казань';
$cou['56']='Челябинск';
$cou['39']='Ростов-на-Дону';
$cou['172']='Уфа';
$cou['38']='Волгоград';
$cou['50']='Пермь';
$cou['62']='Красноярск';
$cou['193']='Воронеж';
$cou['194']='Саратов';
$cou['35']='Краснодар';
$cou['240']='Тольятти';
$cou['143']='Киев';
$cou['157']='Минск';
$cou['162']='Алматы';

    echo "<b>".$_['menu']." Market.yandex.ru</b><br /><br />";
    $mass=$_GET['url'];
    $parse = new yamparse();
    $parse->sleep = $_GET['sleep'];
    $parse->proxy = $_GET['proxy'];
    $parse->key = $_GET['key'];
    $parse->noimg = $_GET['noimg'];
    $parse->countname=$cou[$_GET['yacout']];
    $parse->countnum=$_GET['yacout'];
    $parse->noimg = $_GET['noimg'];
    $parse->antikey = $Config['antigate'];
    $parse->ceil = $_GET['ceil'];
    $parse->_ = $_;
    if(!empty($_GET['file'])) {
        $file = file_get_contents("files/".$_GET['file']);
        $strs = explode("\n",$file);
        foreach($strs as $str) {
            if(!empty($str)) {
                $_strs[] = strtolower(trim($str));
            }
        }
        
        $parse->strs = $_strs;
    }

    foreach ($mass as $url)
{
$url = str_replace("%%","&",$url);
    if(substr_count($url,"guru.xml")) {
        $parse->parse_list($url,$_GET['num']);
    } else {
        $parse->parse_ext($url,$_GET['num']);    
    }
    }

?>


Я сейчас хочу попробовать свой модуль это скрипта сделать чтоб он с того сайта что мне сказали парсил.
Но не могу понять куда и как поля прописывать ну или хотябы где в этих модулях прописаны поля которые скрип берет с сайтов

А сам скрипт вот он: Прикрепленный файл  parser85.zip ( 660.34 килобайт ) Кол-во скачиваний: 3



--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 20 Mar 2017, 07:52
Сообщение #6

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Хммм... короче поставил этот скрип, настроил, скрипт работает но ничего не парсит даже с тех сайтов что у нем прописаны. Наверное слишком старый. Я посмотрел код этого старого скрипта и понял что проще будет написать новый чем разобраться почему не работает этот который старый.


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 20 Mar 2017, 12:19 (Сообщение отредактировал t800 - 03 Apr 2017, 00:38)
Сообщение #7

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Так я нашел на SF.net библиотеку PHP Simple HTML DOM Parser см. https://sourceforge.net/projects/simplehtmldom/

Скчал, положил на своем сайте в каталог /parser/library

Потом в каталоге parser создал файл test0.php c таким вот кодом

Код
<?php

echo '<html xml:lang="ru-ru" lang="ru-ru" >';
echo '<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head>';

//подгружаем библиотеку
require_once 'library/simplehtmldom.php';

//создаём новый объект
$html = new simple_html_dom();
//загружаем в него данные
$html = file_get_html('http://site.ru/');
//находим все ссылки на странице и...
if($html->innertext!='' and count($html->find('a'))) {
foreach($html->find('a') as $a){
//... что то с ними делаем
echo 'Ура! Я что-то спарсил..<br/>';
}
}
//освобождаем ресурсы
$html->clear();
unset($html);
?>


Запустил это файл через браузер у скрипт мне выдал вот что:

http://wiki.kvkozyrev.org/parser/test0.php


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 20 Mar 2017, 22:35 (Сообщение отредактировал t800 - 03 Apr 2017, 00:39)
Сообщение #8

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Так. Вот вроде из примера сделал скрипт который спарсил страницу с товаром

Код
<?php
echo '<html xml:lang="ru-ru" lang="ru-ru" >';
echo '<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head>';

//подгружаем библиотеку
require_once 'library/simplehtmldom.php';

//создаём новый объект
$html = new simple_html_dom();
//загружаем в него данные
$html = file_get_html('http://site.ru/catalog/ibp_akkumulyatory_i_stabilizatory/batarei_dlya_ibp/akkumulyatornye_batarei_dlya_ups_svc_12v_12_ach_razmer_v_mm_150_98_95/');

//находим путь категории  на странице ...

foreach($html->find('ul[class=breadcrumb-navigation]') as $element) echo $element->plaintext . '<br>';

echo '<br>';

// нахожим название

foreach($html->find('h1[class=header_grey]') as $element) echo $element->plaintext . '<br>';

echo '<br>';


// находим цену

foreach($html->find('div[class=item_current_price]') as $element) echo $element->plaintext . '<br>';

echo '<br>';


// находим картинку

foreach($html->find('a[class=fancy bx_bigimages_aligner]') as $element) echo '<img src="' . $element->href . '"><br>';

echo '<br>';

// находим  краткие характеристики

foreach($html->find('div[class=props_top]') as $element) echo $element->plaintext . '<br>';

echo '<br>';

// находим полные характеристики

foreach($html->find('div[class=left_prop]') as $element) echo $element->plaintext . '<br>';

echo '<br>';

foreach($html->find('div[class=left_value]') as $element) echo $element->plaintext . '<br>';


//освобождаем ресурсы
$html->clear();
unset($html);
?>


Вот что получилось http://wiki.kvkozyrev.org/parser/test6.php

А как теперь сделать чтобы он парсил не одну страницу а все страницы с товарами?
Про это в примерах я ничего не нашел.


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
t800
сообщение 02 Apr 2017, 23:55 (Сообщение отредактировал t800 - 03 Apr 2017, 11:39)
Сообщение #9

Разработчик
Сообщений: 534
Спасибо сказали: 221 раз




Фух вроде доделал скрипт. barb_metal.gif barb_metal.gif barb_metal.gif


Код
<?php
// Задаем заголовки чтобы по русски отображалось нормально
echo '<html xml:lang="ru-ru" lang="ru-ru" >';
echo '<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head>';
echo "Парсер от t800 :-) <br/><br/>";


set_time_limit(0); // это для того чтобы скрипт не отвалился через 30 секунд

//подгружаем библиотеку Simple HTML Dom
require_once 'library/simplehtmldom.php';

/* Теперь сам скрипт */


$i=1;

// Указваем количество страниц сколько  хочем спарсить
$n=5;

// Пишем дату сверху в файл куда пишем то что будем парсить
$time = date('Y:m:d:H:i');
$fp = fopen("parse.txt", "w"); // Открываем файл в режиме записи
$test = fwrite($fp,$time . "\r\n");
fclose($fp); //Закрытие файла

// Указываем адрес карты сайта (файла sitemap.xml) откуда берем ссылки страниц которые надо парсить

$sitemap = "http://site.ru/sitemap.xml";

// загружаем файл sitemap

$xml = simplexml_load_file($sitemap);

// Извлекаем ссылки из файла sitemap.xml

foreach ($xml->url as $url_list) {
    $url = $url_list->loc;

// вызываем нашу функцию parse() с указанием url страницы которую надо спарсить

    parse($url);

// Выводим инфу о загрузке
        echo " ***  Загружено: ".$i." из ".$n." страниц *** \r\n ";
        echo "<br>";
        echo str_pad('',4096)."\n";
        echo str_pad('',4096)."\n";
        flush();
// Тут проверка условия  на то сколько спрарсили страниц и выход из скрипта если уже спарсили сколько задано
        if($i++>=$n){
                echo " *** Готово! *** ";
                exit;
                }
}

// Здесь парсим страницу с url  нашей фукцией  parse()
// А это код нашей функция parse()

function parse($url)
{

$data = @file_get_contents($url); // собачка нужна в если сервер нам вернул 404, это вызовет Warning:, поэтому экранируем ошибки
if(trim($data)=='')return false; // бывает что сайт недоступен, тогда страницy не грузим а выходим из функции

//создаём новый объект
$html = new simple_html_dom();
//загружаем в него данные
$html = @file_get_html($url); // собачка нужна в если сервер нам вернул 404, это вызовет Warning:, поэтому экранируем ошибки

//проверяем что спарсили страничу с товаром (проверку делаем по цене) если цены нету то выходим из функции

$ret = $html->find('div[class=item_current_price]', 0);
if ($ret==null) return false;

//находим путь категории  на странице ...

foreach($html->find('ul[class=breadcrumb-navigation]') as $ul)
{
        foreach($ul->find('li') as $li)
        {
                foreach($li->find('a') as $a)
                {
                echo $a->plaintext . '/';
                $catalog = $a->plaintext . '/';
                $fp = fopen("parse.txt", "a"); // Открываем файл в режиме дописывания
                $test = fwrite($fp, $catalog ); // Запись в файл
                fclose($fp); //Закрытие файла
                }

       }
}


//echo '<br/>';

$fp = fopen("parse.txt", "a"); // Открываем файл в режиме дописывания

// находим название

foreach($html->find('h1[class=header_grey]') as $element) echo $element->plaintext;

//echo '<br>';

$test = fwrite($fp, $element->plaintext ); // Запись в файл
if ($test) echo '';
else echo 'Ошибка при записи в файл.';


// находим цену

foreach($html->find('div[class=item_current_price]') as $element) echo '';

$test = fwrite($fp, $element->plaintext ); // Запись в файл

if ($test) echo '';
else echo 'Ошибка при записи в файл.';


// находим картинку

foreach($html->find('a[class=fancy bx_bigimages_aligner]') as $element) echo '';

$url_img = "http://site.ru/" . $element->href;

// извелкаем имя файла картинки из url картинки
$file_name= substr($url_img, strrpos($url_img,"/")+1, strlen($url_img)-strrpos($url_img,"/"));  //Retrive file name from url

// задаем папку куда картинку сохранять
$img_path = "./images/".$file_name;

$test = fwrite($fp, $img_path ); // Запись в файл
if ($test) echo '';
else echo 'Ошибка при записи в файл.';

//  Закачиваем и сохраняем изображение

grab_image($url_img,$img_path);

// находим  краткие характеристики

foreach($html->find('div[class=props_top]') as $element) $test = fwrite($fp, $element); // Запись в файл

// находим полные характеристики

foreach($html->find('div[class=left_prop]') as $element)  $test = fwrite($fp, $element); // Запись в файл

foreach($html->find('div[class=left_value]') as $element)  $test = fwrite($fp, $element); // Запись в файл


// Записываем концы строк

$test = fwrite($fp, "\r\n" );
fclose($fp); //Закрытие файла

//в конце освобождаем ресурсы (не знаю зачем это надо, но говорят, что надо, иначе скрипт может зависнуть)
$html->clear();
unset($html);

}

// Это функция grub_image() че картинки скачивает сurl-ом  и сохраняет  (взята из комментариев на Stack Overflow)
// ЗЫ  сurl-ом потому что curl-ом быстрее скачивается

function grab_image($url,$saveto){
    $ch = curl_init ($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
    $raw=curl_exec($ch);
    curl_close ($ch);
    if(file_exists($saveto)){
        unlink($saveto);
    }
    $fp = fopen($saveto,'x');
    fwrite($fp, $raw);
    fclose($fp);
}

?>


Скрипт работает вот так:

http://wiki.kvkozyrev.org/parser/parser7.php


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 29 March 2024 - 08:45
Copyright by Алексей Крючков
Strategy Gamez by GrayMage
Programming by Degtyarev Dmitry
  Яндекс.Метрика