Extraire l'info du Web en ligne de commande đŸ‡«đŸ‡·

Avant mĂȘme de coder un lecteur RSS et de l’utiliser toute la journĂ©e, je cherchais un moyen efficace de connaĂźtre l’heure et le mouvement de la marĂ©e, et un flux RSS semblait une bonne idĂ©e.

Il me semble mĂȘme (pas vraiment sĂ»r) me souvenir d’une telle ressource, mais si elle a jamais existĂ©, elle est tombĂ©e maintenant de toute façon ; et pour cause : il n’est pas une mince affaire de servir potentiellement des centilliards de flux RSS, un par plage / port / cĂŽte.
Donc j’utilisais des sites Web. Trouver le navigateur, se tromper d’URL, ce genre de choses, mais je veux dire on est des programmeurs, on ne fait rien trois fois avant d’écrire un script pour le faire Ă  notre place.

Le truc est que le “grattage” (scraping) Web est gĂ©nĂ©ralement le cheval de bataille des grands frameworks, j’en sais quelque chose, Ă©tant l’auteur de Feedrat et Favrat, qui chassent, trouvent et signalent respectivement les flux RSS et les favicons dans les pages Web, mais avec Nodejs et une montagne de dĂ©pendances.

RĂ©cemment, j’ai remarquĂ© que j’utilisais le mĂȘme site depuis des mois, et qu’il Ă©tait vraiment stable. J’ai donc dĂ©cidĂ© de rechercher “web scraping from the shell” et j’ai trouvĂ© hxnormalize et hxselect ; Ces deux commandes sont disponibles dans le paquet html-xml-utils.

Avec ces deux commandes, nous pouvons

  • Lire du HTML (concrĂštement, disposer d’un objet reprĂ©sentant le DOM de la page, et non plus d’une simple chaine de caractĂšres.)
  • SĂ©lectionner n’importe quel Ă©lĂ©ment dans ce DOM

Nous n’avons donc besoin que d’un vĂ©hicule, d’un vaisseau pour nous transmettre la page Web, et avec ces deux commandes, faire quelque chose d’intĂ©ressant / valable / utile. Ce vaisseau est wget. Ou curl. Allez, wget, c’est celui que je connais le mieux.

Installer les packages nécessaires pour ce tutoriel (Debian)
1
apt install html-xml-utils lynx wget

Oui, on va avoir besoin de lynx plus tard, mais de toute façon tu devrais avoir ces commandes installées sur toutes tes machines tout le temps, allons donc.

Voici le site Web que je consulte pour obtenir les prochaines heures de marĂ©e de n’importe quel endroit de la terre :

Ou juste F12Ou juste F12

Mais nous, on veut ces donnĂ©es disponibles directement sur le bureau, comment faire ça juste avec un bĂšte script shell ? Clic droit sur l’élĂ©ment, sĂ©lectionner “Inspecter” ; En visant bien, on obtiend le rĂ©sultat de l’image ci-dessus.

Note le nom (en fait le type et la classe) de l’élĂ©ment, dans notre cas p.lead et nous voilĂ  en chemin 😎

Tous au clavier

Testons ça : entre la commande suivante dans la console - zsh et bash fonctionnent tous les deux - tu as installé wget, hm ?

1
echo "https://www.cabaigne.net/france/bretagne/saint-quay-portrieux/horaire-marees.html" | wget -O- -i- | hxnormalize -x | hxselect -i "p.lead"

Et voici la sortie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--2022-10-13 20:03:06--  https://www.cabaigne.net/france/bretagne/saint-quay-portrieux/horaire-marees.html
Resolving www.cabaigne.net (www.cabaigne.net)... 000.00.00.000, 000.00.0.000, 000.00.0.000, ...
Connecting to www.cabaigne.net (www.cabaigne.net)|172.67.71.187|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘STDOUT’

- [ <=> ] 48.02K 21.7KB/s in 2.2s

2022-10-13 20:03:09 (21.7 KB/s) - written to stdout [49170]

FINISHED --2022-10-13 20:03:09--
Total wall clock time: 4.0s
Downloaded: 1 files, 48K in 2.2s (21.7 KB/s)
<p class="lead"><img src="/site/images/temps.png"></img> <span class="label label-danger">marée
haute</span> Le jeudi 13 octobre 2022 Ă  <b>22:10</b></p>%

