grep 및 cut in script를 사용하여 HTML 파일에서 웹 사이트 URL을 얻는 방법


21

grep을 사용하여 HTML 파일에서 URL을 추출하려고합니다. 링크는 다음과 같습니다.

<a href="http://examplewebsite.com/">

다른 웹 사이트가있다 .net, .gov그러나 나는 바로 전에 오프 포인트 컷을 만들 수있는 가정합니다 >. 그래서 grep을 사용하고 http 및 .com 이후의 모든 것을 차단하기 위해 어떻게 든 잘라낼 수 있다는 것을 알고 있지만 잠시 동안 붙어 있습니다.


편집했습니다. 일부는 <와 a 사이의 공백을 무시하면 HTML이 없으면 표시되지 않습니다. 그것을 잡아 주셔서 감사합니다!
eltigre

코드 형식을 사용하십시오 (텍스트를 선택하고 Ctrl-K를 누름). 그렇지 않으면 <>강제로 HTML 태그로 표시됩니다.
muru

href 매개 변수의 시작 및 끝 따옴표와 일치하지 않는 이유는 무엇입니까? 게다가, 정규 표현식이 html에 가장 적합하지 않다고 생각합니다.
把 友情 留 在 无 盐

특히 grep을 사용하여 명령을 작성하고 잘라 내고 싶습니다. 다른 방법이 있다는 것을 알고 있지만 그 방법에 대해 알고 싶었습니다.
eltigre

9
일반적으로 HTML은 정규 언어가 아니므로 HTML을 정규 표현식으로 구문 분석하는 것은 좋지 않습니다. 당신이 할 수있는 경우 보장 되는 HTML 당신이있는 거 구문 분석이 매우 간단하다는하고 추출하려는 물건 예측 당신은 할 수 그것으로 멀리 얻을 수. 그러나 stackoverflow.com/a/1732454/4014959
PM 2Ring

답변:


25

필자의 의견에서 말했듯이 일반적으로 정규 표현식으로 HTML을 구문 분석하는 것은 좋지 않지만 구문 분석하는 HTML이 제대로 작동하면 때로는 HTML을 피할 수 있습니다.

요소 href속성 에있는 URL 만 가져 오려면 <a>여러 단계로 수행하는 것이 가장 쉽다는 것을 알게되었습니다. 의견에서 전체 URL이 아닌 최상위 도메인 만 원하는 것 같습니다. 이 경우 다음과 같은 것을 사용할 수 있습니다.

grep -Eoi '<a [^>]+>' source.html |
grep -Eo 'href="[^\"]+"' | 
grep -Eo '(http|https)://[^/"]+'

source.html구문 분석 할 HTML 코드가 포함 된 파일은 어디에 있습니까 ?

이 코드는 각 줄 href에있는 <a>요소 의 속성으로 발생하는 모든 최상위 URL을 인쇄합니다 . -i첫 번째 grep명령 의 옵션 은 요소 <a><A>요소 모두에서 작동하도록하는 것입니다 . 대문자 속성 인 OTOH 를 캡처 -i하기 위해 2nd grep에 줄 수도 있다고 생각 HREF합니다. OTOH는 그런 깨진 HTML을 무시하고 싶습니다. :)

내용을 처리하려면 http://google.com/

wget -qO- http://google.com/ |
grep -Eoi '<a [^>]+>' | 
grep -Eo 'href="[^\"]+"' | 
grep -Eo '(http|https)://[^/"]+'

산출

http://www.google.com.au
http://maps.google.com.au
https://play.google.com
http://www.youtube.com
http://news.google.com.au
https://mail.google.com
https://drive.google.com
http://www.google.com.au
http://www.google.com.au
https://accounts.google.com
http://www.google.com.au
https://www.google.com
https://plus.google.com
http://www.google.com.au

호주 Google 페이지로 리디렉션되는 결과는 다른 예제와 약간 다릅니다.


고맙습니다. 이것이 바로 내가 찾던 것입니다. 가장 깨끗한 방법입니다.
eltigre

@eltigre : 나의 기쁨! 그러나 위의 의견에서 내가 연결 한 경고에 유의하십시오. :)
PM 2Ring

나는 쉬운 점을 기대하면서이 질문에 도달했다. 그리고 당신은 이미 머리에 못을 박
Mark K Cowan

