Quiero un programa de línea de comando que imprima el título de un sitio web. Por ejemplo:
Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc
debería dar:
Why Are Bad Words Bad?
Le das la url e imprime el Título.
command-line
web
http
Ufoguy
fuente
fuente
Respuestas:
Puede canalizarlo a GNU
recode
si hay cosas como<
en él:Para quitar la
- youtube
parte:Para señalar algunas de las limitaciones:
portabilidad
No hay un comando estándar / portátil para hacer consultas HTTP. Hace unas décadas, hubiera recomendado
lynx -source
aquí. Pero hoy en día,wget
es más portátil, ya que se puede encontrar por defecto en la mayoría de los sistemas GNU (incluidos la mayoría de los sistemas operativos de escritorio / portátiles basados en Linux). Otros que son bastante portátiles incluyen elGET
comando que viene conperl
la libwww que a menudo se instalalynx -source
, y en menor medidacurl
. Otros comunes los incluyenlinks -source
,elinks -source
,w3m -dump_source
,lftp -c cat
...Protocolo HTTP y manejo de redireccionamiento
wget
es posible que no obtenga la misma página que la que, por ejemplo,firefox
se mostrará. La razón es que los servidores HTTP pueden elegir enviar una página diferente en función de la información proporcionada en la solicitud enviada por el cliente.La solicitud enviada por wget / w3m / GET ... será diferente de la enviada por firefox. Si eso es un problema, puede modificar el
wget
comportamiento para cambiar la forma en que envía la solicitud, aunque con opciones.Los más importantes aquí a este respecto son:
Accept
yAccept-language
: eso le dice al servidor en qué idioma y conjunto de caracteres le gustaría al cliente obtener la respuesta.wget
no envía ninguno de manera predeterminada, por lo que el servidor generalmente enviará con su configuración predeterminada.firefox
en el otro extremo es probable que esté configurado para solicitar su idioma.User-Agent
: que identifica la aplicación del cliente para el servidor. Algunos sitios envían contenido diferente basado en el cliente (aunque eso es principalmente por diferencias entre las interpretaciones del lenguaje javascript) y pueden negarse a servirle si está utilizando un agente de usuario de tipo robotwget
.Cookie
: si ha visitado este sitio anteriormente, su navegador puede tener cookies permanentes.wget
No lo haré.wget
seguirá las redirecciones cuando se realicen en el nivel de protocolo HTTP, pero dado que no analiza el contenido de la página, no las realizadas por javascript o cosas por el estilo<meta http-equiv="refresh" content="0; url=http://example.com/">
.Eficiencia en el desempeño
Aquí, por flojera, hemos
perl
leído todo el contenido en la memoria antes de comenzar a buscar la<title>
etiqueta. Dado que el título se encuentra en la<head>
sección que se encuentra en los primeros bytes del archivo, eso no es óptimo. Un mejor enfoque, si GNUawk
está disponible en su sistema podría ser:De esa manera, awk deja de leer después de la primera
</title
y, al salir, hacewget
que se detenga la descarga.Análisis del HTML
Aquí,
wget
escribe la página a medida que la descarga. Al mismo tiempo,perl
sorbe su salida (-0777 -n
) completa en la memoria y luego imprime el código HTML que se encuentra entre las primeras apariciones de<title...>
y</title
.Eso funcionará para la mayoría de las páginas HTML que tienen una
<title>
etiqueta, pero hay casos en los que no funcionará.Por el contrario, la solución de coffeeMug analizará la página HTML como XML y devolverá el valor correspondiente para
title
. Es más correcto si se garantiza que la página sea XML válido . Sin embargo, no se requiere que HTML sea XML válido (las versiones anteriores del lenguaje no lo eran), y debido a que la mayoría de los navegadores son indulgentes y aceptarán códigos HTML incorrectos, incluso hay muchos códigos HTML incorrectos.Tanto mi solución como coffeeMug fallarán en una variedad de casos de esquina, a veces lo mismo, a veces no.
Por ejemplo, el mío fallará en:
o:
Mientras que su fallará:
(html válido, no xml) o:
o:
(de nuevo, válido
html
, faltan<![CDATA[
partes para que sea válido XML).(HTML incorrecto, pero aún se encuentra allí y es compatible con la mayoría de los navegadores)
interpretación del código dentro de las etiquetas.
Esa solución genera el texto sin formato entre
<title>
y</title>
. Normalmente, no debe haber ninguna etiqueta HTML allí, posiblemente puede haber comentarios (aunque algunos navegadores como Firefox no los manejan, por lo que es muy poco probable). Todavía puede haber algo de codificación HTML:De lo que se ocupa GNU
recode
:Pero un cliente web también está destinado a hacer más transformaciones en ese código al mostrar el título (como condensar algunos de los espacios en blanco, eliminar los iniciales y finales). Sin embargo, es poco probable que sea necesario. Entonces, como en los otros casos, depende de usted decidir si vale la pena el esfuerzo.
Conjunto de caracteres
Antes de UTF-8, iso8859-1 solía ser el juego de caracteres preferido en la web para caracteres que no son ASCII, aunque estrictamente hablando tenían que escribirse como
é
. Las versiones más recientes de HTTP y el lenguaje HTML han agregado la posibilidad de especificar el conjunto de caracteres en los encabezados HTTP o en los encabezados HTML, y un cliente puede especificar los conjuntos de caracteres que acepta. UTF-8 tiende a ser el juego de caracteres predeterminado en la actualidad.Entonces, eso significa que, por ahí, encontrará
é
escrito comoé
, comoé
, como UTF-8é
, (0xc3 0xa9), como iso-8859-1 (0xe9), con los 2 últimos, a veces la información en el juego de caracteres en los encabezados HTTP o los encabezados HTML (en diferentes formatos), a veces no.wget
solo obtiene los bytes sin procesar, no le importa su significado como caracteres y no le dice al servidor web sobre el juego de caracteres preferido.recode html..
se encargará de convertir elé
oé
en la secuencia adecuada de bytes para el conjunto de caracteres utilizado en su sistema, pero para el resto, eso es más complicado.Si el conjunto de caracteres de su sistema es utf-8, es probable que esté bien la mayor parte del tiempo, ya que tiende a ser el conjunto de caracteres predeterminado que se utiliza actualmente.
Eso de
é
arriba era un UTF-8é
.Pero si quieres cubrir otros charsets, una vez más, habrá que cuidarlo.
También debe tenerse en cuenta que esta solución no funcionará en absoluto para las páginas codificadas UTF-16 o UTF-32.
Para resumir
Idealmente, lo que necesita aquí es un navegador web real para brindarle la información. Es decir, necesita algo para hacer la solicitud HTTP con los parámetros adecuados, interpretar la respuesta HTTP correctamente, interpretar completamente el código HTML como lo haría un navegador y devolver el título.
Como no creo que se pueda hacer en la línea de comandos con los navegadores que conozco (aunque ahora vea este truco
lynx
), debe recurrir a la heurística y las aproximaciones, y la anterior es tan buena como cualquiera.También es posible que desee tener en cuenta el rendimiento, la seguridad ... Por ejemplo, para cubrir todos los casos (por ejemplo, una página web que tiene algunos javascript extraídos de un sitio de terceros que establece el título o redirige a otra página en un onload hook), puede que tenga que implementar un navegador de la vida real con sus motores dom y javascript que pueden tener que hacer cientos de consultas para una sola página HTML, algunas de las cuales intentan explotar vulnerabilidades ...
Si bien el uso de expresiones regulares para analizar HTML a menudo está mal visto , este es un caso típico en el que es lo suficientemente bueno para la tarea (IMO).
fuente
<
ya que no se garantiza que los títulos tengan etiquetas finales y cualquier otra etiqueta debería forzar su terminación. También es posible que desee quitar nuevas líneas.También puede probar
hxselect
(desde HTML-XML-Utils ) conwget
lo siguiente:Se puede instalar
hxselect
en distribuciones basadas en Debian usando:sudo apt-get install html-xml-utils
.La redirección de STDERR es para evitar el
Input is not well-formed. (Maybe try normalize?)
mensaje.Para deshacerse de "- YouTube", canalice la salida del comando anterior a
awk '{print substr($0, 0, length($0)-10)}'
.fuente
sudo apt-get install html-xml-utils
hxselect
.brew install html-xml-utils
.También puede usar
curl
ygrep
para hacer esto. Tendrá que recurrir a la utilización de PCRE (Perl Compatible Regular Expressions) engrep
conseguir la mirada detrás de las instalaciones y mirar hacia adelante para que podamos encontrar las<title>...</title>
etiquetas.Ejemplo
Detalles
Los
curl
interruptores:-s
= silencioso-o -
= enviar salida a STDOUTLos
grep
interruptores:-i
= insensibilidad a mayúsculas y minúsculas-o
= Devuelve solo la porción que coincide-P
= Modo PCREEl patrón para
grep
:(?<=<title>)
= busca una cadena que comience con esto a la izquierda de ella(?=</title>)
= busca una cadena que termine con esto a la derecha(.*)
= todo en el medio<title>..</title>
.Situaciones más complejas
Si
<title>...</titie>
abarca varias líneas, entonces lo anterior no lo encontrará. Puede mitigar esta situación utilizandotr
, para eliminar cualquier\n
carácter, es decirtr -d '\n'
.Ejemplo
Archivo de muestra
Y una muestra de ejecución:
lang = ...
Si
<title>
se configura así,<title lang="en">
entonces deberá eliminarlo antes degrep
usarlo. La herramientased
se puede usar para hacer esto:Lo anterior encuentra la cadena que no distingue entre mayúsculas y minúsculas
lang=
seguida de una secuencia de palabras (\w+
). Luego es despojado.Un analizador HTML / XML real - usando Ruby
En algún momento, la expresión regular fallará al resolver este tipo de problema. Si eso ocurre, es probable que desee utilizar un analizador HTML / XML real. Uno de esos analizadores es Nokogiri . Está disponible en Ruby as a Gem y se puede usar así:
Lo anterior está analizando los datos que vienen a través de
curl
como HTML (Nokogiri::HTML
). El métodoxpath
luego busca nodos (etiquetas) en el HTML que son nodos hoja, (//
) con el nombretitle
. Para cada encontrado, queremos devolver su contenido (e.content
). Elputs
luego los imprime.Un analizador HTML / XML real - usando Perl
También puede hacer algo similar con Perl y el módulo HTML :: TreeBuilder :: XPath .
Luego puede ejecutar este script de la siguiente manera:
fuente
<title>Unix\nLinux</title>
está destinado a serUnix Linux
, noUnixLinux
.Usar expresiones regulares simples para analizar HTML es ingenuo. Por ejemplo, con líneas nuevas e ignorando la codificación de caracteres especiales especificada en el archivo. Haga lo correcto y analice realmente la página utilizando cualquiera de los otros analizadores reales mencionados en las otras respuestas o utilice el siguiente delineador:
(Lo anterior incluye un carácter Unicode).
BeautifulSoup también maneja una gran cantidad de HTML incorrecto (por ejemplo, faltan etiquetas de cierre), que arrojaría por completo expresiones regulares simplistas. Puede instalarlo en una python estándar usando:
o si no tienes
pip
, conAlgunos sistemas operativos como Debian / Ubuntu también lo tienen empaquetado (
python-bs4
paquete en Debian / Ubuntu).fuente
bs4
no está en la biblioteca estándar de python. Tienes que instalarlo usandoeasy_install beautfulsoup4
(noeasyinstall bs4
).Tal vez sea "trampa", pero una opción es pup, un analizador HTML de línea de comandos .
Aquí hay dos formas de hacerlo:
Usando el
meta
campo conproperty="og:title
atributoy otra forma de usar el
title
campo directamente (y luego cortar la- YouTube
cadena al final).fuente
--plain
opción de cachorro .Parece posible con el
lynx
uso de este truco (zsh
,bash
sintaxis):Debido a que es un navegador web de la vida real, no sufre muchas de las limitaciones que menciono en mi otra respuesta .
Aquí, estamos usando el hecho de que
lynx
establece la$LYNX_PRINT_TITLE
variable de entorno al título de la página actual al imprimir la página.Por encima, estamos dando un archivo de configuración (como un tubo) que define una "impresora" lince llamada
P
que simplemente da salida al contenido de esa variable de descriptor de archivo3
(que descriptor de archivo se redirige alynx
's stdout con3>&1
mientras que la salida estándar lince es en sí redirigidos a / dev / null).Luego usamos la función de
lynx
secuencias de comandos para simular que el usuario presionap
, yEnd
(también conocido como select) yEnter
(^J
).-accept_all_cookies
de lo contrario, Lynx solicitaría al usuario la confirmación de cada cookie.fuente
Manera simple:
Pocas alternativas:
fuente
Me gustó la idea de Stéphane Chazelas de usar Lynx y LYNX_PRINT_TITLE, pero ese script no me funcionó en Ubuntu 14.04.5.
He creado una versión simplificada usando Lynx y archivos preconfigurados de antemano.
Agregue la siguiente línea a /etc/lynx-cur/lynx.cfg (o donde sea que resida su lynx.cfg):
Esta línea le indica que guarde el título, mientras imprime, en "/home/account/title.txt"; puede elegir el nombre de archivo que desee. Solicita páginas MUY grandes, aumente el valor anterior de "1000" a cualquier número de líneas por página que desee, de lo contrario Lynx hará un mensaje adicional "al imprimir documentos que contengan un número muy grande de páginas".
Luego cree el archivo /home/account/lynx-script.txt con el siguiente contenido:
Luego ejecute Lynx usando las siguientes opciones de línea de comandos:
Al completar este comando, el archivo /home/account/title.txt se creará con el título de su página.
Para resumir, aquí hay una función PHP que devuelve un título de página basado en la URL dada, o falso en caso de error.
fuente
Usando nokogiri, uno puede usar una consulta simple basada en CSS para extraer el texto interno de la etiqueta:
Del mismo modo, para extraer el valor del atributo "contenido" de la etiqueta:
fuente