2013-05-27 5 views
2

자주 파이썬에서 lxml 모듈을 사용하여 일부 웹 사이트의 데이터를 긁어 내고 일반적으로 모듈에 익숙합니다. 그러나 긁어 모으려고하면 etree.fromstring() 전화에서 lxml.etree.XMLSyntaxError: AttValue: " or ' expected 오류가 발생하지만 대개는 그렇지 않습니다. 나는 그 오류를 얼마나 자주 볼 수 있는지 명확히 할 수는 없지만, 수천 번 또는 수천 번 중 하나라고 생각합니다. 오류가 발생합니다. 오류가 발생하고 스크립트가 중지 된 후 바로 똑같은 스크립트를 실행하면 오류가 표시되지 않고 스크립트가 예상대로 올바르게 실행됩니다. 왜 그것이 오발 적 오류를 내뱉습니까? 문제를 해결할 방법이 있습니까? urllib2.urlopen() 함수를 인스턴스화 할 때 유사한 문제가 있지만 최근에 urllib2에서 오류를 보지 못했기 때문에 지금부터 정확한 오류 메시지를 작성할 수 없습니다.왜 lxml은 파이썬에서 (보통은 아니지만) 오류를 내뱉습니까?

감사합니다.

+0

아마 * invalid * XML입니까? 오류가 발생한 데이터를 캡처하고 [XML/XHTML validator] (http://validator.w3.org)로 유효성을 검사하십시오. (아마도 동일한 데이터에 대해 오류가 결정적으로 발생하지 않을 가능성이 있습니다. 서버가 다른 것을 반환했을 가능성이 있습니까?) – user2246674

답변

2

웹 사이트는 XML이 아닌 (종종 유효하지 않은) HTML로 작성됩니다. HTML을 XML로 취급하지 않아야합니다.

사용 lxml's HTML parser하고 문제가 사라해야

import urllib2 
from lxml import etree 

parser = etree.HTMLParser() 
tree = etree.parse(urllib2.urlopen(url), parser) 

을 당신이 그 LXML를 발견하면 여전히된다는 잘못된 HTML을 읽으려고 할 때, 당신은 더 관대 파서를 찾을 수있을 것이다. BeautifulSoup로와 html5lib 파이썬에 가장 관대 한 (그리고 가장 느린) HTML 파서입니다 :

from bs4 import BeautifulSoup 

soup = BeautifulSoup(urllib2.urlopen(url), 'html5lib') 
+0

더 자세한 정보를 제공해야하지만 일반적으로 오류가 표시되지 않습니다. 난 정확히 똑같은 페이지를 긁어 내려고 시도 할 때 1,000 ~ 10,000 번 중 한 번만 오류가 발생합니다.이 페이지는 다칠 때마다 정확히 같은 XML입니다. 또한 페이지는 엄격한 XML 파일로 구성되며 웹에서 자주 볼 수있는 잘못된 HTML 파일이 아닙니다. 마지막으로, 오류가 표시 되더라도 다음 번에 동일한 XML 파일 (파일의 내용을 변경하지 않음)로 구성된 동일한 페이지를 다 쳤으므로 오류가 더 이상 발생하지 않습니다. – Blaszard

+0

@ user2360798 : 샘플 XML 파일을 보여줄 수 있습니까? – Blender

1

가 나는 또한 LXML의 iterparse() 때때로 매우 예측할 수없는 패턴에 AttValue: ' expected를 throw하는 문제가 있었다. 내가 보내는 XML이 유효하다는 것을 알았고 같은 스크립트를 다시 실행하면 종종 작동하게됩니다 (또는 완전히 다른 시점에서 실패합니다).

결국 다시 테스트 할 수있는 테스트 사례를 만들었고 즉시 임의의 결과로 AttValue 오류를 완료하거나 발생시킵니다. 여기에 내가 잘못 했어 :

내 입력은 에 내가 썼던 파일과 유사한 객체 (요청으로부터 HTTP 응답 스트림을 처리하고 있지만 먼저 ungzipped되어야합니다)입니다. read() 메서드를 작성할 때 크기 인자를 부정하고 무시했습니다. 대신, 고정 크기의 압축 바이트 청크를 압축 해제하고 압축 해제 된 바이트 시퀀스를 반환합니다. 이는 종종 32k lxml 요청보다 훨씬 많습니다!
위의 문제가 발생한 lxml 어딘가에서 버퍼 오버 플로우가 발생했다고 생각합니다. lxml이 요청한 것보다 더 많은 바이트를 반환하는 것을 멈추자 마자,이 임의의 에러는 사라질 것입니다.

관련 문제