Bingo ! Dans cette petite chaßne se trouvent les 2 infos dont nous avons besoin :

  • L’état actuel de la marĂ©e (dans notre cas “haute” (high))
  • La date/heure de la prochaine marĂ©e

Il ne reste plus qu’à se dĂ©barrasser du formatage HTML, ce que seul un dĂ©butant entreprendrait : l’analyse HTML (ou n’importe quel langage de balisage d’ailleurs) est une douleur dont la mĂ©moire ne disparait jamais vraiment, demande Ă  n’importe quelle pauvre Ăąme ayant dĂ©jĂ  essayĂ©.

Non, ce que nous allons faire est de juste demander poliment à Lynx (lynx est installé) dont le travail est de faire pile cela (analyser du HTML) de nous sortir une chaßne propre et non formatée :

1
echo "https://www.cabaigne.net/france/bretagne/saint-quay-portrieux/horaire-marees.html" | wget -O- -i- | hxnormalize -x | hxselect -i "p.lead" | lynx -stdin -dump

Sortie

1
2
3
4
5
FINISHED --2022-10-13 20:10:15--
Total wall clock time: 0.7s
Downloaded: 1 files, 48K in 0.2s (219 KB/s)
[temps.png]
marée haute Le jeudi 13 octobre 2022 à 22:10

Oh, flute, il y a une balise sur notre chemin. Regarde à nouveau l’image ci-dessus. Saperlipopette, ce $*=)! de

1
<img src="/site/images/temps.png">

Est physiquement dans le div mĂȘme, pas moyen d’éviter ça. On va juste l’extraire de la chaĂźne reçue en utilisant ce bon vieux sed

1
echo "https://www.cabaigne.net/france/bretagne/saint-quay-portrieux/horaire-marees.html" | wget -O- -i- | hxnormalize -x | hxselect -i "p.lead" | lynx -stdin -dump | sed '1d'

Sortie

1
2
3
4
FINISHED --2022-10-13 20:20:26--
Total wall clock time: 1.7s
Downloaded: 1 files, 48K in 0.2s (194 KB/s)
marée haute Le jeudi 13 octobre 2022 à 22:10

Tous à la plage 😎

Voici le script que j’ai Ă©crit pour obtenir l’heure et le mouvement de la prochaine marĂ©e directement dans ma barre i3status, accessible en un clin d’Ɠil ; Passer simplement l’url en premier argument.

~/.scripts/px-i3-next-tide-time.sh [url]
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env bash

PHRASE=$(echo "$1" | wget -O- -i- | hxnormalize -x | hxselect -i "p.lead" | lynx -stdin -dump | sed '1d')

MOVE=$(echo $PHRASE | awk '{print $2}')
TIME=$(echo $PHRASE | awk '{print $9}')

[[ $MOVE = "basse" ]] && ICON="" || ICON=""

echo "$TIME $ICON" > /tmp/.next_tide_time.txt

Dans i3

~/.config/i3/config
1
2
3
set $next_tide_script ~/.scripts/px-i3-next-tide-time.sh [url]
exec_always --no-startup-id $next_tide_script

À ce stade, le script s’exĂ©cutera Ă  chaque dĂ©marrage ou redĂ©marrage d’i3 ; Si - comme moi - tu veux qu’il s’exĂ©cute toutes les heures quoi qu’il arrive, utilise ça (avec ton propre ${MYSCRIPTDIR} bien sur)

1
(crontab -l 2>/dev/null; echo "0 * * * * ${MYSCRIPTDIR}/px-i3-next-tide-time.sh") | crontab -

Oui, c’est une entrĂ©e crontab directement depuis le shell, sans avoir Ă  utiliser visudo ou autre non-sens, oui je sais que tu l’as lu ici en premier, merci beaucoup.

~/.config/i3/i3status.conf
1
2
3
4
5
6
7
8
order += "read_file next_tide_time"

read_file next_tide_time {
format = "<span foreground='#ffffff'></span> <span foreground='#3daee9'> %content</span>"
format_bad = ""
path = "/tmp/.next_tide_time.txt"
}

C’est tout, Ă  la prochaine fois, restons rĂ©els. Oh, et attention aux oursins 🐚