명령 줄을 사용하여 웹 사이트 제목을 얻으려면 어떻게합니까? 줄 프로그램을 원합니다. 예를 들어 : Alan:~ titlefetcher

웹 사이트의 제목을 인쇄하는 명령 줄 프로그램을 원합니다. 예를 들어 :

Alan:~ titlefetcher http://www.youtube.com/watch?v=Dd7dQh8u4Hc

제공해야합니다 :

Why Are Bad Words Bad?

당신은 URL을 제공하고 제목을 인쇄합니다.



답변

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
  perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'

다음 recode과 같은 것이 있으면 GNU로 파이프 할 수 있습니다 &lt;.

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
  perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
  recode html..

- youtube부품 을 제거하려면

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)(?: - youtube)?\s*<\/title/si'

몇 가지 제한 사항을 지적하려면 다음을 수행하십시오.

이식성

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옵션을 사용하여 요청을 보내는 방식을 변경하도록 동작을 변경할 수 있습니다.

이와 관련하여 여기에서 가장 중요한 것은 다음과 같습니다.

  • AcceptAccept-language: 그 클라이언트의 응답을 얻을하고자하는 언어와 문자셋에 서버를 알려줍니다. wget서버는 일반적으로 기본 설정으로 보낼 수 있도록 기본적으로 하나를 전송하지 않습니다. firefox다른 쪽 끝에는 언어를 요청하도록 구성되어있을 수 있습니다.
  • User-Agent: 서버에 대한 클라이언트 응용 프로그램을 식별합니다. 일부 사이트는 클라이언트에 따라 다른 콘텐츠를 전송하지만 (대부분 자바 스크립트 언어 해석의 차이점이 있지만) 로봇 과 같은 사용자 에이전트를 사용하는 경우 서비스를 거부 할 수 있습니다 wget.
  • Cookie: 이전에이 사이트를 방문한 경우 브라우저에 영구 쿠키가있을 수 있습니다. wget하지 않을 것이다.

wget는 HTTP 프로토콜 수준에서 수행 될 때 리디렉션을 따르지만, 자바 스크립트 나 이와 같은 작업이 아닌 페이지의 내용을 보지 않기 때문입니다 <meta http-equiv="refresh" content="0; url=http://example.com/">.

성능 / 효율

게으름 perl에서 <title>태그 를 찾기 전에 메모리의 전체 내용을 읽었습니다 . 제목이 <head>파일의 처음 몇 바이트 에있는 섹션 에서 발견되면 최적이 아닙니다. awk시스템에서 GNU 를 사용할 수있는 경우 더 나은 방법 은 다음과 같습니다.

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
  gawk -v IGNORECASE=1 -v RS='</title' 'RT{gsub(/.*<title[^>]*>/,"");print;exit}'

그렇게하면 awk는 첫 번째 이후 읽기 를 중지 </title하고 종료하면 wget다운로드가 중지됩니다.

HTML 파싱

여기에서 wget다운로드 할 때 페이지를 씁니다. 동시에 perl, 그 출력 (slurps -0777 -n메모리) 전체를 후 제의 발생 사이에서 발견 된 HTML 코드 인쇄 <title...></title.

<title>태그 가있는 대부분의 HTML 페이지에서 작동 하지만 작동하지 않는 경우가 있습니다.

반대로 coffeeMug의 솔루션 은 HTML 페이지를 XML로 구문 분석하고에 해당하는 값을 반환합니다 title. 페이지가 유효한 XML임을 보증하는 것이 더 정확 합니다 . 그러나 HTML은 유효한 XML 일 필요는 없으며 (이전 버전의 언어는 그렇지 않았 음) 대부분의 브라우저는 관대하며 잘못된 HTML 코드를 허용하므로 잘못된 HTML 코드가 많이 있습니다.

내 솔루션과 coffeeMug 모두 다양한 경우에 대해 실패 할 수 있으며 때로는 동일하거나 때로는 그렇지 않습니다.

예를 들어, 광산은 실패합니다.

<html><head foo="<title>"><title>blah</title></head></html>

