2016-08-28 1 views
1

일부 text<html> 태그 외부에있는 문서로 작업하고 있습니다. 본문 안의 데이터를 읽을 때 html 태그에도없는 텍스트를 반환합니다.xpath가 html 태그 외부로 텍스트를 반환하는 이유는 무엇입니까?

page_text = Nokogiri::HTML(open(file_path)).xpath("//body").text 
p page_text 

출력 :

"WARC/1.0\nWARC-Type: response\nWARC-Date: 2012-02-11T04:48:01Z\nWARC-TREC-ID: clueweb12-0000tw-13-04988\nWARC-IP-Address: 184.85.26.15\nWARC-Payload-Digest: sha1:PNCB5NNAA766RLLISZ6ODV3FJZBCATKR\nWARC-Target-URI: http://www.allchocolate.com/health/basics/\nWARC-Record-ID: \nContent-Type: application/http; msgtype=response\nContent-Length: 14577\n\n\n\n\n sample document\n\n\n hello world\n\n"

문서 :

WARC/1.0 
WARC-Type: response 
WARC-Date: 2012-02-11T04:48:01Z 
WARC-TREC-ID: clueweb12-0000tw-13-04988 
WARC-IP-Address: 184.85.26.15 
WARC-Payload-Digest: sha1:PNCB5NNAA766RLLISZ6ODV3FJZBCATKR 
WARC-Target-URI: http://www.allchocolate.com/health/basics/ 
WARC-Record-ID: <urn:uuid:ff32c863-5066-4f51-802a-f31d4af074d5> 
Content-Type: application/http; msgtype=response 
Content-Length: 14577 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <title>sample document</title> 
</head> 
<body> 
    hello world 
</body> 
</html> 
+1

"[mcve]"을 (를) 읽으십시오. 이미지를 사용하여 예상 출력을 표시하지 마십시오. 링크 썩어 다음 휴식 시간에 귀하의 질문을 이해하지 않습니다. 대신 정보를 질문에 복사하여 붙여넣고 가독성을 위해 적절하게 형식을 지정하십시오. Nokogiri로 전달하기 전에 원본에서 HTML이 아닌 부분을 제거해야합니다. 헤더 정보가 무엇인지 모르기 때문에 혼란 스러울뿐입니다. –

+0

@ theTinMan 제안 해 주셔서 감사합니다. 제 질문을 수정했습니다. – Abdullah

답변

1

분명히 선행 텍스트가 문제이지만, 텍스트를 후행 없습니다. XML은 고도로 구조화 된 언어이며 XML 구문 분석기를 HTML에 적용한다는 것은 최소한 유효한 HTML을 가져야한다는 것을 의미합니다. 유효한 HTML이 없다면 Nokogiri가 뱉어내는 모든 것을 얻을 수 있습니다.

그것은 노코 기리가 기본 루트 노드 전체를 감싸는 것처럼 다음, 나에게 보이는 본질적으로 //body XPath를 무시하고, 거기에 모든 텍스트 노드를 반환합니다. 흥미롭게도 div에 텍스트를 포함하고 xpath //div을 검색하면 아무런 문제가 없으므로 해결책을 제안 할 수 있습니다.

Nokogiri가 //body이 루트 노드와 같다고 생각합니다. 아! 어쩌면 Nokogiri는 루트 노드에 <body>을 사용합니다. 아니요 : xpath /body//body이 작동하지 않습니다.

응답 언급합니다 :

그런 다음 div 태그를 삽입 <body> 태그를 검색 할 정규식을 사용할 수 있습니다. 하지만 간단한 정규 표현식으로 html을 검색하는 것은 쉬운 해결책이 될 수 없으며 모든 경우에 작동하지는 않습니다. 안녕하세요 세계, 모든 노드를 인쇄 노코 기리 발견 :

require 'nokogiri' 

nodes = Nokogiri::HTML(open('html.html')).xpath('//*') 

nodes.each do |node| 
    puts node.name 
end 

--output:-- 
html 
body 
p 

그래서 노코 기리을 그런데

, 당신은 노코 기리 만 텍스트가 문서를 분석하여 태그 이외의 텍스트를 처리하는 방법을 볼 수 있습니다 3 개의 태그로 텍스트를 래핑합니다.

는 또는 더 나은 아직, 당신은 문서를 구문 분석하고 HTML로 인쇄 할 수 있습니다 :이 같은 hello world을 얻을 수 있다는 것을 의미

require 'nokogiri' 

doc = Nokogiri::HTML(open('./html.html')) 
puts doc.to_html 

