Парсинг данных
«Лошадью ходи, лошадью!»
Однажды по пути в командировку мне на глаза попалась свежая chess-news: во время девятой, зимней, недавно завершившейся, партии за звание ЧМ по шахматам среди мужчин 2021г. наш «декабрист» допустил грубейшую ошибку (на уровне «любителя»), повлиявшую и на окончательный итог турнира не в его пользу. Поискав в сети саму партию в чистом виде для импорта/анализа в шахматном движке на своём Android — столкнулся с проблемой: всякие, разные, шахматные сайты/базы требовали регистрацию/авторизацию что бы поработать с данными. Например, на одном таком, русскоязычном, шахматном сайте партия отображалась, но без аккаунта — скачать её было «невозможно». Расшарив ссылку на 9-партию, её все еще «невозможно» было скопипастить подручными средствами для анализа, самому же «играть в шахматы, угодя в цейтнот», против сайтов по их правилам я не спешил.
Код:
$ curl https://share.chessbase.com/SharedGames/game/?p=GGcui1RiwlsMXUUn49qJYW2loW1DrYRbproL+VX5mtFrtma1XhYxiFD4U+vvB+7P | grep "WCh 2021" -A 12 #чекаю ссылку с помощью curl, ищу данные партии, вывожу 12 строк (охват партии)Результат — готовая партия для импорта/анализа:
Загружаю её в open source Android приложение droidfish и включаю анализ.
Погибельно-оборонительный за белых пассивный 27 ход: «пешка c5» вместо контратаки «конь с5/пешка f3» соответствует проигрышу лёгкой фигуры за белых, движок всё видит и отображает преимущество за чёрных в 3 единицы (1 = пешка, 3 = конь/слон. При прочих равных условиях МС должен обыграть гроссмейстера с преимуществом 1-й пешки в 9 из 10 случаев).
И забавная реакция чемпиона мира, против которого так «дерзко» было сыграно:
К слову, в Termux имеется возможность играть в шахматы прямо в CLI. Пакет для установки «gnuchess».
Код:
$ pkg install gnuchess
$ gnuchessТяжёлая боевая ничья на 45 ходу в ходе троекратного повторения позиции.
Gnuchess не единственная логическая cli-игра в Termux, под гейм-пакеты выделен целый репозиторий.
Музыкальный пауза
Являясь поклонником литературного аудио сериала Этногенез (ИМХО, одни из лучших аудиокниг в проекте — цикл про хакеров [1, 2]) намеревался получить всю коллекцию этногенез-музыки, а потом ещё и слушать её прямо в CLI. Сами саундтреки бесплатные и свободно доступны на официальном сайте для скачивания в разделе музыка.
82 музыкальных трека, из которых некоторые просто
Карманный CLI спешит на помощь...
Чтобы проверить с чем именно придется иметь дело, сurl-ом и grep-ом проверяю web-страницу проекта Этногенеза. Разметка страницы простая, набрасываю рабочий bash-код в одну строку для скачивания всех аудиотреков за один присест. Жизнь движение, ставлю «музыкальный поток» на автоскачивание и ухожу на тренировку.
Код:
#Создаю общедоступный каталог «этногенез», в который собираюсь загрузить все аудиотреки
$ mkdir storage/shared/Download/этногенез$ cd storage/shared/Download/этногенезCurl-ом получаю html-страницы, grep-ом ищу все отношения к «mp3»
$ curl http://www.etnogenez.ru/music/ | grep '<span><a href="/paid-audio/0/pgg/episode'Исходя из проанализированных данных полный код на скачку музыки следующий:
Bash:
mkdir storage/shared/Download/этногенез
cd storage/shared/Download/этногенез
curl http://www.etnogenez.ru/music/ | grep '<span><a href="/paid-audio/0/pgg/episode' | awk '{print $2}' | sed 's/href="/http:\/\/www.etnogenez.ru/' | sed s/\"//g | wget -i -
# а так получить общий размер всех аудиотреков перед загрузкой = 849.09 Мб
curl http://www.etnogenez.ru/music/ | grep '<span><a href="/paid-audio/0/pgg/episode' | awk '{print $5}' | sed s/~//g | awk 'length( $0 ) < 9 {sum += $0} END {print sum}'
Описание bash-кода.
Curl-ом получаю страницу; grep-ом ищу все отношения к «.mp3»; вижу, что все нужные данные по разделителю «пробел» находятся во втором «столбце», использую awk забирая 2-й столбец; с помощью sed восстанавливаю валидный префикс url-ов всех mp3-треков и отбрасываю кавычки; готовые url(s) саундтреков поочередно отправляются на вход утилите для скачивания wget.
Пошёл процесс скачивания всех 82 аудиотреков.
Однако, если пользователь не так причудлив чтобы искусно владеть bash-оболочкой, а может всё с точностью наоборот, то задачу с извлечением url(s)/mp3-треков со страницы можно повторить, например, на Python.
Код:
$ pip install beautifulsoup4 html5lib#создаем файл: «parsing_mp3.py»
$ nano parsing_mp3.py#Наполняем:
Python:
import requests
from bs4 import BeautifulSoup
r = requests.get("http://www.etnogenez.ru/music/").text
soup = BeautifulSoup(r, 'html.parser')
## Парсинг url(s) аудиотреков
for link in soup.find_all(class_="play ga_track"):
if ".mp3" in link.get('href'):
print(f"http://www.etnogenez.ru/{link.get('href')}")
## Предварительный размер аудиотреков
sum_ = 0
for i in soup.find_all("div", class_="inner_content episode_size"):
try:
sum_ += float(i.string.split()[0])
except:
pass
print(f"\n{sum_} Мб") #получаем общий размер всей будущей музыки
$ python parsing_mp3.py > url && wget -i url #с помощью python извлекаю с web-сайта все url(s) (относящиеся к mp3) и сохраняю в файл "url", с помощью wget закачиваю всё что указано в файле "url"Пошла скачка всех тех же 82 аудиотреков по порядку, а в случае какой-либо ошибки/обрыва линии всегда можно докачать прерванное без излишнего кода.
Кроме того, с помощью wget (в случаях отсутствия ограничений) можно, например, выкачать весь сайт; отдельный web-каталог или спарсить все изображения, чем не может похвастать какое-либо Android приложение.
Код:
$ wget -U="Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0" -r -k -p -E -nc url #выкачать ресурс$ wget -U="Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0" -r -l=1 -nd -nc -A jpeg,jpg,bmp,gif,png url #спарсить/выкачать все изображения, глубина рекурсии задается ключом -l=цифраАвтоматизация процесса:
бэкап, шифрование данных с последующей синхронизацией в облако по расписанию
Rclone & 7-zip & crontabбэкап, шифрование данных с последующей синхронизацией в облако по расписанию
Rclone
Данные, которые я постоянно выгружаю (вернее написать: данные которые автосинхронизируются) в облако со своего Android устройства — это зашифрованные бэкапы кэш/приложения.
Бэкап приложений и их данных по расписанию осуществляет приложение OandBackuPX/TB #требуется root
Остальная логика завязана на Termux.
Синхронизация/шифрование берёт на себя «rclone».
Автозапуск скрипта по расписанию осуществляется с помощью «cron» в Termux.
Установка и настройка rclone на примере Яндекс.Диска
Код:
$ pkg install rclone
$ rclone configНастройка rclone простая: выбор в стиле POSIX:: [y/n/enter/digit] ответив на вопросы (выбирать все действия рекомендую значениями по умолчанию).
Цифрами выбрать Yandex Disk (это может быть любая другая цифра в любой/обновленной версии ПО, например сегодня это цифра - 32). Откроется браузер. Ввести данные авторизации яндекс-аккаунта и вернуться в терминал, где автоподставится ключ. Облако настроено и готово к синхронизации в обе стороны, но такое положение вещей нас не устраивает, нам нужно защищать свои данные в любом случае (примечание — если пользователю не нужно шифровать данные, для последующей выгрузки на диск, то Я.Диск на этом шаге уже настроен и готов к работе).
Чтобы создать отдельный зашифрованный каталог в облаке, необходимо донастроить созданный ранее контейнер: обеспечить шифрование/дешифрование данных на лету.
Код:
$ rclone config #--> n --> вводим имя (сопоставление шифрованного каталога), если у меня ранее контейнер назывался «yad», этот я назову: yenc (первая буква облака, суффикс от сокращения «encrypt», стоить иметь ввиду на будущее, что короткие имена удобней использовать в этой утилите). Выбрать «Encrypt/Decrypt a remote» --> 10, далее ввести имя и шифрованный каталог (имя до двоеточия обязательно должно = имени создаваемого ранее контейнера: yad) yad:crypt выбрать режим шифрования, их 3 (в зависимости от работы в параноидальных условиях).1. Encrypt the filenames see the docs for the details."standard"
2. Very simple filename obfuscation.
"obfuscate"
3. Don't encrypt the file names. Adds a ".bin" extension only.
"off"
Использую 3-й вариант, который добавляет к шифрованным файлам лишь рсаширение «.bin» (остальные варианты обфусцируют имена файлов).
Далее, directory_name_encryption --> «2» (false), далее Password or pass phrase for encryption --> «y» (напечатать пароль, он не будет отображаться в CLI — это не баг, а стандартная защита), далее No leave this optional password blank --> «n», далее Edit advanced config? --> «n». После чего увидите свою конфигурацию (подтвердите её нажав «y»):
[yenc]remote = yad:crypt
filename_encryption = off
directory_name_encryption = false
password = *** ENCRYPTED ***
На сколько «сложным» бы не казался rclone его конфиг настройки простой, в затруднительном положении (выбирать все пункты по «default») в крайне затруднительном — RTFM.
Вот пара команд, которые нам потребуются «sync» и «copy».
Обратите внимание, чтобы получить зашифрованные данные с Я.Диска и расшифровать, их нужно указывать просто как «yenc:» (а не «
$ rclone copy yenc: ~home/test #скопирует/расшифрует все данные с облака в каталог test (если в папке «test» имелись какие-либо сторонние данные, с ними ничего не произойдет).$ rclone sync yenc: ~home/test #аналогично, но уничтожит все сторонние данные в папке «test» (то есть полная синхронизация каталогов). Как всё просто. Да, так просто потерять всё. Пользователю необходимо соблюдать осторожность и внимательность, чтобы случайно не уничтожить сторонние данные. Например, ошибочный ввод:$ rclone sync yenc: ~home/ #уничтожит все пользовательские данные Termux, синхронизировав зашифрованный «crypt» каталог в облаке c «home» на гаджете нерадивого пользователя.Синхронизация, но в обратную сторону (гаджет --> облако):
$ rclone sunc источник :приемник/каталог #полная синхронизация$ rclone copy источник :приемник/каталог #синхронизация только выбранных данныхСуществуют векторы атак, при которых пользовательская цитадель может не устоять (проблема хранения облачного пароля в открытом виде в конфигурации rclone). Плюсом rclone является то, что он легко настраивается для работы в параноидальных обстоятельствах (зашифровав конфиг/открытый пароль, но потребуется вводить каждый раз пароль разблокировки при синхронизации данных). Из минусов, бэкап-данные дублируются перед шифрованием в облако, излишне нагружая дисковое пространство на устройстве пользователя.
В rclone имеется второстепенно-полезная hash-функция, которая умеет проверять рекурсивно заданный хэш у файлов во всех подкаталагах без «| трубы» и циклов (алогичная утилита hashdeep).
Скриншот Rclone --> Я.Диск.
7-zip
Если пользователь не желает шифровать данные в облаке с помощью rclone, например, если он находится в обстоятельствах, где нет возможности быстро развернуть rclone (а настроить/установить его нет времени), а данные нужно получить в расшифрованном виде как можно скорее, то на помощь приходит криптостойкий/кроссплатформенный архиватор «7-zip».
Код:
$ pkg install p7zip
$ cd storage/shared/Download
$ 7z u test.7z -pCodeby -mx9 'test' #ключ «u» сообщает, что в архив добавлять/создавать только новые/обновлённые файлы; пароль «Codeby» (шифрование криптостойкое, т.е хэш из разряда медленных, придерживаясь парольной доктрины хэш не растрескать); «mx9» максимальное сжатие; архивирование каталога «test». Эта команда удобна, если пользователь настроил автобэкап архива «test.7z» в облако.В ином случае (ручной бэкап архивов в облако).
Код:
$ 7z u test.7z -pCodeby -mx9 'test' && mv 'test.7z' $(date +"%d-%m-%Y_%Hч_%Mм")_android.7z #разница в том, что архив после сжатия будет переименован с новым дата-суффиксом: «13-02-2022_10ч_25м_android.7z». Из плюсов, наглядно видно по имени файла: когда был сделан/обновлён бэкап. Из минусов, с таким именем возникнут сложности с автобэкапом; такие архивы множатся (вместо быстрой дозаписи одного единственного архива создаются новые копии).Автовыполнение скриптов по расписанию
В Termux нет полноценной системы инициализации, но кое-что и кое-как работает и позволяет запускать скрипты на автомате:
- A) при автозагрузке гаджета;
- Б) либо запускать скрипты строго по расписанию, даже когда Termux не в трее.
Код:
$ pkg install cronie termux-services# ребут Termux
$ sv-enable crond #достаточно этот шаг сделать один раз и пользователь в деле$ crontab -e #настроить выполнение скриптов по расписанию по классике. Например, в исполняемом "скрипт.sh" первой строкой достаточно указать сокращенный путь: "#!/bin/bash" и не забывайте про раздачу прав: "chmod +x скрипт.sh"# быстрая проверка, работает ли "демон"
$ pidof crondПользователям с агрессивным энергосбережением стоит добавить все приложения Termux в исключение: «ограничения работы в фоновом режиме» в настройках своего Android.
Быстрый check автоматизации процесса
Код:
$ nano -$ срипт.sh#Наполнение скрипта
Bash:
#!bin/bash
mkdir storage/downloads/Codeby #создать пустой каталог в общедоступном месте
$ chmod + x срипт.sh #разрешаем выполнение скрипта$ crontab -e #создаём задание: каждую минуту автоматически создавать папку «Сodeby» в общедоступном каталоге «Downloads»*/1 * * * * bash /data/data/com.termux/files/home/скрипт.sh#«ctrl + o» сохранить; «ctrl + x» выход из nano; «ctrl + d выход из Termux»
Любым файловым менеджером проверяем общедоступный каталог «Downloads» и ищем папку «Codeby», удаляем её, но в течение минуты она снова появится, что сигнализирует о том, что скрипт работает на автомате, а значит можно приступать к написанию сценариев реальных задач.
Если пользователь не скачивал termux-boot, если у пользователя агрессивное энергосбережение, то в шторке Android/Termux есть функция «wakelock» (пытаться запрещать переходить гаджету в глубокий сон).
Бэкап Termux
В лучшем случае будет обидно установить и настроить Termux/пакеты под себя, но при развёртывании копи на другом устройстве и/или при любом инциденте потерпеть фиаско.
Проверка сколько места занимает настроенная Termux-среда.
Код:
$ cd ../../ && du -sh #подняться на два каталога выше и измерить пользовательские и системные пакеты Termux>>>4.1G
$ pkg list-install | wc -l #количество установленных пакетов>>> 307
Если у пользователя отсутствуют root-права, то авто/бэкап всей среды делается по мануалу.
Продолжение:
Часть 1-я
Часть 3-я
Часть 4-я
Часть 5-я
Последнее редактирование: