PHP: Использование CURL с сертифкатом

Задача: Некий удаленный ресурс проверяет сертификат пользователя, при попытке получить с него данные. В наличии только стандартные сертификаты выданные LetEncrypt.

Решение:

Сертификаты необходимо сконвертировать. В наличии:

  • sert.crt — сертификат домена в PEM формате
  • sert.key — приватный ключ PEM формате

Конвертируем используя промежуточную конвертацию в формат p12:

openssl pkcs12 -export -in sert.crt -inkey sert.key -out sert.p12
openssl pkcs12 -in sert.p12 -nodes -out result.pem

По итогу получили файл result.pem. Далее его и будем использовать при работе с curl:

$ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, "https://некий ресурс");    
                curl_setopt($ch, CURLOPT_SSLCERT, WUO_ROOT."result.pem" );
                curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM");
                curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
                curl_setopt($ch, CURLOPT_POST, True);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                $post=http_build_query($post, '', '&');
                curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
                curl_setopt($ch, CURLOPT_VERBOSE, true);
                $result = curl_exec($ch);
                curl_close($ch);   

1c: сохранение настроек формы внешней обработки

Задача: при открытии внешней обработки, восстанавливать значения на форме которые были при предыдущем запуске обработки.

Решение: на события ПриОткрытииНаСервере и при ПриЗакрытииНаСервере навсеми обработчики:

&НаСервере
Процедура СохранитьНастройкиНаСервере(КлючОбъекта, КлючНастроек, Пользователь = Неопределено)
    Настройки = Новый Структура;
    Для Каждого Элем ИЗ Элементы Цикл
        Если ТипЗнч(Элем) = Тип("ПолеФормы") Тогда
            Если Объект.Свойство(Элем.Имя) Тогда 
                Настройки.Вставить(Элем.Имя, Объект[Элем.Имя]);
            Иначе
                Настройки.Вставить(Элем.Имя, ЭтаФорма[Элем.Имя]);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;    
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта,  КлючНастроек, Настройки,, Пользователь);
КонецПроцедуры

&НаСервере
Процедура ВосстановитьНастройкиНаСервере(КлючОбъекта, КлючНастроек, Пользователь = Неопределено)   
    СтруктураНастроек = Неопределено;
    Попытка
        СтруктураНастроек = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта,КлючНастроек, ,Пользователь);
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;    
    Если СтруктураНастроек <> Неопределено Тогда
        Для Каждого Настройка Из СтруктураНастроек Цикл
            Если Объект.Свойство(Настройка.Ключ) Тогда 
                Объект[Настройка.Ключ] = Настройка.Значение;
            Иначе
                ЭтаФорма[Настройка.Ключ] = Настройка.Значение;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура УдалитьНастройкиНаСервере(КлючОбъекта, КлючНастроек, Пользователь = Неопределено)
    ХранилищеОбщихНастроек.Удалить(КлючОбъекта, КлючНастроек, Пользователь);
    Сообщить("Настройки " + КлючОбъекта + " для " + Пользователь + " удалены"); 
КонецПроцедуры

&НаСервере
Процедура ПриЗакрытииНаСервере()
	СохранитьНастройкиНаСервере("СохранениеНастроекПользователяФорма", "ВсеНастройки", ПользователиИнформационнойБазы.ТекущийПользователь());
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	ПриЗакрытииНаСервере();
КонецПроцедуры

&НаСервере
Процедура ПриОткрытииНаСервере()
   ВосстановитьНастройкиНаСервере("СохранениеНастроекПользователяФорма", "ВсеНастройки", ПользователиИнформационнойБазы.ТекущийПользователь());
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ПриОткрытииНаСервере();
КонецПроцедуры

Xpath — поиск текста и части текста на странице

Поиск точного совпадения:

//div[@data-ng-if='!filter.query']/span[text()='20 из ']

Поиск по части текста:

//div[@data-ng-if='!filter.query']/span[contains(text(), '20')]

парсер ГосУслуг

Задача: выкачать файлы уведомлений от ФССП приходящие для организации.

Почему нет штатного API для получения уведомлений на Госуслугах, вопрос интересный. В результате каждая организация которая в большом объеме работает со службой судебных приставов изобретает свой инструмент для автоматизации получения уведомлений. И я сей чаши не избежал 😉

Решение: напишем парсер на node.js с использование Selenium 2

// Начальные установки..
// количество выгружаемых уведомлений
cnt_uv=100;
// логин для входа в госуслуги
login="+094802к934к"
// пароль для входа 
pass="уамцумцук ";
// путь для сохранения файлов
save_path="c:\\tmp";
// полное название организации
full_name="ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ «РОГА И КОПЫТА»";

var webdriver = require('selenium-webdriver');