--output:-- 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html><body><p>WARC/1.0 
WARC-Type: response 
WARC-Date: 2012-02-11T04:48:01Z 
WARC-TREC-ID: clueweb12-0000tw-13-04988 
WARC-IP-Address: 184.85.26.15 
WARC-Payload-Digest: sha1:PNCB5NNAA766RLLISZ6ODV3FJZBCATKR 
WARC-Target-URI: http://www.allchocolate.com/health/basics/ 
WARC-Record-ID: <uuid:ff32c863-5066-4f51-802a-f31d4af074d5> 
Content-Type: application/http; msgtype=response 
Content-Length: 14577 




    <title>sample document</title> 


    hello world 


</uuid:ff32c863-5066-4f51-802a-f31d4af074d5></p></body></html> 

은 :

require 'nokogiri' 

doc = Nokogiri::HTML(open('./html.html')) 
title = doc.at_xpath('//title') 
puts title.next.text.strip 

--output:-- 
hello world 

또 다른 방법은 없애입니다 Nokogiri와 구문 분석하기 전에 비 -HTML 콘텐츠의 :

require 'nokogiri' 

infile = File.open('html.html') 
non_html = infile.gets(sep="\n\n") 
html = infile.gets(nil) #Slurp the rest of the file 

doc = Nokogiri::HTML(html) 
puts doc.at_xpath('//body').text.strip 

--output:-- 
hello world 

HTML 컨텐트와 비 -HTML 컨텐트를 구분하는 빈 줄은 항상 여기에 있습니다.

+0

그래서 해결책은 무엇입니까? – Abdullah

+0

내 답변에 대한 추가 사항을 확인하십시오. – 7stud

2

Nokogiri는 파일 ​​내용을 HTML 문서로 구문 분석하려고하지만 올바른 문서가 아닙니다. 이것은 HTML 문서에 들어있는 텍스트 문서입니다. 물론 Nokogiri는이 사실을 모르고 있으며, HTML 자체로 그 부분을 골라 낼 수 없기 때문에 모든 것을 파싱하려고합니다. 유효한 HTML이 아니므로 오류가 발생합니다.

Nokogiri가 분석 할 수있는 한 최선을 다해 오류를 수정하려고 시도하지만,이 경우에는 작동하지 않으므로 여기에서 볼 수있는 이상한 결과가 나타납니다.

특히 Nokogiri가 HTML 앞의 텍스트를 볼 때 HTML 텍스트 본문에 포함되어야한다고 가정합니다. 따라서 body의 하위 항목으로 텍스트를 추가하기 전에 htmlbody 요소를 만들고 삽입합니다.

나중에 실제 <body> 태그가 표시되지만 이미 body 요소가 있고 그 중 하나만있을 수 있으므로 무시합니다.

유효 HTML 만 제공하면됩니다 (오류 수정으로 작은 문제를 해결할 수 있음). 처음에는 여분의 텍스트를 제거하기 위해 파일을 사전 처리해야 할 수 있습니다.

1

우선 @ 7stud 대답은 \n\n에 파일을 깰 수 있지만 내 문서 수집에 파일을 깨뜨릴 수 있다는 점에서 실제 html 코드보다 항상 \n\n이 아닙니다.

따라서 동일한 아이디어를 사용하여 html 시작 태그 앞에 regex를 사용하여 모든 텍스트를 제거한 다음이를 Nokogiri (으)로 전달하여 구문 분석하는 다른 해결 방법이 있습니다.

file = File.read(file_path).to_s 
file = file.sub(/.*?(?=<html)/im,"") 
page = Nokogiri::HTML(file) 

이제 제대로 작동합니다.

0

이 내용 노코 기리에 전달하기 전에 사전 처리로 간단합니다

require 'nokogiri' 

text = ' 
WARC/1.0 
WARC-Type: response 
WARC-Date: 2012-02-11T04:48:01Z 
WARC-TREC-ID: clueweb12-0000tw-13-04988 
WARC-IP-Address: 184.85.26.15 
WARC-Payload-Digest: sha1:PNCB5NNAA766RLLISZ6ODV3FJZBCATKR 
WARC-Target-URI: http://www.allchocolate.com/health/basics/ 
WARC-Record-ID: <urn:uuid:ff32c863-5066-4f51-802a-f31d4af074d5> 
Content-Type: application/http; msgtype=response 
Content-Length: 14577 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <title>sample document</title> 
</head> 
<body> 
    hello world 
</body> 
</html> 
' 

doc = Nokogiri::HTML(text[/<!DOCTYPE.+/m]) 
doc.to_html # => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <title>sample document</title>\n</head>\n<body>\n hello world\n</body>\n</html>\n" 

트릭은 다음과 같습니다 텍스트를 통해보고에 <!DOCTYPE에서 모든 텍스트를 반환하는 루비를 알려줍니다

text[/<!DOCTYPE.+/m] 

유효한 HTML 인 문자열의 끝.