2009-02-08 8 views
1

google.com에서 링크를 추출하고 싶습니다. 내 HTML 코드는 다음과 같습니다.정규식을 사용하여 HTML에서 링크를 어떻게 추출합니까?

<a href="http://www.test.com/" class="l" 

www.rubular.com을 사용하는 정규식을 찾으려면 약 5 분이 걸렸습니다. 때문이다 :,

require "open-uri" 
url = "http://www.google.com/search?q=ruby" 

source = open(url).read() 
links = source.scan(/"(.*?)" class="l"/) 

links.each { |link| puts #{link} 
} 

문제는이 웹 사이트 링크를 출력되지 않습니다 :

"(.*?)" class="l" 

코드입니다.

답변

0

무엇이 잘못 되었나요?

HTML을 정규식으로 구문 분석하려고합니다. 그러지 마. 정규 표현식은 실제 XHTML 태그 스프를 제외하고 유효한 XHTML로 허용되는 구문의 범위를 포함 할 수 없습니다. Hpricot과 같은 HTML 구문 분석기 라이브러리를 사용하십시오.

FWIW, 'http://www.google.com/search?q=ruby'을 가져 오면 반환 된 마크 업에서 'class = "l"'을받지 못합니다. 아마도 귀하가 사용중인 로컬 Google 및 로그인 여부 또는 Google 쿠키가 있는지에 따라 달라질 수 있습니다. (나와 같은 스크립트는 그렇지 않습니다.)

+0

글쎄, 그래. 그것도. HTML 파서는 이것에 훨씬 낫다. –

4

링크는 실제로 class=l이 아니며 class="l"입니다. 그런데이 그림을 그리기 위해 메서드에 일부 로깅을 추가하여 다양한 단계에서 출력을보고 디버깅 할 수있게했습니다. 찾으려는 문자열을 찾고 찾지 못했습니다. 그래서 정규 표현식이 실패한 것입니다. 그래서 당신이 실제로 원하는 문자열을 찾고 그에 따라 정규식을 변경했습니다. 디버깅 기술은 편리합니다.

require "open-uri" 
url = "http://www.google.com/search?q=ruby" 

source = open(url).read 

puts "--- PAGE SOURCE ---" 
puts source 

links = source.scan(/<a.+?href="(.+?)".+?class=l/) 

puts "--- FOUND THIS MANY LINKS ---" 
puts links.size 

puts "--- PRINTING LINKS ---" 
links.each do |link| 
    puts "- #{link}" 
end 

정규 표현식도 향상되었습니다. 당신은 a 태그 (<a)의 여는 것으로 시작하는 텍스트를 찾고, 당신이 신경 쓰지 않는 어떤 종류의 문자들 (.+?), href 속성 (href="), 원하는 href 속성의 내용 ((.+?)), 일부 공백이나 다른 속성 (.+?), 그리고 마지막으로 클래스 abrubute (class=l).

나는 세 곳에서 .+?입니다. .은 모든 문자를 의미하며 +은 바로 앞에 하나 이상의 내용이 있어야 함을 의미하고 ?.+이 가능한 짧은 문자열로 일치해야 함을 의미합니다.

2

뻔뻔스럽게 말하면 문제는 정규식을 사용하고 있다는 것입니다. 문제는 HTML이 context-free language으로 알려져 있고 정규 표현식은 regular languages으로 알려진 언어 클래스 일 수 있다는 것입니다.

당신이해야 할 일은 Hpricot과 같은 HTML 코드를 처리 할 수있는 파서로 페이지 데이터를 보낸 다음 파서에서 파스 트리를 가져 오는 것입니다.

관련 문제