const {Builder, By, Key, until} = require('selenium-webdriver');
(async function example() {

    var chrome = require("selenium-webdriver/chrome");
    var chromeOptions = new chrome.Options();
    chromeOptions.addArguments("test-type");
//    chromeOptions.addArguments("start-maximized");
//    chromeOptions.addArguments("--js-flags=--expose-gc");
//    chromeOptions.addArguments("--enable-precise-memory-info");
  //  chromeOptions.addArguments("--disable-popup-blocking");
 //   chromeOptions.addArguments("--disable-default-apps");
//    chromeOptions.addArguments("--disable-infobars");
    //chromeOptions.addArguments("--user-data-dir=C:\\tmp");
    chromeOptions.addArguments("safebrowsing-disable-download-protection");

    let driver = await new Builder().forBrowser('chrome').setChromeOptions(chromeOptions).build();
    driver.setDownloadPath(save_path);
  try {            
    console.log("-загружаем страницу авторизации");
    await driver.get('https://lk.gosuslugi.ru');
    console.log("--ok");
    console.log("-ждем отрисовки");   
    elm= await driver.wait(until.elementLocated(By.xpath(".//button[@id='loginByPwdButton']"), 30000));            
    console.log("--ok");
    console.log("-вставляем логин пароль и кликаем Enter");   
    await driver.findElement(By.id('login')).sendKeys(login,Key.TAB,pass,Key.RETURN);
    console.log("--ok");
    console.log("--ok");
    console.log("-ищем full_name и кликаем по ней");   
         elm= await driver.wait(until.elementLocated(By.xpath(".//div[@title='"+full_name+"']"), 30000));        
         await driver.executeScript("arguments[0].click();", elm);        
    console.log("--ok");
    console.log("-ждем пока не будет перехода на нужную страницу");           
    ccurl="";
    while (ccurl!=="https://lk.gosuslugi.ru/info"){
        await driver.getCurrentUrl().then(
                url => {console.log('current url: "' + url + '"');ccurl=url;}
        );
        await driver.sleep(100);
    };
    //elm= await driver.wait(until.elementLocated(By.xpath(".//a[@data-ng-href='https://esia.gosuslugi.ru/profile/org/org.xhtml?orgOid=1087125902']"), 30000));            
    //await driver.sleep(2000) 
    console.log("--ok");
    console.log("-идём на страницу уведомлений");   
    for (var i = 1; i < cnt_uv; i++) {
        await driver.get("https://lk.gosuslugi.ru/notifications")
        //console.log("--ok");        
        //console.log("-загружаю "+cnt_uv+" сообщений");           
        await GetNotifications(driver,cnt_uv);         
        //console.log("--ok");        
        //console.log("-кликаю по первому уведомлению и сохраняю файлы");           
        await UvedOpen(i);
        console.log("--ok сохранен файл " +i+" из "+cnt_uv);            
    };
            
    async function UvedOpen(n){
        fl=await driver.findElements(By.xpath(".//a[@data-ng-click='openDetails(notification)' and @class='grid-wrap__col-lg-1 grid-wrap__col-md-1 grid-wrap__col-sm-1 grid-wrap__col-md-land-1 pad-top-24 pad-bottom-24']"))        
         await driver.executeScript("arguments[0].scrollIntoView()", fl[n]);
         await driver.executeScript("arguments[0].click();", fl[n]);                
         elm= await driver.wait(until.elementLocated(By.linkText('Сохранить'), 30000));        
         //await driver.executeScript("arguments[0].click();", elm);
         elm=await driver.findElements(By.linkText('Сохранить'));
         elm[0].click();
         elm[1].click();  
         await driver.sleep(1000);
    }
    async function GetNotifications(driver,cnt){ 
        for (var i = 0; i < cnt/10; i++) {
            pp=((i+1)*10);
            //console.log("----ждем появления кнопки 'Показать еще ("+pp+")'");        
             elm= await driver.wait(until.elementLocated(By.linkText('Показать еще'), 30000));        
            //console.log("----ok");
            //console.log("-нажимаю кнопку 'Показать еще'");       
               await driver.executeScript("arguments[0].scrollIntoView()", elm);
               await driver.executeScript("arguments[0].click();", elm);
            //console.log("--ok");
        };     
        //console.log("-ждем полной прогрузки страницы");       
        fl=  await driver.findElements(By.xpath(".//a[@data-ng-click='openDetails(notification)' and @class='grid-wrap__col-lg-1 grid-wrap__col-md-1 grid-wrap__col-sm-1 grid-wrap__col-md-land-1 pad-top-24 pad-bottom-24']"))        
        while (fl.length<cnt_uv){
            fl=  await driver.findElements(By.xpath(".//a[@data-ng-click='openDetails(notification)' and @class='grid-wrap__col-lg-1 grid-wrap__col-md-1 grid-wrap__col-sm-1 grid-wrap__col-md-land-1 pad-top-24 pad-bottom-24']"))        
             await driver.sleep(100);
          //  console.log("---ждем..");
        };      
    };    
    
  } finally {    
    console.log("-вот и всё ребята..");
    await driver.quit();
  }
})();

1С: Поиск пользователя по имени пользователя информационной базы.

Задача: найти пользователя из справочника «Пользователи» если известно только имя пользователя информационной базы.

Решение: воспользуемся стандартной функцией БСП ПользователиИнформационнойБазы:

			ПИБ=ПользователиИнформационнойБазы.НайтиПоИмени("Вася ВГ);
			Исполнитель=справочники.Пользователи.НайтиПоРеквизиту("ИдентификаторПользователяИБ",ПИБ.УникальныйИдентификатор);
1 86 87 88 89 90 310