2011-10-02 4 views
1

다운로드 한 웹 페이지 ('something'.html'로 저장 됨)를 읽고 이에 따라 구문 분석하는 프로그램을 작성하고 있습니다. 이 프로그램의 인코딩과 디코딩을 올바르게하는 데 어려움을 겪고 있습니다. 그것은 대부분의 웹 페이지는 ISO-8859-1 인코딩 된 나의 이해 그리고 나는이 페이지의 응답을 확인하고 그게 내가 주어진 캐릭터 세트이다 : 그것은 선언 페이지의 메타 태그에, 그러나파이썬을 사용하여 파일에 UTF-8로 텍스트를 쓸 수 없습니다.

>>> print r.info() 
Content-Type: text/html; charset=ISO-8859-1 
Connection: close 
Cache-Control: no-cache 
Date: Sun, 20 Feb 2011 15:16:31 GMT 
Server: Apache/2.0.40 (Red Hat Linux) 
X-Accel-Cache-Control: no-cache 

'UTF -8 '는 인코딩 설정입니다 같이

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 

그래서, 파이썬에서 나는,이 페이지를 읽어을 분석하고, UTF-8 정상에서 파일을 읽고 일반적으로 쓰기를 포함하여 작성하는 접근 방법을 시도했다 :

with open('../results/1.html','r') as f:         
    page = f.read() 
... 
with open('../parsed.txt','w') as f: 
    for key in fieldD: 
     f.write(key+'\t'+fieldD[key]+'\n') 

나는 읽기 & 쓰기 과정에서 사용할 인코딩 파일을 말하는 명시 적으로 시도 :

with codecs.open('../results/1.html','r','utf-8') as f:         
    page = f.read() 
... 
with codecs.open('../parsed.txt','w','utf-8') as f:         
    for key in fieldD: 
     f.write(key+'\t'+fieldD[key]+'\n') 

명시 적으로 'ISO-8849-1'읽고 'UTF-8'에 쓸 파일을 말하는 :

utf-16으로 작성하고 사전에 추가하기 전에 각 문자열을 별도로 인코딩하는 것을 비롯하여 이러한 아이디어의 모든 순열 및 기타 잘못된 아이디어. 나는 최선의 접근 방식이 무엇인지 모르겠습니다. 그것은 어떤 인코딩을 사용하지 않는 것이 가장 좋았던 것 같습니다. 최소한 텍스트 편집기에서 결과를 올바르게 볼 수있게 만들었습니다. (이맥스, 텍스트 랭글러)

이 주제와 관련하여 여기에서 몇 게시물을 읽었습니다. 계속되고있는 일의 머리 나 꼬리를 만드는 것처럼 보이지는 않습니다.

감사합니다.

+2

[이해가 잘못되었습니다.] (http://www.w3.org/QA/2008/05/utf8-web-growth.html) 대부분의 웹 페이지는 UTF-8을 사용하고 있습니다. 그리고 심지어 Windows 코드 페이지 1252는 잊혀진 저자 덕분에 ISO 8859-1보다 훨씬 더 안전합니다. – Joey

+0

어떤 오류 메시지가 나타 납니까? –

+0

내 이해가 잘못되었는지 여부에 관계없이이 특정 페이지에서 얻은 응답은 ISO-8859-1을 나타냅니다. 실제로 파이썬이 성공적으로 파일에 쓸 것이라는 의미로 오류가 발생하지는 않습니다. 그러나 파일을 보는 데 사용하는 문자에 따라 문자가 올바르게 표시되거나 표시되지 않을 수 있습니다. 감사. – josh

답변

2

안내에 따라 진행되었습니다. 표시된 페이지는 NOT이며 UTF-8로 인코딩되어 있습니다. UTF-8을 사용한 디코딩이 실패합니다. 실험용 문자 세트 감지기에 따르면 나는 가끔 혼란 스럽지만, ISO-8859-1, cp1252 및 ISO-8859-15 중 하나 인 라틴 기반 인코딩으로 인코딩되어 있으며 언어는 ' es '(스페인어) 또는'fr '(프랑스어). 그것을보고있는 나에 따르면, 그것은 스페인어 다. Firefox (보기 >>>보기 인코딩)는 ISO-8859-1이라고 말합니다.

그럼 이제는 도구가 저장된 파일을 올바르게 표시 할 것인지 실험 해보십시오. 찾을 수없는 경우 파일을 UTF-8, 즉 data.decode ('ISO-8859-1') .encode ('UTF-8')로 코드 변환하고 UTF-8을 표시하는 도구를 찾아야합니다 바르게. 너무 열심히해서는 안됩니다. 파이어 폭스는 인코딩에 신경 쓸 수 있으며, 내가 던진 인코딩에 대해서 올바르게 표시 할 수있다. "직관"에 대한 요청 후

업데이트 :

코드의 3 번째 블록에서, 당신은 ... ""사이와 만 입력 및 출력을 포함한다. 입력 코드는 unicode 개체를 생성해야합니다. 그러나 출력 코드에서 str 함수를 사용합니다 (왜 ???). "..."뒤에 여전히 unicode 개의 개체가 있다고 가정하면 str()을 적용하면 시스템의 기본 인코딩이 'ascii'(반드시 있어야 함)이거나 'utf8'인 경우 자동으로 데이터를 맹 글링하면 예외가 발생합니다 그렇게해서는 안된다.) "..."(2) import sys; print sys.getdefaultencoding() (3)의 결과를 (1) "Iglesia Católica"에서 예상되는 출력 파일 대신 출력 파일에서 "(1) 내용을 게시하십시오."- ó입니까?(4) 파일의 실제 바이트 (들) (사용 인쇄에 repr (데이터)) 오

예상 당신은 네가 있습니다 ... 당신이 Iglesia Cat√ɬ≥lica을 볼 주석의 말을 해결 대신 하나 대신 문자가 표시됩니다. 이것은 UTF-8 인코딩을 두 번 나타내주는 증상입니다. 다음 퍼즐은 그 캐릭터를 표시하는 퍼즐이었습니다. 그 중 두 개는 ISO-8859-1 또는 cp1252에 매핑되지 않았습니다. 나는 오래된 DOS 코드 페이지 인 cp437과 cp850을 사용해 보았습니다. 여전히 Windows의 명령 프롬프트 창에서 사용되었지만 적합하지 않았습니다. koi8r도 어느쪽에도 맞지 않았습니다. 라틴 문자 기반의 문자 세트가 필요합니다. 매크로 맨은 어떨까요? 타다 !! Mac 터미널에서 이중 인코딩 된 guff를 stdout으로 보냈습니다. 아래의 데모를보십시오.

>>> from unicodedata import name 
>>> oacute = u"\xf3" 
>>> print name(oacute) 
LATIN SMALL LETTER O WITH ACUTE 
>>> guff = oacute.encode('utf8').decode('latin1').encode('utf8') 
>>> guff 
'\xc3\x83\xc2\xb3' 
>>> for c in guff.decode('macroman'): 
...  print name(c) 
... 
SQUARE ROOT 
LATIN CAPITAL LETTER E WITH ACUTE 
NOT SIGN 
GREATER-THAN OR EQUAL TO 
>>> 

저장된 파일을 검사 나도 파일 (플러스 디렉토리 containin * .JPG, CSS 파일 등)로 웹 페이지를 저장 - 파이어 폭스 "로 페이지를 저장"을 사용. 저장된 페이지에서이 작업을 시도하고 결과를 게시하십시오.

>>> data = open('g0.htm', 'rb').read() 
>>> uc = data.decode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "c:\python27\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb7 in position 1130: invalid start byte 
>>> pos = data.find("Iglesia Cat") 
>>> data[pos:pos+20] 
'Iglesia Cat\xf3lica</a>' 
>>> # Looks like one of ISO-8859-1 and its cousins to me. 

주의 : 파일이 UTF-8로 인코딩 된 경우 UTF-8 코덱으로 파일을 읽으면 유니 코드가 생성됩니다. 파싱 ​​할 때 어떻게 든 데이터를 변조하지 않고 UTF-8 코덱을 사용하여 구문 분석 된 유니 코드를 작성하면 이중 인코딩되지 않습니다. "str"("오타"기억), "unicode", "encode", "decode", "utf", "UTF"등의 코드를 신중하게 살펴볼 필요가 있습니다. - 파티 라이브러리 파싱을 할 수 있습니까? 출력 파일에 쓰기 바로 전에 print repr(key), repr(field[key])을 할 때 무엇을 볼 수 있습니까?

이것은 지루해지고 있습니다. 추측하는 대신 웹에서 코드 및 저장된 페이지를 볼 수 있습니다.

32766.html : 나는 당신이 그의 inode를 날려 버린 사람이 vfat 파일 시스템 (또는 그와 비슷한 것)의 폴더에 너무 많은 파일을 작성하려고 애쓰는 것을 깨달았다. 따라서 수동으로 "다른 이름으로 저장"을 수행하지 않습니다. 이 파일을 "저장"하는 데 사용한 코드를 게시하십시오.

+0

맞아요, 원래의 글에서 ISO-8859-1로 인코딩 된 것으로 의심됩니다. 서버가 캐릭터 세트를 표현한 것입니다. 그러나 내가 찾고있는 부분은 ISO-8859-1을 사용하여 페이지를 디코딩하고 구문 분석 한 다음 UTF-8로 인코딩하고 파일에 쓰는 정크가 왜 파일에 기록되는지에 대한 직관입니다. 당신은 내 원래 게시물에서 코드의 세 번째 블록을 볼 수 있습니다 본질적으로 당신이 대답이 여기에 무슨 말을하고 있지만 나는 이미 그것을 시도하고 그 특정 시도를 위해 파일을 표시하는 데 사용하는 도구, 모든 외국 문자는 쓰레기입니다. 감사. – josh

+0

내 실수. 'str()'은 오타입니다. ...의 내용은 전체 프로그램이고 어느 정도 길이입니다. 텍스트에서 일어나는 모든 일은 파싱됩니다. 기본 인코딩은 ascii입니다. ISO-8859-1을 열고 UTF-8로 작성하는 방법을 사용하면 다음과 같은 결과를 얻을 수 있습니다. Iglesia Cat√ɬllica. 'repr (data) = u 'Iglesia Cat \ xc3 \ xb3lica'' – josh

+0

맞습니다. 나는 우리가 가지고있는 오도 된 커뮤니케이션이 나가 웹 떨어져이 페이지에 접근하고 있지 않다이다 것을 나는 생각한다. 나는 그들을 내 HD에 저장했습니다. 그래서, 그들은 utf-8로 저장 될 수 있었을 것입니다. 그리고 ISO-8859-1을 사용하여 그들을 열었을 때 마지막에 utf-8로 다시 인코딩하면이 문자들을 얻을 수 있습니다. 내가 원하는 것은'codecs.open ('../ results/1.html', 'r', 'utf)을 사용하여 열어서 얻을 수있는 유니 코드 문자열'Iglesia Cat \ xf3lica' -8 ')'. 것은 분명히 쓰기 인코딩'codecs.open ('../ parsed.txt', 'w', 'utf-8')을 명시 적으로 부여해야하며'$ a Iglesia Cat√ ≥lica'를 생성합니다. – josh

1
>>> url = 'http://213.97.164.119/ABSYS/abwebp.cgi/X5104/ID31295/G0?ACC=DCT1' 
>>> data = urllib2.urlopen(url).read()[4016:4052]; data 
'Iglesia+Cat%f3lica">Iglesia Cat\xf3lica' 

>>> data.decode('latin-1') 
u'Iglesia+Cat%f3lica">Iglesia Cat\xf3lica' 

>>> data.decode('latin-1').encode('utf-8') 
'Iglesia+Cat%f3lica">Iglesia Cat\xc3\xb3lica' 

무엇을 얻었습니까?

관련 문제