감사합니다, @MarkKCowan. :) FWIW, 나는 원래 awk를 사용하여 답변을 작성하기 시작했지만 grep 기반 솔루션이 awk에 익숙하지 않은 사람들에게는 이해하기 쉽다고 결정했습니다. 어쨌든 위의 코드는 내 awk 코드보다 짧습니다.
PM 2Ring

2
@mavavilj : OP는 최상위 도메인 만 원했기 때문에 ://첫 번째 /또는 앞에있는 문자 만 허용 "합니다. 그러나 전체 URL을 보려면 해당 명령을로 변경하십시오 grep -Eo '(http|https)://[^"]+. 해당 줄의 다른 옵션은 grep -Eo '(http|https)://[^?"]+'쿼리 옵션을 차단하는 것입니다. 그러나이 변형은 다른 URL에 포함 된 URL을 쿼리 매개 변수로 계속 인쇄하지만 별도의 행에 인쇄됩니다.
PM 2Ring

25

도구에 제한이 있는지 확실하지 않은 경우 :

그러나 정규 표현식이 언급 된 것처럼 갈 수있는 가장 좋은 방법은 아니지만 다음은 내가 함께 한 예입니다.

cat urls.html | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
  • grep -E : egrep과 동일
  • grep -o : 그렙 된 내용 만 출력
  • (http | https) : / 또는
  • az : 모두 소문자
  • AZ : 모든 경우입니다
  • . : 도트
  • \ ?: 무엇입니까?
  • * : [...] 그룹을 반복합니다
  • uniq : 중복을 제거합니다

산출:

bob@bob-NE722:~s$  wget -qO- https://stackoverflow.com/ | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
https://stackauth.com
https://meta.stackoverflow.com
https://cdn.sstatic.net/Img/svg-icons
https://stackoverflow.com
https://www.stackoverflowbusiness.com/talent
https://www.stackoverflowbusiness.com/advertising
https://stackoverflow.com/users/login?ssrc=head
https://stackoverflow.com/users/signup?ssrc=head
https://stackoverflow.com
https://stackoverflow.com/help
https://chat.stackoverflow.com
https://meta.stackoverflow.com
...

\d다른 숫자 유형을 잡기 위해 추가 할 수도 있습니다 .


2
IRI 정규식! 그중 하나를 사용하고 OP를 두려워하십시오! :)
muru

2
@muru ... 떨고 ... 나는 무엇을 말 해야할지 모르겠다. 저 사람들도 진짜입니까?
jmunsch

4
@jmunsch, uniq는 인접한 복제본을 제거합니다. sort -u?
JJoao

1
대단한 답변입니다!
Gery

@JJoao는 파이프보다 정렬 -u의 소스입니까? 그냥 생각 실험, id 봐야합니다. 그러나 쉘 미들웨어에 대해서는 아마 옳을 것입니다.
jmunsch

9

grep이 Perl 정규식을 지원하는 경우 :

grep -Po '(?<=href=")[^"]*(?=")'
  • (?<=href=")하고 (?=")있는 lookaround 에 대한 표현 href속성. -P옵션 이 필요합니다 .
  • -o 일치하는 텍스트를 인쇄합니다.

예를 들면 다음과 같습니다.

$ curl -sL https://www.google.com | grep -Po '(?<=href=")[^"]*(?=")'
/search?
https://www.google.co.in/imghp?hl=en&tab=wi
https://maps.google.co.in/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
https://www.youtube.com/?gl=IN&tab=w1
https://news.google.co.in/nwshp?hl=en&tab=wn
...

평소와 같이이 URL이 유효한 URI이거나 구문 분석중인 HTML이 유효하다는 보장은 없습니다.


8

A와 비 정규식 대체 를 사용 강아지 :

pup 'a[href] attr{href}' < yourfile.html

속성 a이있는 모든 요소를 찾은 href다음 속성 값을 표시 href합니다.

를 설치하려면 pupGo (프로그래밍 언어)가 필요합니다.

sudo apt-get install golang
sudo go get github.com/ericchiang/pup

이 솔루션의 장점은 HTML의 형식이 적절하지 않다는 것 입니다.


1
+1 pup, 설치 시간 ....
Mark K Cowan

파일로도 넣을 수 있습니다. pup 'a.classname[href] attr{href}' < tut.html >links.md
Ahmad Awais

1

여기 에서 제안 된 것보다 훨씬 간단하고 잠재적으로 더 빠른 IMHO 솔루션을 찾았 습니다. https 파일을 지원하도록 약간 조정했습니다. 그러나 TD; TR 버전은 ...