또는:

<!-- <title>old</title> --><title>new</title>

그의 의지가 실패하는 동안 :

<TITLE>foo</TITLE>

(XML이 아닌 유효한 HTML) 또는 :

또는:

<title>...</title>
...
<script>a='<title>'; b='</title>';</script>

(다시 유효 html하고 누락 된 <![CDATA[부분으로 XML을 유효하게 만듭니다).

<title>foo <<<bar>>> baz</title>

(잘못된 HTML이지만 여전히 거기에서 발견되어 대부분의 브라우저에서 지원됨)

태그 내부의 코드 해석

즉, 용액의 원료 텍스트 출력 <title></title>. 일반적으로 거기에 HTML 태그가 없어야하며 주석이있을 수 있습니다 ( firefox와 같은 일부 브라우저에서는 처리하지 않을 수도 있음 ). 여전히 일부 HTML 인코딩이있을 수 있습니다.

$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
  perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Wallace &amp; Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube

어느 것이 GNU에 의해 처리됩니까 recode?

$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
  perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
   recode html..
Wallace & Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube

그러나 웹 클라이언트는 제목을 표시 할 때 해당 코드에서 더 많은 변환을 수행해야합니다 (예 : 일부 공백을 압축하거나 앞뒤 공백을 제거). 그러나 그럴 필요는 없을 것입니다. 따라서 다른 경우와 마찬가지로 노력의 가치가 있는지 결정하는 것은 귀하의 몫입니다.

문자 세트

UTF-8 이전에는 iso8859-1 이 ASCII가 아닌 문자에 대해 웹 에서 선호하는 문자 세트로 사용 되었지만 엄격하게 말하면로 작성해야했습니다 &eacute;. 최신 버전의 HTTP 및 HTML 언어는 HTTP 헤더 또는 HTML 헤더에서 문자 세트를 지정할 수있는 가능성을 추가했으며 클라이언트는 허용되는 문자 세트를 지정할 수 있습니다. 오늘날 UTF-8은 기본 문자셋이되는 경향이 있습니다.

그래서, 당신이 찾을거야, 거기를 의미 é로 작성 &eacute;으로, &#233;UTF-8로 é, 2 마지막 것들에 대한로, ISO-8859-1 (0xe9)로, (0xc3의 0xa9) 캐릭터 세트에 때때로 정보를 때로는 다른 형식의 HTTP 헤더 또는 HTML 헤더에서.

wget 원시 바이트 만 가져오고 문자의 의미를 신경 쓰지 않으며 웹 서버에 선호하는 문자 집합에 대해 알려주지 않습니다.

recode html..시스템에서 사용되는 문자 집합에 대해 &eacute;또는 &#233;적절한 바이트 시퀀스로 변환하도록주의를 기울이지 만 나머지는 더 까다 롭습니다.

시스템 문자셋이 utf-8이라면, 오늘날 사용되는 기본 문자셋 인 경향이 있기 때문에 대부분 괜찮을 것입니다.

$ wget -qO- 'http://www.youtube.com/watch?v=if82MGPJEEQ' |
 perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Noir Désir - L&#39;appartement - YouTube

é위 UTF-8이었다 é.

그러나 다른 문자셋을 커버하려면 다시 한 번 처리해야합니다.

이 솔루션은 UTF-16 또는 UTF-32 인코딩 페이지에서는 전혀 작동하지 않습니다.

요약하자면

이상적으로, 여기에 필요한 것은 정보를 제공하는 실제 웹 브라우저입니다. 즉, 적절한 매개 변수를 사용하여 HTTP 요청을 수행하고 HTTP 응답을 올바르게 해석하고 HTML 코드를 브라우저처럼 완전히 해석 한 다음 제목을 반환해야합니다.

내가 아는 브라우저를 사용하여 명령 줄에서 수행 할 수 있다고 생각하지 않기 때문에 (지금은 이 트릭을lynx 참조하십시오 ) 휴리스틱과 근사에 의존해야하며 위의 것 중 어느 것이나 좋습니다.

성능, 보안 등을 고려해야 할 수도 있습니다. 예를 들어, 모든 경우 (예 : 타사 사이트에서 일부 자바 스크립트를 가져 와서 제목을 설정하거나 onload hook)와 같이 단일 HTML 페이지에 대해 수백 개의 쿼리를 수행해야하는 DOM 및 자바 스크립트 엔진으로 실제 브라우저를 구현해야 할 수 있습니다.

하지만 종종 눈살을 찌푸리게되는 HTML을 구문 분석 regexps ‘에를 사용하여 , 여기가 작업 (IMO)으로 충분 전형적인 경우이다.


답변

당신은 또한 시도 할 수 있습니다 hxselect(에서 HTML-XML-의 Utils 포함) wget은 다음과 같습니다 :

wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' | hxselect -s '\n' -c  'title' 2>/dev/null

다음을 hxselect사용하여 데비안 기반 배포판에 설치할 수 있습니다
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)}'.


