Задача: Есть некая очень захламленная сторонними элементами страница в разметке html. Необходимо преобразовать находящуюся на ней таблица в массив данных.
Решение: сначала вычленим «грязное» содержимое таблицы между тегами <tbody></tbody>, затем преобразуем его в DOM документ, а далее уже распарсим его обходами и разложим элементы в массив.
Получилось что-то вроде:
//вычленяю таблицу
$t1=explode("<tbody>",$res);
$t2=explode("</tbody>",$t1[1]);
$tbody="<html><head><meta charset='UTF-8'></head><body><table><tbody>".$t2[0]."</tbody></table></body></html>";
$mass=[];
$dom = new domDocument('1.0', 'utf-8');
@$dom->loadHTML($tbody);
$tables= $dom->getElementsByTagName('table');
foreach ($tables as $table) {
$trs= $table->getElementsByTagName('tr');
foreach ($trs as $tr) {
$tds=$tr->getElementsByTagName('td');
$info=[];
foreach ($tds as $td) {
$info[]=$td->textContent;
};
$mass[]=$info;
}
}
В одном из проектов, скрипт парсит сайт на bitrix. С какого то момента, при установке параметров таблицы отдаваемой по ajax, стала выводиться ошибка «Request is not XHR». Быстрый гуглинг решения не дал. Стал кропотливо сравнивать заголовки которые отдаются запросом в браузере и заголовки который отдавал в скрипте. Отличие нашлось относительно быстро, страница на сайте добавляла дополнительный заголовок «Bx-ajax:true». В результате модифицировал скрипт следующим образом:
До недавнего времени (еще несколько лет назад) для хранения данных учётных записей в 1С единственной защитой было — показывать поле с паролем со «звездочками». Сам же пароль хранился в практически открытом виде в реквизитах формы. Ну.. возможно это и не безопасно.. Новая методика хранения чувствительных данных в 1С призвана эту безопасность увеличить. Работа с безопасным хранилищем в 1с, Поэтому в БСП были внедрены функции общего назначения «ПрочитатьДанныеИзБезопасногоХранилища» и «ЗаписатьДанныеВБезопасноеХранилище».
В чём разница между хранением в реквизитах и новой методикой:
Имея доступ к объекту метаданных, пользователь может прочитать содержимое реквизита с паролем, что невозможно при использовании безопасного хранилища. Для исключения случаев несанкционированного доступа к безопасному хранилищу получение и запись данных (паролей) возможна только в привилегированном режиме.
Данные в безопасном хранилище хранятся в закрытом виде и тем самым исключаются случаи непредумышленной «засветки» паролей.
Безопасное хранилище исключено из планов обмена, что предотвращает утечку паролей из информационной базы при обмене данными.
Задача: выгрузить табличную часть формы в файл формата XLSX. К сожалению на прямую это не сделать, но зато мы можем воспользоваться функционалом компонента ПостроительОтчета, который в свою очередь понимает на входе таблицу значений. В итоге нам остаётся лишь выгрузить табличную часть в таблицу значений, которую в свою оочередь скормить построителю отчетов. На выходе будет ТабличныйДокумент, который уже штатно может сохраняться в т.ч. и в формат xlsx. Код получается примерно такой::
&НаСервере
Функция ЭкспортВExcelНаСервере()
ТабДок = Новый ТабличныйДокумент;
Тз = Новый ТаблицаЗначений;
тз.Колонки.Добавить("Отделение");
тз.Колонки.Добавить("Подразделение");
тз.Колонки.Добавить("ЛС");
тз.Колонки.Добавить("КодСопоставления");
тз.Колонки.Добавить("ДатаРождения");
тз.Колонки.Добавить("МестоРождения");
тз.Колонки.Добавить("СерияПаспорта");
тз.Колонки.Добавить("НомерПаспорта");
тз.Колонки.Добавить("СерияНомерПаспорта");
тз.Колонки.Добавить("РезультатПроверки");
для каждого стр из объект.РезультатСопоставления цикл
нс=тз.Добавить();
нс.Отделение=стр.Отделение;
нс.Подразделение=стр.Подразделение;
нс.ЛС=стр.ЛС;
нс.КодСопоставления=стр.КодСопоставления;
нс.ДатаРождения=стр.ДатаРождения;
нс.МестоРождения=стр.МестоРождения;
нс.СерияПаспорта=стр.СерияПаспортаС;
нс.НомерПаспорта=стр.НомерПаспортаС;
нс.СерияНомерПаспорта=стр.СерияНомерПаспорта;
нс.РезультатПроверки=стр.РезультатПроверки;
конеццикла;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Тз);
Построитель.Выполнить();
Построитель.Вывести(ТабДок);
ИмяВременногоФайлаХар = ПолучитьИмяВременногоФайла(".xlsx");
ТабДок.Записать(ИмяВременногоФайлаХар,ТипФайлаТабличногоДокумента.XLSX);
сообщить(ИмяВременногоФайлаХар);
Двоичное=Новый ДвоичныеДанные(ИмяВременногоФайлаХар);
Адрес=ПоместитьВоВременноеХранилище(Двоичное,ЭтаФорма.УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
&НаКлиенте
Процедура ЭкспортВExcel(Команда)
Адрес=ЭкспортВExcelНаСервере();
Описание=Новый ОписаниеПередаваемогоФайла(ПолучитьИмяВременногоФайла(".xlsx"),Адрес);
МассивОписаний=Новый Массив;
МассивОписаний.Добавить(Описание);
ПолучитьФайлы(МассивОписаний,,,Ложь);
Для Каждого фф Из МассивОписаний Цикл
ЗапуститьПриложение(фф.Имя);
КонецЦикла;
КонецПроцедуры
Пользователь нажимает кнопку «Экспорт в эксель», на сервере формируется файл и передаётся на клиент. На клиенте он открывается приложением по умолчанию для данного формата файла. Код получился кросс платформенный, что в наше время очень актуально.
Всё началось неплохо (с)… А именно захотел я обновить apache на одном из серверов, Ubuntu на «наисвежайший». Сначала попытался собрать из исходных кодов, но как-то не срослось, а потому чуть погуглив, нашел что в репозитарии ondrej/apache2 всегда лежат уже собраные пакеты самой свежей версии. Казалось бы дело простое:
Но не тут то было..Получил ошибку «No module named ‘apt_pkg'»:
Traceback (most recent call last):
File "/usr/bin/add-apt-repository", line 5, in <module>
import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'
При попытке доустановить пакет через pip3… вышло сообщение, что пакета то такого и нет..
pip install apt_pkg
ERROR: Could not find a version that satisfies the requirement apt_pkg (from versions: none)
ERROR: No matching distribution found for apt_pkg
Долго гуглил почему так, выяснить так и не смог. Единственное что удалось выяснить, что если запускать pip3 для python3.10, то пакет ищется и устанавливается. Возможно дело в как-то криво установленном python3.11 В результате, пришлось перейти обратно на python3.10