Eu quero um programa de linha de comando que imprima o título de um site. Por exemplo:
Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc
deveria dar:
Why Are Bad Words Bad?
Você fornece o URL e ele imprime o título.
command-line
web
http
Ufoguy
fonte
fonte
Respostas:
Você pode canalizar para o GNU
recode
se houver coisas como<
:Para remover a
- youtube
peça:Para apontar algumas das limitações:
portabilidade
Não há comando padrão / portátil para fazer consultas HTTP. Algumas décadas atrás, eu recomendaria
lynx -source
aqui. Atualmente, porém,wget
é mais portátil, pois pode ser encontrado por padrão na maioria dos sistemas GNU (incluindo a maioria dos sistemas operacionais de desktop / laptop baseados em Linux). Outros razoavelmente portáveis incluem oGET
comando que vem comperl
a libwww que é frequentemente instalada elynx -source
, em menor graucurl
. Outros comuns aqueles incluemlinks -source
,elinks -source
,w3m -dump_source
,lftp -c cat
...Protocolo HTTP e manipulação de redirecionamento
wget
pode não ter a mesma página que a que, por exemplo,firefox
seria exibida. O motivo é que os servidores HTTP podem optar por enviar uma página diferente com base nas informações fornecidas na solicitação enviada pelo cliente.A solicitação enviada pelo wget / w3m / GET ... será diferente da enviada pelo firefox. Se esse é um problema, você pode alterar o
wget
comportamento para alterar a maneira como ele envia a solicitação, com opções.Os mais importantes aqui a esse respeito são:
Accept
eAccept-language
: informa ao servidor em que idioma e conjunto de caracteres o cliente gostaria de receber a resposta.wget
não envia nenhum por padrão; portanto, o servidor normalmente envia com suas configurações padrão.firefox
do outro lado, provavelmente está configurado para solicitar seu idioma.User-Agent
: que identifica o aplicativo cliente para o servidor. Alguns sites enviam conteúdo diferente com base no cliente (embora seja principalmente devido a diferenças entre interpretações de linguagem javascript) e podem se recusar a atendê-lo se você estiver usando um agente de usuário do tipo robôwget
.Cookie
: se você já visitou este site antes, seu navegador pode ter cookies permanentes para ele.wget
não vou.wget
seguirá os redirecionamentos quando forem feitos no nível do protocolo HTTP, mas como ele não analisa o conteúdo da página, não os que são feitos por javascript ou coisas do tipo<meta http-equiv="refresh" content="0; url=http://example.com/">
.Desempenho / Eficiência
Aqui, por preguiça,
perl
lemos todo o conteúdo na memória antes de começar a procurar a<title>
tag. Dado que o título é encontrado na<head>
seção que está nos primeiros bytes do arquivo, isso não é o ideal. Uma abordagem melhor, se o GNUawk
estiver disponível no seu sistema, pode ser:Dessa forma, o awk para de ler após o primeiro
</title
e, ao sair, fazwget
com que o download seja interrompido.Análise do HTML
Aqui,
wget
escreve a página enquanto a baixa. Ao mesmo tempo,perl
inverte toda a saída (-0777 -n
) na memória e depois imprime o código HTML encontrado entre as primeiras ocorrências de<title...>
e</title
.Isso funcionará para a maioria das páginas HTML que possuem uma
<title>
tag, mas há casos em que ela não funciona.Por outro lado, a solução do coffeeMug analisará a página HTML como XML e retornará o valor correspondente para
title
. É mais correto se é garantido que a página é XML válida . No entanto, não é necessário que o HTML seja XML válido (as versões mais antigas da linguagem não eram) e, como a maioria dos navegadores existentes é branda e aceita códigos HTML incorretos, há muitos códigos HTML incorretos por aí.Tanto a minha solução como a do coffeeMug falharão em vários casos de canto, às vezes iguais, às vezes não.
Por exemplo, o meu falhará:
ou:
Enquanto o dele falhará:
(html válido, não xml) ou:
ou:
(novamente, partes
html
ausentes e válidas<![CDATA[
para torná-lo XML válido).(html incorreto, mas ainda encontrado e suportado pela maioria dos navegadores)
interpretação do código dentro das tags.
Essa solução gera o texto bruto entre
<title>
e</title>
. Normalmente, não deve haver nenhuma tag HTML, pode haver comentários (embora não sejam tratados por alguns navegadores como o Firefox tão improvável). Ainda pode haver alguma codificação HTML:O que é tratado pelo GNU
recode
:Mas um cliente da Web também deve fazer mais transformações nesse código ao exibir o título (como condensar alguns espaços em branco, remover os principais e os finais). No entanto, é improvável que haja uma necessidade disso. Assim, como nos outros casos, cabe a você decidir se vale a pena o esforço.
Conjunto de caracteres
Antes do UTF-8, iso8859-1 costumava ser o conjunto de caracteres preferido na Web para caracteres não ASCII, embora estritamente falando eles precisassem ser escritos como
é
. Versões mais recentes do HTTP e da linguagem HTML adicionaram a possibilidade de especificar o conjunto de caracteres nos cabeçalhos HTTP ou HTML, e um cliente pode especificar os conjuntos de caracteres que aceita. Atualmente, o UTF-8 é o conjunto de caracteres padrão.Então, isso significa que lá fora, você vai encontrar
é
escrito comoé
, comoé
, como UTF-8é
, (0xC3 0xA9), como iso-8859-1 (0xE9), com os 2 últimos, por vezes, as informações sobre o charset nos cabeçalhos HTTP ou HTML (em diferentes formatos), às vezes não.wget
obtém apenas os bytes brutos, não se importa com o significado deles como caracteres e não informa o servidor da web sobre o conjunto de caracteres preferido.recode html..
tomará o cuidado de converteré
oué
na seqüência adequada de bytes para o conjunto de caracteres usado em seu sistema, mas, quanto ao resto, isso é mais complicado.Se o seu conjunto de caracteres do sistema for utf-8, é provável que esteja tudo bem na maioria das vezes, pois esse tende a ser o conjunto de caracteres padrão usado hoje em dia.
Isso
é
acima foi um UTF-8é
.Mas se você deseja cobrir outros conjuntos de caracteres, mais uma vez, isso deve ser resolvido.
Também deve ser observado que esta solução não funcionará de maneira alguma para páginas codificadas em UTF-16 ou UTF-32.
Resumindo
Idealmente, o que você precisa aqui é um navegador da Web real para fornecer as informações. Ou seja, você precisa de algo para fazer a solicitação HTTP com os parâmetros adequados, interpretar a resposta HTTP corretamente, interpretar completamente o código HTML como um navegador faria e retornar o título.
Como não acho que isso possa ser feito na linha de comando com os navegadores que conheço (embora veja agora esse truque
lynx
), você precisa recorrer a heurísticas e aproximações, e a acima é tão boa quanto qualquer outra.Você também pode levar em consideração desempenho, segurança ... Por exemplo, para cobrir todos os casos (por exemplo, uma página da Web que tenha algum javascript extraído de um site de terceiros que define o título ou redireciona para outra página em um onload hook), pode ser necessário implementar um navegador da vida real com seus mecanismos dom e javascript que podem precisar fazer centenas de consultas para uma única página HTML, algumas das quais tentando explorar vulnerabilidades ...
Embora o uso de regexps para analisar HTML geralmente seja desaprovado , este é um caso típico em que é bom o suficiente para a tarefa (IMO).
fonte
<
uma vez que não é garantido que os títulos tenham tags finais e qualquer outra tag deve forçar seu término. Você também pode querer descascar novas linhas.Você também pode tentar
hxselect
(do HTML-XML-Utils ) comwget
o seguinte:Você pode instalar
hxselect
em distros baseadas Debian usando:sudo apt-get install html-xml-utils
.O redirecionamento STDERR é para evitar a
Input is not well-formed. (Maybe try normalize?)
mensagem.Para se livrar do "- YouTube", canalize a saída do comando acima para
awk '{print substr($0, 0, length($0)-10)}'
.fonte
sudo apt-get install html-xml-utils
hxselect
.brew install html-xml-utils
.Você também pode usar
curl
egrep
fazer isso. Você vai precisar de recorrer a utilização do PCRE (Perl Compatible Regular Expressions) emgrep
para obter a aparência trás e instalações à frente olhar para que possamos encontrar as<title>...</title>
tags.Exemplo
Detalhes
Os
curl
comutadores:-s
= silencioso-o -
= envia a saída para STDOUTOs
grep
comutadores:-i
= insensibilidade ao caso-o
= Retorna apenas a parte que corresponde-P
= Modo PCREO padrão para
grep
:(?<=<title>)
= procure uma string que comece com isso à esquerda dela(?=</title>)
= procure uma string que termine com isso à direita(.*)
= tudo no meio<title>..</title>
.Situações mais complexas
Se
<title>...</titie>
abranger várias linhas, o item acima não o encontrará. Você pode atenuar essa situação usandotr
, para excluir qualquer\n
caractere, ou sejatr -d '\n'
.Exemplo
Arquivo de exemplo.
E uma amostra:
lang = ...
Se o
<title>
conjunto estiver definido assim,<title lang="en">
você precisará removê-lo antes degrep
inseri-lo. A ferramentased
pode ser usada para fazer isso:O
lang=
texto acima localiza a sequência que não diferencia maiúsculas de minúsculas, seguida por uma sequência de palavras (\w+
). É então retirado.Um analisador de HTML / XML real - usando Ruby
Em algum momento, o regex falhará na solução desse tipo de problema. Se isso ocorrer, é provável que você queira usar um analisador de HTML / XML real. Um desses analisadores é Nokogiri . Está disponível no Ruby como uma jóia e pode ser usado assim:
A descrição acima está analisando os dados que vêm via
curl
HTML (Nokogiri::HTML
). O métodoxpath
procura por nós (tags) no HTML que são nós folha (//
) com o nometitle
. Para cada encontrado, queremos retornar seu conteúdo (e.content
). Emputs
seguida, os imprime.Um analisador de HTML / XML real - usando Perl
Você também pode fazer algo semelhante com o Perl e o módulo HTML :: TreeBuilder :: XPath .
Você pode executar este script da seguinte maneira:
fonte
<title>Unix\nLinux</title>
é para serUnix Linux
, nãoUnixLinux
.Usar regex simples para analisar HTML é ingênuo. Por exemplo, com novas linhas e ignorando a codificação de caracteres especiais especificada no arquivo. Faça a coisa certa e realmente analise a página usando qualquer um dos outros analisadores reais mencionados nas outras respostas ou use o seguinte liner:
(O exemplo acima inclui um caractere Unicode).
O BeautifulSoup também lida com um monte de HTML incorreto (por exemplo, falta de tags de fechamento), o que geraria completamente um regexing simplista. Você pode instalá-lo em um python padrão usando:
ou se você não tiver
pip
, comAlguns sistemas operacionais como o Debian / Ubuntu também o têm (
python-bs4
pacote no Debian / Ubuntu).fonte
bs4
não está na biblioteca padrão do python. Você precisa instalá-lo usandoeasy_install beautfulsoup4
(nãoeasyinstall bs4
).Talvez esteja "trapaceando", mas uma opção é pup, um analisador de HTML de linha de comando .
Aqui estão duas maneiras de fazer isso:
Usando o
meta
campo comproperty="og:title
atributoe outra maneira de usar o
title
campo diretamente (e depois cortar a- YouTube
string no final).fonte
--plain
opção de filhote .Parece ser possível com
lynx
este truque (zsh
,bash
sintaxe):Por ser um navegador da vida real, ele não sofre muitas das limitações mencionadas na minha outra resposta .
Aqui, estamos usando o fato de que
lynx
define a$LYNX_PRINT_TITLE
variável de ambiente como o título da página atual ao imprimir a página.Acima, estamos fornecendo um arquivo de configuração (como um canal) que define uma "impressora" do lynx chamada
P
que apenas gera o conteúdo dessa variável para o descritor de arquivos3
(esse descritor de arquivo é redirecionado paralynx
o stdout com3>&1
enquanto o lynx stdout é redirecionado para / dev / null).Em seguida, usamos
lynx
o recurso de script para simular o pressionamento do usuáriop
eEnd
(aka select) eEnter
(^J
).-accept_all_cookies
caso contrário, o lynx solicitaria ao usuário a confirmação de cada cookie.fonte
Maneira simples:
Poucas alternativas:
fonte
Gostei da ideia de Stéphane Chazelas de usar Lynx e LYNX_PRINT_TITLE, mas esse script não funcionou para mim no Ubuntu 14.04.5.
Fiz uma versão simplificada usando o Lynx e arquivos pré-configurados com antecedência.
Adicione a seguinte linha ao /etc/lynx-cur/lynx.cfg (ou onde quer que seu lynx.cfg esteja):
Esta linha instrui a salvar o título, durante a impressão, em "/home/account/title.txt" - você pode escolher qualquer nome de arquivo que desejar. Você solicita MUITAS páginas grandes, aumenta o valor acima de "1000" para qualquer número de linhas por página que desejar, caso contrário, o Lynx fará um prompt adicional "ao imprimir documentos contendo um número muito grande de páginas".
Em seguida, crie o arquivo /home/account/lynx-script.txt com o seguinte conteúdo:
Em seguida, execute o Lynx usando as seguintes opções de linha de comando:
Após a conclusão deste comando, o arquivo /home/account/title.txt será criado com o título da sua página.
Para encurtar a história, aqui está uma função PHP que retorna um título de página com base no URL fornecido ou falso em caso de erro.
fonte
Usando nokogiri, é possível usar uma consulta simples baseada em CSS para extrair o texto interno da tag:
Da mesma forma, para extrair o valor do atributo "content" da tag:
fonte