답변

사용 curl하고 grep이를 수행 할 수도 있습니다 . 당신의 사용에 입대해야 PCRE (펄 호환 정규 표현식) 에서 grep우리가 찾을 수 있도록 시설을 뒤에 모양을 앞서 나갈보고 <title>...</title>태그를.

$ curl 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -so - | \
    grep -iPo '(?<=<title>)(.*)(?=</title>)'
Why Are Bad Words Bad? - YouTube

세부

curl스위치 :

  • -s = 침묵
  • -o - = STDOUT으로 출력 보내기

grep스위치 :

  • -i = 대소 문자 구분
  • -o = 일치하는 부분 만 반환
  • -P = PCRE 모드

패턴 grep:

  • (?<=<title>) = 왼쪽으로 시작하는 문자열을 찾으십시오.
  • (?=</title>) = 오른쪽으로 끝나는 문자열을 찾으십시오.
  • (.*)= 사이에있는 모든 것 <title>..</title>.

더 복잡한 상황

<title>...</titie>여러 줄에 걸쳐 있으면 위의 줄을 찾지 못합니다. 당신은 사용하여이 상황을 완화 할 수 tr있는 삭제, \n즉, 문자를 tr -d '\n'.

샘플 파일.

$ cat multi-line.html
<html>
<title>
this is a \n title
</TITLE>
<body>
<p>this is a \n title</p>
</body>
</html>

그리고 샘플 실행 :

$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
     tr -d '\n' | \
     grep -iPo '(?<=<title>)(.*)(?=</title>)'
this is a \n title

lang = …

<title>이 설정되어 있으면 넣기 <title lang="en">전에 제거해야 grep합니다. 이 도구 sed를 사용하여 다음을 수행 할 수 있습니다.

$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
     tr -d '\n' | \
     sed 's/ lang="\w+"//gi' | \
     grep -iPo '(?<=<title>)(.*)(?=</title>)'
this is a \n title

위는 대소 문자를 구분하지 않는 문자열 lang=과 단어 시퀀스 ( \w+)를 찾습니다 . 그런 다음 제거됩니다.

실제 HTML / XML 파서-Ruby 사용

어떤 시점에서 정규 표현식은 이러한 유형의 문제를 해결하지 못할 것입니다. 이 경우 실제 HTML / XML 파서를 사용하고 싶을 것입니다. 그러한 파서 중 하나는 Nokogiri 입니다. 루비에서 보석으로 사용할 수 있으며 다음과 같이 사용할 수 있습니다.

$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
    ruby -rnokogiri -e \
     'puts Nokogiri::HTML(readlines.join).xpath("//title").map { |e| e.content }'

this is a \n title

