Я хочу программу командной строки, которая печатает заголовок веб-сайта. Например:
Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc
должен дать:
Why Are Bad Words Bad?
Вы даете ему URL, и он печатает название.
command-line
web
http
Ufoguy
источник
источник
Ответы:
Вы можете передать его в GNU,
recode
если есть такие вещи<
:Чтобы удалить
- youtube
часть:Чтобы указать на некоторые из ограничений:
портативность
Не существует стандартной / переносимой команды для выполнения HTTP-запросов. Несколько десятилетий назад я бы рекомендовал
lynx -source
вместо этого здесь. Но в настоящее времяwget
он более переносим, поскольку его можно найти по умолчанию в большинстве систем GNU (включая большинство операционных систем для настольных компьютеров / ноутбуков на базе Linux). Другие довольно переносимые включаютGET
команду, которая поставляется сperl
libwww, которая часто устанавливаетсяlynx -source
, и в меньшей степениcurl
. Другие распространенные из них включают в себяlinks -source
,elinks -source
,w3m -dump_source
,lftp -c cat
...HTTP протокол и обработка перенаправления
wget
может не получить ту же страницу, что и та, которая, например,firefox
будет отображаться. Причина в том, что HTTP-серверы могут выбрать отправку другой страницы на основе информации, предоставленной в запросе, отправленном клиентом.Запрос, отправленный wget / w3m / GET ..., будет отличаться от запроса, отправленного firefox. Если это проблема, вы можете изменить
wget
поведение, чтобы изменить способ отправки запроса с помощью параметров.Наиболее важными здесь в этом отношении являются:
Accept
иAccept-language
: сообщает серверу, на каком языке и кодировке клиент хотел бы получить ответ.wget
По умолчанию он не отправляется, поэтому сервер обычно отправляет с настройками по умолчанию.firefox
на другом конце, скорее всего, настроен на запрос вашего языка.User-Agent
: идентифицирует клиентское приложение на сервере. Некоторые сайты отправляют разный контент на основе клиента (хотя это в основном из-за различий между интерпретациями языка javascript) и могут отказаться обслуживать вас, если вы используете пользовательский агент типа роботаwget
.Cookie
: если вы посещали этот сайт раньше, в вашем браузере могут быть постоянные файлы cookie для него.wget
не буду.wget
будет следовать перенаправлениям, когда они будут выполнены на уровне протокола HTTP, но так как он не смотрит на содержимое страницы, а не на содержимое javascript или тому подобное<meta http-equiv="refresh" content="0; url=http://example.com/">
.Производительность / эффективность
Здесь, из-за лени, мы
perl
прочитали весь контент в памяти, прежде чем начать искать<title>
тег. Учитывая, что заголовок находится в<head>
разделе, который находится в первых нескольких байтах файла, это не оптимально. Лучший подход, если GNUawk
доступен в вашей системе, может быть:Таким образом, awk прекращает чтение после первого
</title
и, выйдя, вызываетwget
остановку загрузки.Разбор HTML
Здесь
wget
пишет страницу, как она загружает его. В то же время,perl
slus свой output (-0777 -n
) целиком в памяти, а затем печатает HTML-код, найденный между первыми вхождениями<title...>
и</title
.Это будет работать для большинства HTML-страниц, имеющих
<title>
тег, но в некоторых случаях это не сработает.В отличие от этого решение coffeeMug будет анализировать HTML-страницу как XML и возвращать соответствующее значение для
title
. Более правильно, если на странице гарантированно указан правильный XML . Тем не менее, HTML не обязательно должен быть действительным XML (более ранние версии языка не были), и поскольку большинство браузеров проявляют снисходительность и будут принимать неправильный HTML-код, существует даже много неправильного HTML-кода.И моё решение, и CoffeeMug не удастся для разных угловых случаев, иногда одинаковых, иногда нет.
Например, у меня не получится:
или же:
Пока его не получится
(действительный HTML, а не XML) или:
или же:
(опять же, допустимые
html
, недостающие<![CDATA[
части, чтобы сделать его действительным XML).(неверный html, но все еще обнаруживается и поддерживается большинством браузеров)
интерпретация кода внутри тегов.
Это решение выводит необработанный текст между
<title>
и</title>
. Обычно там не должно быть никаких HTML-тэгов, там могут быть комментарии (хотя они не обрабатываются некоторыми браузерами, такими как Firefox, что очень маловероятно). Там все еще может быть некоторая кодировка HTML:О чем позаботится GNU
recode
:Но веб-клиент также предназначен для выполнения большего количества преобразований в этом коде при отображении заголовка (например, сжатие некоторых пробелов, удаление начальных и конечных). Однако вряд ли в этом будет необходимость. Так что, как и в других случаях, вам решать, стоит ли это усилий.
Набор символов
До UTF-8 iso8859-1 раньше был предпочтительным набором символов в сети для символов, не относящихся к ASCII, хотя, строго говоря, они должны были быть записаны как
é
. Более поздние версии HTTP и язык HTML добавили возможность указывать набор символов в заголовках HTTP или в заголовках HTML, и клиент может указывать кодировки, которые он принимает. UTF-8 сегодня является набором символов по умолчанию.Таким образом, это означает , что там, вы найдете
é
написанные , какé
, такé
как UTF-8é
, (0xC3 0xa9), в ISO-8859-1 (0xe9), с за 2 последних из них, иногда информацию о кодировке в заголовках HTTP или в заголовках HTML (в разных форматах), иногда нет.wget
он получает только необработанные байты, не заботится об их значении в качестве символов и не сообщает веб-серверу о предпочтительной кодировке.recode html..
позаботится о том, чтобы преобразоватьé
илиé
в правильную последовательность байтов для набора символов, используемого в вашей системе, но в остальном это сложнее.Если ваша системная кодировка UTF-8, скорее всего, в большинстве случаев она будет в порядке, так как обычно она используется по умолчанию.
Это
é
выше было UTF-8é
.Но если вы хотите прикрыть другие кодировки, еще раз об этом нужно позаботиться.
Следует также отметить, что это решение не будет работать вообще для страниц в кодировке UTF-16 или UTF-32.
Подводить итоги
В идеале, то, что вам нужно здесь, это настоящий веб-браузер, чтобы дать вам информацию. То есть вам нужно что-то сделать для HTTP-запроса с правильными параметрами, правильно интерпретировать HTTP-ответ, полностью интерпретировать HTML-код, как браузер, и вернуть заголовок.
Поскольку я не думаю, что это можно сделать в командной строке с браузерами, которых я знаю (хотя теперь посмотрите на этот трюк
lynx
), вам придется прибегнуть к эвристике и аппроксимациям, и приведенный выше вариант хорош как любой.Вы также можете принять во внимание производительность, безопасность ... Например, чтобы охватить все случаи (например, веб-страницу, на которой есть некоторый JavaScript, извлеченный из стороннего сайта, который устанавливает заголовок или перенаправляет на другую страницу в onload hook), вам, возможно, придется реализовать реальный браузер с его механизмами dom и javascript, которым, возможно, придется выполнять сотни запросов для одной HTML-страницы, некоторые из которых пытаются использовать уязвимости ...
Хотя использование регулярных выражений для анализа HTML часто вызывает недовольство , здесь приведен типичный случай, когда этого достаточно для выполнения задачи (IMO).
источник
<
поскольку заголовки не обязательно имеют конечные теги, а любой другой тег должен принудительно завершать его. Вы также можете удалить новые строки.Вы также можете попробовать
hxselect
(из HTML-XML-Utils )wget
следующим образом:Вы можете установить
hxselect
в дистрибутивах на основе Debian с помощью:sudo apt-get install html-xml-utils
.STDERR перенаправление, чтобы избежать
Input is not well-formed. (Maybe try normalize?)
сообщения.Чтобы избавиться от «- YouTube», перенаправьте вывод команды выше
awk '{print substr($0, 0, length($0)-10)}'
.источник
sudo apt-get install html-xml-utils
hxselect
.brew install html-xml-utils
.Вы также можете использовать
curl
иgrep
сделать это. Вам необходимо заручиться использование PCRE (Perl Compatible Regular Expressions) в ,grep
чтобы получить вид сзади и вид впереди объектов , так что мы можем найти<title>...</title>
метки.пример
подробности
В
curl
выключателях:-s
= тихий-o -
= отправить вывод в STDOUTВ
grep
выключателях:-i
= нечувствительность к регистру-o
= Вернуть только ту часть, которая соответствует-P
= Режим PCREШаблон для
grep
:(?<=<title>)
= искать строку, которая начинается с этого слева от него(?=</title>)
= искать строку, которая заканчивается этим справа от него(.*)
= Все между ними<title>..</title>
.Более сложные ситуации
Если
<title>...</titie>
охватывает несколько строк, то выше не найдет его. Вы можете смягчить эту ситуацию с помощьюtr
, чтобы удалить любые\n
символы, то естьtr -d '\n'
.пример
Образец файла.
И пример прогона:
языки = ...
Если
<title>
установлено так,<title lang="en">
то вам нужно удалить это передgrep
его использованием. Инструментsed
может быть использован для этого:Выше находит строку без учета регистра,
lang=
за которой следует слово sequence (\w+
). Это тогда раздето.Настоящий HTML / XML Parser - с использованием Ruby
В какой-то момент регулярное выражение не сможет решить эту проблему. Если это произойдет, вы, вероятно, захотите использовать настоящий анализатор HTML / XML. Одним из таких парсеров является Nokogiri . Он доступен в Ruby как Gem и может использоваться следующим образом:
Выше анализирует данные, которые поступают через
curl
как HTML (Nokogiri::HTML
). Затем методxpath
ищет узлы (теги) в HTML, которые являются конечными узлами (//
) с именемtitle
. Для каждого найденного мы хотим вернуть его содержимое (e.content
).puts
Затем печатает их.Настоящий HTML / XML Parser - с использованием Perl
Вы также можете сделать нечто подобное с Perl и модулем HTML :: TreeBuilder :: XPath .
Затем вы можете запустить этот скрипт так:
источник
<title>Unix\nLinux</title>
должно бытьUnix Linux
, нетUnixLinux
.Использование простого регулярного выражения для разбора HTML наивно. Например, с символами новой строки и игнорированием специальной кодировки символов, указанной в файле. Делайте правильные вещи и действительно анализируйте страницу, используя любой из других реальных парсеров, упомянутых в других ответах, или используйте следующий вкладыш:
(Выше приведен символ Unicode).
BeautifulSoup также обрабатывает много неправильных HTML (например, отсутствующих закрывающих тегов), что полностью исключает упрощенное регулярное выражение. Вы можете установить его в стандартном Python, используя:
или, если у вас нет
pip
, сНекоторые операционные системы, такие как Debian / Ubuntu, также имеют
python-bs4
пакет ( пакет в Debian / Ubuntu).источник
bs4
отсутствует в стандартной библиотеке Python. Вы должны установить его с помощьюeasy_install beautfulsoup4
(неeasyinstall bs4
).Может быть, это «обман», но один из вариантов - pup, анализатор HTML командной строки .
Вот два способа сделать это:
Использование
meta
поля сproperty="og:title
атрибутоми другой способ, используя
title
поле напрямую (а затем обрезая- YouTube
строку в конце).источник
--plain
опцию щенка .Кажется, это возможно с
lynx
использованием этого трюка (zsh
,bash
синтаксис):Поскольку это реальный веб-браузер, он не страдает от многих ограничений, которые я упоминал в своем другом ответе .
Здесь мы используем тот факт , что
lynx
устанавливает$LYNX_PRINT_TITLE
переменную среды в заголовок текущей страницы при печати страницы.Выше мы даем файл конфигурации (как канал), который определяет вызываемый lynx «принтер»,
P
который просто выводит содержимое этой переменной в файловый дескриптор3
(этот файловый дескриптор перенаправляется в стандартныйlynx
вывод с, в3>&1
то время как сам lynx stdout перенаправляется сам по себе). в / dev / null).Затем мы используем средства
lynx
сценариев для имитации нажатия клавиш пользователемp
, а такжеEnd
(он же select) иEnter
(^J
).-accept_all_cookies
в противном случае lynx будет запрашивать у пользователя подтверждение для каждого файла cookie.источник
Простой способ:
Несколько альтернатив:
источник
Мне понравилась идея Стефана Шазеласа использовать Lynx и LYNX_PRINT_TITLE, но этот скрипт не работал для меня под Ubuntu 14.04.5.
Я сделал его упрощенную версию, используя Lynx и предварительно настроенные файлы.
Добавьте следующую строку в /etc/lynx-cur/lynx.cfg (или там, где находится ваш lynx.cfg):
Эта строка указывает сохранить заголовок во время печати в «/home/account/title.txt» - вы можете выбрать любое имя файла, которое пожелаете. Вы запрашиваете ОЧЕНЬ большие страницы, увеличьте указанное выше значение с «1000» до любого количества строк на странице, которое хотите, в противном случае Lynx выдаст дополнительный запрос «при печати документа, содержащего очень большое количество страниц».
Затем создайте файл /home/account/lynx-script.txt со следующим содержимым:
Затем запустите Lynx, используя следующие параметры командной строки:
После выполнения этой команды будет создан файл /home/account/title.txt с заголовком вашей страницы.
Короче говоря, здесь есть функция PHP, которая возвращает заголовок страницы на основе заданного URL-адреса или false в случае ошибки.
источник
Используя nokogiri, можно использовать простой запрос на основе CSS для извлечения внутреннего текста тега:
Аналогично, чтобы извлечь значение атрибута «content» тега:
источник