추신 : 사이트 URL을 파일 경로로 바꿀 수 있으며 동일한 방식으로 작동합니다.

lynx -dump -listonly -nonumbers "http://www.goggle.com" > links.txt

lynx -dump -listonly -nonumbers "some-file.html" > links.txt

링크를 파일에 배치하는 대신 링크를 보려면 대신 시도하십시오 ...

lynx -dump -listonly -nonumbers "http://www.google.com"

lynx -dump -listonly -nonumbers "some-file.html"

결과는 다음과 유사합니다 ...

http://www.google.ca/imghp?hl=en&tab=wi
http://maps.google.ca/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?gl=CA&tab=w1
http://news.google.ca/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
https://www.google.ca/intl/en/options/
http://www.google.ca/history/optout?hl=en
...
etc.

내 유스 케이스의 경우 이것은 잘 작동했습니다. 그러나 요즘 사람들은 라이브러리의 CDN URI에 src = "// blah.tld"와 같은 링크를 추가한다는 사실에주의하십시오. 검색 된 링크에있는 것을보고 싶지 않았습니다.

"lynx -dump"는 기본적으로 주어진 페이지에서 클릭 가능한 모든 링크를 추출하기 때문에 href 또는 다른 소스의 링크를 확인할 필요가 없습니다. 따라서 그 후에해야 할 유일한 생각은 grep을 사용하여 "lynx -dump"의 결과를 구문 분석하여 동일한 결과의 더 깨끗한 원시 버전을 얻는 것입니다.


하지만 문제는 말한다 "는 HTML에서 추출 된 URL 파일 [그 모습]처럼"(예), NOT "웹 페이지에서 추출 된 URL". 로컬 컴퓨터에있는 파일에 대한 답변을 사용할 수있는 경우 방법을 설명하십시오. 의견에 응답하지 마십시오. 명확하고 완전하게 답변을 편집 하십시오.
G-Man, 'Reinstate

1
URL을 파일 이름으로 바꿀 수 있습니다.
asiby

@ G-Man, 왜 -1? 코드를 직접 시도하고 로컬 파일에서도 작동하는지 확인해야합니다. 명확하지 않은 경우를 위해 그 설명을 추가했습니다.
asiby

이것은 정말 편리합니다 .. xargs와 함께 사용하는 경우 추가 가치가 있습니다 | 정렬 | 중복 링크를 제거하려면 uniq.
스튜어트 Axon

0
wget -qO- google.com |
tr \" \\n | grep https\*://

... 아마 잘 될 것입니다. 작성된대로 다음을 인쇄합니다.

http://schema.org/WebPage
http://www.google.com/imghp?hl=en&tab=wi
http://maps.google.com/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?tab=w1
http://news.google.com/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
http://www.google.com/intl/en/options/
http://www.google.com/history/optout?hl=en
https://accounts.google.com/ServiceLogin?hl=en&continue=http://www.google.com/
https://www.google.com/culturalinstitute/project/the-holocaust?utm_source=google&amp;utm_medium=hppromo&amp;utm_campaign=auschwitz_q1&amp;utm_content=desktop
https://plus.google.com/116899029375914044550

링크 만 일치시키고 최상위 도메인 중 하나만 연결해야하는 경우 다음을 수행 할 수 있습니다.

wget -qO- google.com |
sed '/\n/P;//!s|<a[^>]*\(https*://[^/"]*\)|\n\1\n|;D'

... 또는 그와 비슷한 것-일부 sed\n경우 마지막 두 개의 문자 로 리터럴 ewline 문자 를 대체해야 할 수도 있습니다 n.

작성된대로 위 명령은 다음을 인쇄합니다.

http://www.google.com
http://maps.google.com
https://play.google.com
http://www.youtube.com
http://news.google.com
https://mail.google.com
https://drive.google.com
http://www.google.com
http://www.google.com
http://www.google.com
https://www.google.com
https://plus.google.com

... 어쨌든 (후자의 경우 가장 유용 할 수 있음 )|sort -u 필터를 끝까지 사용하여 목록을 가져 sort오고 중복 항목을 삭제할 수 있습니다.



-1
echo "<a href="http://examplewebsite.com/">"|sed -r 's:<.*"::g'|sed 's:/">$::g'

나는 그 "똑똑한"인용구가 당신이 의도 한 것 (정규적인 "더블"인용구)인지 확실하지 않다?
Jeff Schaller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.