위는 curlHTML ( Nokogiri::HTML)을 통해 제공되는 데이터를 구문 분석합니다 . xpath그런 다음 이 메서드 는 HTML에서 리프 노드 인 노드 (태그)를 이름으로 찾습니다 ( //) title. 찾은 각각에 대해 내용 ( e.content) 을 반환하려고합니다 . 그런 puts다음 인쇄합니다.

실제 HTML / XML 파서-Perl 사용

Perl 및 HTML :: TreeBuilder :: XPath 모듈 과 비슷한 작업을 수행 할 수도 있습니다 .

$ cat title_getter.pl
#!/usr/bin/perl

use HTML::TreeBuilder::XPath;

$tree = HTML::TreeBuilder::XPath->new_from_url($ARGV[0]);
($title = $tree->findvalue('//title')) =~ s/^\s+//;
print $title . "\n";

그런 다음이 스크립트를 다음과 같이 실행할 수 있습니다.

$ ./title_getter.pl http://www.jake8us.org/~sam/multi-line.html
this is a \n title

답변

간단한 정규식을 사용하여 HTML을 구문 분석하는 것은 순진합니다. 예를 들어, 줄 바꿈 및 파일에 지정된 특수 문자 인코딩을 무시합니다. 옳은 일을하고 다른 답변에 언급 된 다른 실제 파서를 사용하여 페이지를 구문 분석하거나 다음 한 라이너를 사용하십시오.

python -c "import bs4, urllib2; print bs4.BeautifulSoup(urllib2.urlopen('http://www.crummy.com/software/BeautifulSoup/bs4/doc/')).title.text"

(위에는 유니 코드 문자가 포함되어 있습니다).

BeautifulSoup은 단순한 정규 표현식을 완전히 버릴 수있는 잘못된 HTML (예 : 닫는 태그 누락)을 많이 처리합니다. 다음을 사용하여 표준 파이썬으로 설치할 수 있습니다.

pip install beautifulsoup4

또는 당신이없는 경우 pip에,

easy_install beautifulsoup4

데비안 / 우분투와 같은 일부 운영 체제에서도 패키지로 제공됩니다 ( python-bs4데비안 / 우분투의 패키지).


답변

어쩌면 “속임수”일 수도 있지만 한 가지 옵션은 pup, 명령 줄 HTML 파서 입니다.

다음 두 가지 방법이 있습니다.

속성이 있는 meta필드 사용property="og:title

$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'meta[property=og:title] attr{content}'
Why Are Bad Words Bad?

다른 방법으로 title필드를 직접 사용 - YouTube하고 마지막에 문자열을 제거합니다 .

$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'title text{}' | sed 's/ - YouTube$//'
Why Are Bad Words Bad?

답변

lynx이 트릭 ( zsh, bash구문) 을 사용하면 가능 합니다.

lynx -cfg=<(printf '%s\n' 'PRINTER:P:printf "%0s\\n" "$LYNX_PRINT_TITLE">&3:TRUE'
  ) lynx 3>&1 > /dev/null -nopause -noprint -accept_all_cookies -cmd_script <(
    printf '%s\n' "key p" "key Select key" "key ^J" exit
  ) 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc'

그것이 실제 웹 브라우저이기 때문에 다른 답변 에서 언급 한 많은 제한이 없습니다 .

여기서는 페이지를 인쇄 할 때 환경 변수를 현재 페이지의 제목으로 lynx설정 하는 사실을 사용하고 $LYNX_PRINT_TITLE있습니다.

위, 우리라는 살쾡이 “프린터”를 정의 (파이프 등) 구성 파일을 제공하고 P단지 설명을 파일에 해당 변수의 내용을 출력 3(해당 파일 기술자로 재 lynx와의 표준 출력을 3>&1스라소니 표준 출력 자체가 리디렉션되는 동안 / dev / null로).

그런 다음 lynx스크립팅 기능을 사용하여 p, 및 End(일명 select) 및 Enter( ^J)를 누르는 사용자를 시뮬레이션합니다 .

-accept_all_cookies 그렇지 않으면 lynx는 사용자에게 모든 쿠키에 대한 확인을 요청합니다.


답변

간단한 방법 :

curl -s example.com | grep -o "<title>[^<]*" | tail -c+8

몇 가지 대안 :

curl -s example.com | grep -o "<title>[^<]*" | cut -d'>' -f2-
wget -qO- example.com | grep -o "<title>[^<]*" | sed -e 's/<[^>]*>//g'