Je veux un programme en ligne de commande qui affiche le titre d'un site Web. Par exemple:
Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc
devrait donner:
Why Are Bad Words Bad?
Vous lui donnez l'URL et le titre est imprimé.
command-line
web
http
Ufoguy
la source
la source
Réponses:
Vous pouvez le diriger vers GNU
recode
s’il contient des éléments tels<
que:Pour enlever la
- youtube
pièce:Pour souligner certaines des limitations:
portabilité
Il n'y a pas de commande standard / portable pour effectuer des requêtes HTTP. Il y a quelques décennies, j'aurais recommandé à la
lynx -source
place ici. Mais de nos jours, ilwget
est plus portable car on peut le trouver par défaut sur la plupart des systèmes GNU (y compris la plupart des systèmes d’exploitation pour ordinateurs de bureau / ordinateurs portables basés sur Linux). Parmi les autres assez portables, citons laGET
commande qui vient avecperl
libwww qui est souvent installéelynx -source
, et dans une moindre mesurecurl
. D' autres communes les comprennentlinks -source
,elinks -source
,w3m -dump_source
,lftp -c cat
...Protocole HTTP et traitement de la redirection
wget
peut ne pas obtenir la même page que cellefirefox
affichée par exemple . La raison en est que les serveurs HTTP peuvent choisir d'envoyer une page différente en fonction des informations fournies dans la demande envoyée par le client.La requête envoyée par wget / w3m / GET ... va être différente de celle envoyée par firefox. Si cela pose un problème, vous pouvez modifier le
wget
comportement pour modifier la manière dont il envoie la demande avec des options.Les plus importants ici à cet égard sont:
Accept
etAccept-language
: cela indique au serveur dans quelle langue et quel jeu de caractères le client souhaite obtenir la réponse.wget
n'envoie pas de valeur par défaut, le serveur envoie donc avec ses paramètres par défaut.firefox
à l'autre extrémité est probablement configuré pour demander votre langue.User-Agent
: qui identifie l'application client sur le serveur. Certains sites envoient un contenu différent en fonction du client (bien que ce soit principalement pour des différences entre les interprétations du langage javascript) et peut refuser de vous servir si vous utilisez un agent utilisateur de type robot , commewget
.Cookie
: si vous avez déjà visité ce site, votre navigateur peut avoir des cookies permanents pour cela.wget
Ne fera pas.wget
suivra les redirections quand elles seront terminées au niveau du protocole HTTP, mais comme cela ne regarde pas le contenu de la page, pas celles faites par javascript ou quelque chose comme<meta http-equiv="refresh" content="0; url=http://example.com/">
.Performance / Efficacité
Ici, par paresse, nous avons
perl
lu tout le contenu en mémoire avant de commencer à chercher la<title>
balise. Étant donné que le titre se trouve dans la<head>
section qui se trouve dans les premiers octets du fichier, ce n'est pas optimal. Une meilleure approche, si GNUawk
est disponible sur votre système, pourrait être:De cette façon, awk arrête de lire après le premier
</title
et, en quittant,wget
arrête le téléchargement.Analyse du HTML
Ici,
wget
écrit la page lorsqu’elle la télécharge. En même temps,perl
glisse sa sortie (-0777 -n
) en mémoire, puis imprime le code HTML trouvé entre les premières occurrences de<title...>
et</title
.Cela fonctionnera pour la plupart des pages HTML comportant une
<title>
balise, mais dans certains cas, cela ne fonctionnera pas.En revanche, la solution de coffeeMug analysera la page HTML au format XML et renverra la valeur correspondante pour
title
. Il est plus correct de s’assurer que la page est un XML valide . Cependant, il n'est pas nécessaire que HTML soit un XML valide (les anciennes versions du langage ne l'étaient pas) et, comme la plupart des navigateurs sont cléments et acceptent le code HTML incorrect, il existe même de nombreux codes HTML incorrects.Ma solution et CoffeeMug échoueront dans différents cas, parfois les mêmes, parfois non.
Par exemple, le mien va échouer sur:
ou:
Alors que sa volonté échouera sur:
(HTML valide, pas XML) ou:
ou:
(encore une fois, pièces
html
manquantes<![CDATA[
pour rendre XML valide).(html incorrect, mais toujours trouvé et supporté par la plupart des navigateurs)
interprétation du code à l'intérieur des balises.
Cette solution génère le texte brut entre
<title>
et</title>
. Normalement, il ne devrait pas y avoir de balises HTML, il pourrait y avoir des commentaires (bien que certains navigateurs comme Firefox ne les gèrent pas, ce qui est très peu probable). Il peut encore y avoir un encodage HTML:Ce qui est pris en charge par GNU
recode
:Mais un client Web est également censé faire plus de transformations sur ce code lors de l'affichage du titre (par exemple, condenser certaines des blancs, supprimer les premiers et les derniers). Cependant, il est peu probable que cela soit nécessaire. Donc, comme dans les autres cas, c'est à vous de décider si cela en vaut la peine.
Jeu de caractères
Avant UTF-8, iso8859-1 était le jeu de caractères préféré sur le Web pour les caractères non-ASCII bien que, à proprement parler, ils devaient être écrits sous la forme
é
. Des versions plus récentes de HTTP et du langage HTML ont ajouté la possibilité de spécifier le jeu de caractères dans les en-têtes HTTP ou HTML, et un client peut spécifier les jeux de caractères qu'il accepte. UTF-8 a tendance à être le jeu de caractères par défaut de nos jours.Donc, cela signifie que là-bas, vous trouverez
é
écrit commeé
, comme , commeé
, comme UTF-8é
, (0xc3 0xa9), comme iso-8859-1 (0xe9), avec pour les 2 derniers, parfois les informations sur le jeu de caractères dans les en-têtes HTTP ou les en-têtes HTML (dans différents formats), parfois non.wget
n'obtient que les octets bruts, peu importe leur signification en tant que caractères, ni le serveur Web sur le jeu de caractères préféré.recode html..
se chargera de convertir leé
oué
en la séquence d'octets appropriée pour le jeu de caractères utilisé sur votre système, mais pour le reste, c'est plus compliqué.Si votre jeu de caractères système est utf-8, il y a de fortes chances qu'il fonctionne normalement la plupart du temps, car il s'agit généralement du jeu de caractères par défaut utilisé de nos jours.
Ce qui
é
précède était un UTF-8é
.Mais si vous voulez couvrir d'autres jeux de caractères, encore une fois, il faudra en prendre soin.
Il convient également de noter que cette solution ne fonctionnera pas du tout pour les pages codées UTF-16 ou UTF-32.
Pour résumer
Idéalement, ce dont vous avez besoin ici, c'est un véritable navigateur Web pour vous donner les informations. Autrement dit, vous avez besoin de quelque chose pour traiter la requête HTTP avec les paramètres appropriés, interpréter correctement la réponse HTTP, interpréter intégralement le code HTML comme le ferait un navigateur et renvoyer le titre.
Comme je ne pense pas que cela puisse être fait en ligne de commande avec les navigateurs que je connais (bien que vous voyiez maintenant cette astuce
lynx
), vous devez recourir à des heuristiques et à des approximations, et celle ci-dessus en vaut la peine.Vous pouvez également prendre en compte les performances, la sécurité ... Par exemple, pour couvrir tous les cas (par exemple, une page Web contenant du javascript extrait d'un site tiers qui définit le titre ou redirige vers une autre page dans une page Web). onload), vous devrez peut-être implémenter un navigateur de la vie réelle avec ses moteurs dom et javascript qui devront peut-être faire des centaines de requêtes pour une seule page HTML, dont certaines tentent d'exploiter des vulnérabilités ...
Bien que l’ utilisation des expressions rationnelles pour analyser le langage HTML soit souvent mal vue , voici un cas typique où il convient assez bien à la tâche (IMO).
la source
<
car il n’est pas garanti que les titres ont des balises de fin et toute autre balise devrait forcer sa résiliation. Vous pouvez également vouloir supprimer de nouvelles lignes.Vous pouvez également essayer
hxselect
(à partir de HTML-XML-Utils ) avecwget
les éléments suivants:Vous pouvez installer
hxselect
dans Debian en utilisant la base distros:sudo apt-get install html-xml-utils
.La redirection STDERR consiste à éviter le
Input is not well-formed. (Maybe try normalize?)
message.Pour vous débarrasser de "- YouTube", dirigez la sortie de la commande ci-dessus vers
awk '{print substr($0, 0, length($0)-10)}'
.la source
sudo apt-get install html-xml-utils
-i
àhxselect
trop pour les mêmes raisons que manatwork mentionnées dans mon A, sinon il ne correspond pas à<TITLE>
.hxselect
.brew install html-xml-utils
.wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' | hxclean | hxselect -s '\n' -c 'title' 2>/dev/null
).Vous pouvez également utiliser
curl
etgrep
faire ceci. Vous aurez besoin d'obtenir l'utilisation de PCRE (Perl Compatible Regular Expressions) dansgrep
pour obtenir le look derrière et regarder installations à venir afin que nous puissions trouver les<title>...</title>
tags.Exemple
Détails
Les
curl
interrupteurs:-s
= silencieux-o -
= envoyer la sortie à STDOUTLes
grep
interrupteurs:-i
= insensibilité à la casse-o
= Retourne seulement la portion qui correspond-P
= Mode PCRELe motif pour
grep
:(?<=<title>)
= cherche une chaîne qui commence par celle-ci à sa gauche(?=</title>)
= cherche une chaîne qui se termine par ceci à sa droite(.*)
= tout entre les deux<title>..</title>
.Situations plus complexes
Si
<title>...</titie>
s'étend sur plusieurs lignes, alors ce qui précède ne le trouvera pas. Vous pouvez atténuer cette situation en utilisanttr
, pour supprimer tous les\n
caractères, c.-à-dtr -d '\n'
.Exemple
Exemple de fichier.
Et un exemple de parcours:
lang = ...
Si le
<title>
paramètre est défini comme ceci,<title lang="en">
vous devrez le supprimer avant de l'grep
initialiser. L'outilsed
peut être utilisé pour cela:Ce qui précède trouve la chaîne insensible à la casse
lang=
suivie par une séquence de mots (\w+
). Il est ensuite retiré.Un véritable analyseur HTML / XML - avec Ruby
À un moment donné, regex échouera dans la résolution de ce type de problème. Si cela se produit, vous voudrez probablement utiliser un véritable analyseur HTML / XML. Nokogiri est l'un de ces analyseurs . Il est disponible dans Ruby en tant que gemme et peut être utilisé comme suit:
Ce qui précède est l’analyse des données provenant de
curl
as as HTML (Nokogiri::HTML
). La méthodexpath
recherche ensuite les nœuds (balises) dans le HTML qui sont des nœuds feuilles (//
) avec le nomtitle
. Pour chaque trouvé, nous voulons retourner son contenu (e.content
). Le lesputs
imprime ensuite.Un véritable analyseur HTML / XML - en utilisant Perl
Vous pouvez également faire quelque chose de similaire avec Perl et le module HTML :: TreeBuilder :: XPath .
Vous pouvez ensuite exécuter ce script comme suit:
la source
<title>Unix\nLinux</title>
est censé êtreUnix Linux
, pasUnixLinux
.Utiliser regex simple pour analyser HTML est naïf. Par exemple, avec des nouvelles lignes et en ignorant le codage des caractères spéciaux spécifié dans le fichier. Faites la bonne chose et analysez vraiment la page en utilisant l'un des autres analyseurs réels mentionnés dans les autres réponses ou utilisez le liner suivant:
(Ce qui précède comprend un caractère Unicode).
BeautifulSoup gère également un grand nombre de codes HTML incorrects (par exemple des balises de fermeture manquantes), ce qui provoquerait une expression rationnelle simpliste. Vous pouvez l'installer dans un python standard en utilisant:
ou si vous n'avez pas
pip
, avecCertains systèmes d'exploitation tels que Debian / Ubuntu l'ont également empaqueté (
python-bs4
paquet sur Debian / Ubuntu).la source
bs4
n'est pas dans la bibliothèque standard Python. Vous devez l'installer en utilisanteasy_install beautfulsoup4
(noneasyinstall bs4
).Peut-être que c'est "tricher", mais l'une des options est chiot, un analyseur HTML en ligne de commande .
Voici deux façons de le faire:
Utiliser le
meta
champ avecproperty="og:title
attributet une autre manière en utilisant le
title
champ directement (puis en coupant la- YouTube
chaîne à la fin).la source
--plain
option de chiot .Il semble être possible en
lynx
utilisant cette astuce (zsh
,bash
syntaxe):Parce que c'est un navigateur Web réel, il ne souffre pas de nombreuses limitations que je mentionne dans mon autre réponse .
Ici, nous utilisons le fait que
lynx
la$LYNX_PRINT_TITLE
variable d'environnement est définie sur le titre de la page en cours lors de l'impression de la page.Ci-dessus, nous donnons un fichier de configuration (sous forme de tube) qui définit une "imprimante" lynx appelée
P
simplement le contenu de cette variable dans un descripteur de fichier3
(ce descripteur de fichier est redirigé vers la sortielynx
standard de stdout3>&1
tandis que lynx stdout est lui-même redirigé vers / dev / null).Ensuite, nous utilisons un
lynx
script pour simuler l’utilisateur en appuyant surp
, puis surEnd
(aka select), etEnter
(^J
).-accept_all_cookies
sinon, Lynx demanderait à l'utilisateur une confirmation pour chaque cookie.la source
Manière simple:
Peu d'alternatives:
la source
J'aimais bien l'idée de Stéphane Chazelas d'utiliser Lynx et LYNX_PRINT_TITLE, mais ce script ne fonctionnait pas pour moi sous Ubuntu 14.04.5.
J'en ai fait une version simplifiée en utilisant Lynx et en utilisant des fichiers pré-configurés à l'avance.
Ajoutez la ligne suivante à /etc/lynx-cur/lynx.cfg (ou à l’endroit où réside votre lynx.cfg):
Cette ligne vous invite à enregistrer le titre, lors de l’impression, dans "/home/account/title.txt" - vous pouvez choisir le nom de fichier de votre choix. Vous demandez TRES grandes pages, augmentez la valeur ci-dessus de "1000" à un nombre quelconque de lignes par page, sinon Lynx fera apparaître une invite supplémentaire "lors de l'impression d'un document contenant un très grand nombre de pages".
Créez ensuite le fichier /home/account/lynx-script.txt avec le contenu suivant:
Ensuite, exécutez Lynx en utilisant les options de ligne de commande suivantes:
A l'issue de cette commande, le fichier /home/account/title.txt sera créé avec le titre de votre page.
En résumé, voici une fonction PHP qui renvoie un titre de page basé sur l'URL donnée, ou false en cas d'erreur.
la source
En utilisant nokogiri, on peut utiliser une simple requête basée sur CSS pour extraire le texte intérieur de la balise:
De même, pour extraire la valeur de l'attribut "content" de la balise:
la source