Парсер веб-сайтов для 1С:Предприятие 8.3




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

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

<?php // Полная загрузка сервисных книжек, создан 2025-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

49 Comments

  1. bayce

    А для чего это нужно???

    Reply
  2. Elisy

    (1)

    А для чего это нужно???

    Цены загружать откуда-нибудь, например. Мониторить сайты конкурентов.

    Reply
  3. Kosmovski

    очень хорошо если бы выложыл ссылки на Elisy .Net Bridge 4.0.6. а то но их официальном сайте скачать нет возможности. А на форуме ссылки даже после регистрации не появляються, сорри появляються только после активации аккаунта.

    Reply
  4. Elisy

    (3) Kosmovski,

    выложу здесь — в комментариях для удобства. Страница на Инфостарте почему-то стала неактивной.

    Reply
  5. compreSSor

    когда пытаюсь загрузить *.dt — пишет — «Неверный формат файла для загрузки информационной базы» — это нормально ?

    Reply
  6. compreSSor

    прошу прощения — установил платформу 8.3 — всё загрузилось.

    просто в описании указано

    Платформа:

    1C: Предприятие 8.2

    1С: Предприятие 8.3


    Reply
  7. Elisy

    (5)

    Спасибо за замечание. Сейчас тяжело будет изменить свойства статьи, потому что при изменении статья уходит на модерацию, насколько знаю. Из-за этого статья будет недоступна.

    Reply
  8. compreSSor

    (7) и ещё где-то укажите, что при 1-м запуске необходимо указать каталог для темп-файлов

    Reply
  9. Elisy

    (8) Вы правы. Упустил из виду. При первом запуске необходимо указать каталог для временных файлов. Его можно указать через Сервис-Папка временных файлов в разделе Парсер. В каталог пишутся dll и полный протокол работы, чтобы выявлять возможные проблемы.

    Вот пример: «D:370-ПарсингTemp». В конце обратный слеш должен присутствовать.

    Reply
  10. sss999

    крутая штука )только не понятно как узнать например адреса фоток и реквизитов на сайте как прописать,где у вас там написано div//

    Reply
  11. Elisy

    (10)

    крутая штука )только не понятно как узнать например адреса фоток и реквизитов на сайте как прописать,где у вас там написано div//

    Я в хроме через контекстное меню выбирал Inspect Element, элемент открывался в дереве отладчика.

    Reply
  12. compreSSor

    блин… долго не заходил в конфу — сейчас пытаюсь запустить парсер — выдаёт ошибку

    {ОбщийМодуль.ПарсерКлиент.Модуль(5)}: Тип не определен (AddIn.ElisyNetBridge4)

    AddIn = New(«AddIn.ElisyNetBridge4»);

    Функция ПолучитьNet() Экспорт
    
    ПодключитьВнешнююКомпоненту(«Elisy.NetBridge4»);
    AddIn = New(«AddIn.ElisyNetBridge4»);
    Net = AddIn.GetNet();
    Net.ActivateByLicenseFile(«»);
    
    Возврат Net;
    КонецФункции
    

    Показать

    что могло пойти не так ? Elisy-Net-Bridge-SDK-4-0-6.zip — установлен.

    платформа 1С — 8.3.4.465

    Reply
  13. Elisy

    (12) compreSSor,

    Добрый день, попробуйте переустановить Elisy-Net-Bridge-SDK-4-0-6.zip под администратором.

    Судя по ошибке, ссылка на компонент не найдена в ветке реестра или ссылка из реестра ведет на несуществующий файл Elisy.NetBridge.dll

    Reply
  14. compreSSor

    (13) уже пробовал… даже полностью удалял и опять устанавливал.

    хотя теперь просто пишет — «Тип не определен (AddIn.ElisyNetBridge4)»

    Reply
  15. Elisy

    (14) compreSSor,

    Установлен у вас .Net Framework 4 ?

    Reply
  16. compreSSor

    установлен… 4.5.1

    Reply
  17. monsta

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

    Reply
  18. Elisy

    (17) monsta,

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

    Спасибо за статью, добавил ссылку на нее в своей статье. Думаю, что ваше описание будет всем полезно.

    Reply
  19. Elisy

    (16) compreSSor,

    Какая у вас стояла ОС, когда не запускался .Net Bridge ? Windows 8.1?

    Reply
  20. monsta

    Может замутим аналог import.io в 1С?

    Reply
  21. Elisy

    (20) monsta,

    Может замутим аналог import.io в 1С?

    Много можно чего сделать на основе парсера. Вот ребята сделали Продукт Сбор цен конкурентов 2.0

    http://www.richmedia.us/post/2015/03/11/odineskin-parser.aspx

    Reply
  22. compreSSor

    (19) нет… всегда была Windows 7 (x64)

    Reply
  23. monsta

    (21) занятная штука!

    Умела бы она вот так делать — цены бы не было!

    Import.io пользуется спросом как десктопное приложение, возможно и конфигурация могла бы быть коммерчески интересной.

    Reply
  24. stolya
    Reply
  25. Elisy

    (24) Насколько мне известно многие средства плохо работают с невалидными HTML, например, не хватает в середине одного закрывающего тэга.

    Есть еще детали, с которыми не понятно как справится родной компонент. Например, кодировка сайта может быть разная. Может быть даже так, что сервер возращает одну кодировку, а Head страницы содержит другую.

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

    Reply
  26. DieseL_d2

    Как можно добавить использование proxy?

    Используя С# это можно сделать следующим способом, но как это написать в 1с?

    ——————————————————————————————-

    //Extend the PageRequester class and override the method that creates the HttpWebRequest

    public class YourCustomPageRequester : PageRequester

    {

    protected override HttpWebRequest BuildRequestObject(Uri uri)

    {

    HttpWebRequest request = base.BuildRequestObject(uri);

    request.Proxy = new WebProxy(_config.ConfigurationExtensions[«MyProxy1»]);

    return request;

    }

    }

    //Load config from xml then add proxy values to the «ConfigurationExtensions» dictionary

    CrawlConfiguration crawlConfig = AbotConfigurationSectionHandler.LoadFromXml().Convert();

    crawlConfig.ConfigurationExtensions.Add(«MyProxy1», «http://myproxy1.com:8080»);

    //Create an instance of the crawler and pass in your configuration and custom impl for the IPageRequester

    PoliteWebCrawler crawler = new PoliteWebCrawler(crawlConfig, null, null, null, new YourCustomPageRequester(), null, null,null, null)

    //Crawl the site and the proxy should be used

    crawler.Crawl(new Uri(«http://somesite.com/»));

    ——————————————————————————————-

    Reply
  27. Elisy

    (27)

    Как можно добавить использование proxy?

    В обработке ЗагрузкаСтраниц в макете ИсходныйКод содержится код C#. Думаю, что в него нужно добавить наследованный класс

    public class YourCustomPageRequester : PageRequester
    {
    protected override HttpWebRequest BuildRequestObject(Uri uri)
    {
    HttpWebRequest request = base.BuildRequestObject(uri);
    request.Proxy = new WebProxy(«http://myproxy1.com:8080»);
    return request;
    }
    } 

    Показать

    подставив адрес прокси-сервера (нужно проверить параметр WebProxy, что он дейтсвительно строковый

    Далее в этом же макете поменять строку

    Crawler = new PoliteWebCrawler(crawlConfig, null, null, null, null, null, null, null, null);

    на

    Crawler = new PoliteWebCrawler(crawlConfig, null, null, null, new YourCustomPageRequester(), null, null,null, null)
    Reply
  28. DieseL_d2
    Reply
  29. Elisy

    (29) DieseL_d2,

    Как можно отладить эту конструкцию?

    Судя по ошибке, ругается на строку

    HttpWebRequest request = base.BuildRequestObject(uri); 

    ошибку можно попробовать исправить, заменив строку на

    var request = base.BuildRequestObject(uri); 

    или

    System.Net.HttpWebRequest request = base.BuildRequestObject(uri); 

    или добавив в конструкции using строку

    using System.Net;
    Reply
  30. DieseL_d2
    Reply
  31. Elisy

    (31) DieseL_d2,

    Случайно нашел ваш пост на форуме Abot. Там ответили, что конструктор YourCustomPageRequester содержит параметры и код нужно исправить на

    Crawler = new PoliteWebCrawler(crawlConfig, null, null, null, new YourCustomPageRequester(crawlConfig), null, null,null, null)
    Reply
  32. DieseL_d2

    Это приводит к увеличению ошибок:)

    c:UsersPavelAppDataLocalTempshd4vol5.0.cs(30,75) : error CS1729: Elisy.NetBridge.Crawler.YourCustomPageRequester не содержит конструктор, который принимает 1 аргументов

    c:UsersPavelAppDataLocalTempshd4vol5.0.cs(11,22) : error CS1729: Abot.Core.PageRequester не содержит конструктор, который принимает 0 аргументов

    Reply
  33. DieseL_d2

    Разобрался сам, в совете по добавлению прокси была куча синтаксических ошибок, нашел другой пример, отладил пару других мелких ошибок, код получился вот таким:

    Теперь возникает вопрос, как можно менять прокси во время работы по достижению определенного числа скачанных станиц.

    Перезапуск с новым прокси по сути даст тот же набор страниц(бот пробежит по тем же ссылкам). Запуск бота по последней скачанной странице тоже не совсем верен.

    Я правильно понимаю, что где-то внутри Adot формируется перечень url, по которым нужно пройтись? можно его как-то оттуда вытянуть, перед перезапуском?

    Reply
  34. Elisy

    (34) DieseL_d2,

    Думаю, это проще реализовать в классе YourCustomPageRequester

    Объявить в нем массив адресов прокси,

    private string[] _адресаПрокси = new string[3] {«212.82.126.32:80», «Proxy2», «Proxy3»};

    номер текущего прокси

    int _номерТекущегоАдресаПрокси = 0;

    номер страницы в текущем прокси

    int _номерСтраницы = 0;

    в методе protected override HttpWebRequest BuildRequestObject(Uri uri)

    обращаться к прокси по _адресаПрокси[_номерТекущегоАдресаПрокси % _адресаПрокси.Length]

    увеличивать счетчик _номерСтраницы++

    Если счетчик достигает предела страниц на 1 прокси, увеличивать на 1

    _номерТекущегоАдресаПрокси++

    Reply
  35. compreSSor

    вопрос для всех — как отпарсить » http://dwgroup.com.ua/Catalog.aspx?p=175 » на предмет «Артикул, Цена, Изображение» ?

    особенно интересует «Изображение»

    Reply
  36. Elisy

    (36) compreSSor,

    Думаю, что задача решается в несколько проходов

    На первом проходе через регулярные выражения атрибута onclick можно выйти на ID в ShowDescription(41423)

    ShowDescription определен в «http://dwgroup.com.ua/js/main.js?15» как

        Show_popup(‘divDescription’);
    $.get(‘GoodsNameDescription.aspx?m=’ + Math.random() + ‘&id=’ + id, function(data) {
    $(‘#divDescription’).html(data);
    });
    Show_popup(‘divDescription’);
    return false;

    Радует, что получение идет через get-запрос. Это значит, что доступны URL с описаниями

    «http://dwgroup.com.ua/GoodsNameDescription.aspx?m=1&id=41424»

    «http://dwgroup.com.ua/GoodsNameDescription.aspx?m=1&id=41423»

    Reply
  37. s_uu

    При запуске парсера выдает сообщение «Elisy .Net Bridge v4.0.6.0

    Evaluation NFR version / Ознакомительная NFR-версия

    Copyright © 2008-2015 Elisy Software Design

    E-mail: support@1csoftware.com; Web: http://www.1csoftware.com/dotnet/

    Use the main MAC-address to activate component / Используйте основной MAC-адрес для активации компонента

    The following MAC-addresses are available / Доступны следующие MAC-адреса :

    (Ppp)

    88532EC198AB (Wireless80211)

    88532EC198AA (Wireless80211)

    E8039A96B0DF (Ethernet)»

    И ничего не происходит! Как исправить?

    Reply
  38. Elisy

    (38) s_uu,

    Сообщение говорит о правильном начале работы компонента .Net Bridge. Почему ничего не происходит, нужно смотреть в отладчике. Возможно, виноваты настройки сети. По представленной вами информации сложно судить.

    Reply
  39. white-mount

    Два момента которые не осветил автор:

    1) На сайте разработчика читаем:

    2. Системные требования

    Операционная система (Операционная система (Архитектура x86): Windows 7/Vista SP1/XP SP3/2008/2003 SP2 ):

    Версия .Net-платформы: .Net framework 4.0



    Примечание: . Ограниченная поддержка 64-битных приложений (например, 64-разрядного сервера 1С:Предприятие) осуществляется через расширение COM+.

    2) Сведения которые требует продавец, указывают на привязку клиентской лицензии к конкретному железу. :

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

    — Фамилия Имя Отчество;

    — Адрес электронной почты (email);

    — MAC-адрес компьютера;

    Эти данные будут переданы продавцу для завершения сделки купли-продажи товара.

    Поддерживаю (38) s_uu , на скачанной с сайта, после довольно долгой регистрации, ознакомительной версии обработка выдаёт аналогичные сообщения.

    Дополнительно, Net framework 4.5 и выше не воспринимает.

    Стоит ли покупать продукт, который невозможно протестировать, и который намертво привязывается к одному пк, вопрос открытый.

    Reply
  40. Elisy
    1) На сайте разработчика читаем:

    Не понятен смысл комментария — компонент поддерживает х86, но ничто не мешает использовать под х64 через COM+.

    Поддерживаю (38) s_uu , на скачанной с сайта, после довольно долгой регистрации, ознакомительной версии обработка выдаёт аналогичные сообщения.

    Пользователь в (38) решил не исследовать дальше и не ответил на мой вопрос (39). Понятно, что ничего с этим поделать нельзя будет без дополнительной информации. На Инфостарте, кстати тоже можно скачать без долгой регистрации.

    Дополнительно, Net framework 4.5 и выше не воспринимает.

    Очень странно, так как установка .Net обычно несет с собой предыдущие версии также. И если вы увидели картинку в (38), значит инициализация .Net прошла, так как было обращение к MAC-адресам средствами .Net.

    Стоит ли покупать продукт, который невозможно протестировать, и который намертво привязывается к одному пк, вопрос открытый.

    Именно поэтому Elisy .Net Bridge поставляется бесплатно для ознакомительного доступа, чтобы можно было проверить работу до покупки. Парсер должен работать на незарегистрированном компоненте. Будет надоедать сообщение только.

    Reply
  41. zlakizla

    Добрый день!

    Подскажите, пожалуйста, несколько вопросов при использовании:

    1) Как парсить каталог по страницам? Например, есть УРЛ «https://au.ru/sport/sports_nutrition/» .На данной странице 50 товаров, я получаю наименование и цену товара. А вот, чтобы увидеть следующие товары, надо переходить по страницам. УРЛ следующей страницы «https://au.ru/sport/sports_nutrition/?page=2 (3, 4, 5 и так далее)». Как можно парсить эти страницы?

    2) Как сопоставить Полученные значения при анализе страниц? Например, получаю 2 значения (Наименование и Цена). В итоге получается таблица, в которой сначала идут строки с Наименованием, а потом строки с Ценой. Есть, конечно, колонка «Индекс», но по нему не всегда можно сопоставить. Например, у меня получилось, что я одно значение по Пути «//a[@class=»lotcard-name»]» не нашел и, соответственно, индексы сдвинулись на единицу, и уже не получается сопоставить какому Наименованию соответствует Цена.

    Reply
  42. Elisy

    (42) zlakizla,

    Шаг 1 — скачать нужные страницы. В справочнике Группы страницы попробуйте установить шаблон

    https://au.ru/sport/sports_nutrition/?page=*

    Скачайте страницы

    2. Индекс планировался для сопоставления. Если не получается через параметр a[@class=»lotcard-name»] загрузить все значения, нужно поэкспериментировать с другими значениями, чтобы возвращались все элементы

    Reply
  43. nicknick267-1

    (4) Я так понимаю, она платная, как ее можно приобрести?

    Reply
  44. nicknick267-1

    (41) Сергей здравствуйте.

    Как можно приобрести Elisy .Net Bridge?

    Reply
  45. Elisy

    (44) Компонент продается на этой странице:

    https://infostart.ru/public/20035/

    До покупки, пожалуйста, воспользуйтесь бесплатной демо-версией. Она имеет весь функционал, но выдает сообщение при первом обращении.

    Reply
  46. Elisy

    (45) Компонент продается на этой странице:

    https://infostart.ru/public/20035/

    До покупки, пожалуйста, воспользуйтесь бесплатной демо-версией. Она имеет весь функционал, но выдает сообщение при первом обращении.

    Reply
  47. deman_ru

    Не подскажите в чем может быть проблема, некоторые страницы загружаются не корректно, проблема с кодировкой, русские буквы получаются вида: Замок СЃ Рў-образной ручкой оптом РІ наличии РЅР

    Reply
  48. Elisy

    (48)

    Нужно смотреть заголовки этих страниц. 1. Может быть кодировка не Utf-8 2. Может быть включено сжатие данных. Я не проверял, как при сжатии себе может вести парсер.

    Можете дать пример ссылки?

    Reply
  49. deman_ru

    (49) Разобрался, нужно было в настройках указать кодировку страниц. Спасибо за ответ!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *