2012-03-10 2 views
0
내가 거기에 문서의 톤이 거기 밖으로 토론 알고

을 테스트하지만, 동시에 :루비 1.9 문자 변환 오류가 여전히 정규식

이 다양한 웹 사이트에서 긁어 데이터를 테스트하기 위해 내 레일 시도 내 최고의 기회입니다. 이상한 사실은 내가 수동으로 URL의 소스를 복사하여 붙여 넣으면 모든 것이 올바르게 진행된다는 것입니다.

어떻게해야합니까?

# encoding: utf-8 

require 'rubygems' 
require 'iconv' 
require 'nokogiri' 
require 'open-uri' 
require 'uri' 

url = 'http://www.website.com/url/test' 

sio = open(url) 
@cur_encoding = sio.charset 
doc = Nokogiri::HTML(sio, nil, @cur_encoding) 
txtdoc = doc.to_s 

# 1) String manipulation test 
p doc.search('h1')[0].text # "Nove36  " 
p doc.search('h1')[0].text.strip! # nil <- ERROR 


# 2) Regex test 
# txtdoc = "test test 44.00 € test test" # <- THIS WORKS 
regex = "[0-9.]+ €" 


p /#{regex}/i =~ txtdoC# integer expected 

내가 실현이 아마 내 OS 우분투 플러스 내 텍스트 편집기는 아마 깨진 인코딩을 통해 좋은 인코딩 변환을하고있다 : 즉 괜찮지 만 라이브 실행하는 동안 어떻게 내 응용 프로그램에이 문제를 해결할 수 있습니까?

답변

2

이 페이지에서 줄 바꿈없는 공백 문자 (유니 코드 U + 00A0)에 의해 발생하는 데있어 문제점은. 첫 번째 문제에서

문자열 :

"Nove36 " 

실제로 제거 할 공백 수 있도록이 문자를 고려하지 않습니다 U + 00A0로 끝나는, 그리고 String#strip! :에서

1.9.3-p125 :001 > s = "Foo \u00a0" 
=> "Foo  " 
1.9.3-p125 :002 > s.strip 
=> "Foo  " #unchanged 

당신의 두 번째 문제는 가격과 유로화 사이의 공간이 다시 한번 비공개 공간이므로 정규 공간을 찾는 것처럼 정규 표현식은 단순히 일치하지 않습니다.

# s as before 
1.9.3-p125 :003 > s =~ /Foo/#2 spaces, no match 
=> nil 
1.9.3-p125 :004 > s =~ /Foo/#1 space, match 
=> 0 
1.9.3-p125 :005 > s =~ /Foo \u00a0/ #space and non breaking space, match 
=> 0 

원본을 복사하여 붙여 넣을 때 브라우저는 줄 바꿈하지 않는 공백을 정상적으로 처리하기 때문에 정상적인 공백 문자 만 복사하므로 그 방식으로 작동합니다.

sio = open(url) 
@cur_encoding = sio.charset 

txt = sio.read    #read the whole file 
txt.gsub! "\u00a0", " " #global replace 

doc = Nokogiri::HTML(txt, nil, @cur_encoding) #use this new string instead... 
+0

그것은 작동합니다! 고마워요 : D –

3

@cur_encoding = # doc.encoding ISO-8859-15

ISO-8859-15가 인용 된 페이지에 대한 올바른 부호화 아니다; UTF-8이어야합니다. UTF-8로 아이콘 화하면 8859-15 만 문제가됩니다.

이 인코딩은 문서의 결함이있는 <meta> 태그에서 발생합니다. 브라우저는 해당 태그를 무시하고 Content-Type: text/html;charset=utf-8 HTTP 응답 헤더의 우선 인코딩을 사용합니다.

그러나 Nokogiri는 open() 스트림에서이 헤더를 읽을 수 없습니다. Ruby에 대해 아무 것도 모른다는 경고를 받으면 소스를 보면 대신 문자열 또는 IO에서 encoding 속성을 사용하는 것으로 보입니다. 이는 open-uri 인 것으로 보입니다.

당신은 당신의 자신의 재정의 인코딩으로 전달할 수 있습니다, 그래서 시도를 추측 :

sio= open(url) 
doc= Nokogiri::HTML.parse(doc, nil, sio.charset) # should be UTF-8? 
+0

잘 했어, 밥 : 당신이 처리를 시작하기 전에

간단한 수정은 공간을 \u00a0의 글로벌 치환을하는 것입니다. 사람들이 머리글을 보지 않고 웹 페이지의 인코딩을 알고 있다고 가정하는 이유를 모르겠습니다. – tchrist

+0

고마워요 @bobince, 지금은 확실히 더 낫네 (나는 ISO-8859-15를 두 태그 xml doctype과 meta charset으로 생각했다). –

+0

@bobince - 죄송합니다. 깜빡 : 아직도 nokogiristring.strip과 같은 기본 작업을 수행 할 수 없습니다! 또는 정규식. 어떻게해야합니까? –