2010-11-27 3 views
2

얘들 아, 난 그냥urllib2가, 구글 앱 엔진, 그리고 유니 코드 질문

나의 현재의 곤경이입니다 ... 그래서 나는 문제의 무리 실행 해요 구글 앱 엔진을 배우고 야. 데이타베이스가 있습니다.

class Website(db.Model): 
    web_address = db.StringProperty() 
    company_name = db.StringProperty() 
    content = db.TextProperty() 
    div_section = db.StringProperty() 
    local_links = db.StringProperty() 
    absolute_links = db.BooleanProperty() 
    date_updated = db.DateTimeProperty() 

그리고 제가 가지고있는 문제는 content 속성에 있습니다.

> 500 바이트가 넘는 웹 페이지의 내용을 저장해야하므로 db.TextProperty()를 사용하고 있습니다.

내가 실행중인 문제는 urllib2.readlines() 형식으로 유니 코드입니다. TextProperty()에 넣으면 ASCII로 변환됩니다. 일부 문자는 128보다 크고 UnicodeDecodeError를 던집니다.

이것을 우회하는 간단한 방법이 있습니까? 대부분의 경우, 나는

내 오류는 ... 그 문자에 대해 걱정하지 않는다 :

Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/init.py", line 511, in call handler.get(*groups) File "/base/data/home/apps/game-job-finder/1.346504560470727679/main.py", line 61, in get x.content = website_data_joined File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 542, in set value = self.validate(value) File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2407, in validate value = self.data_type(value) File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 1006, in new return super(Text, cls).new(cls, arg, encoding) UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 2124: ordinal not in range(128)

+1

f = urllib2.open('http://www.google.com') website = Website() content = unicode(f.read(), errors = 'ignore') # Ignore characters that cause errors website.content = db.Text(content) # Don't need to specify an encoding since content is already a unicode string 
하지 "디코딩을 를"인코딩 " ". 다른 방법이 아닌 것이 확실합니까? –

+0

네, 맞아요. – shawn

+0

readline을 만들고 데이터 저장소에 넣은 스 니펫을 추가 할 수 있습니까? – systempuntoout

답변

1
선이 readlines 유니 코드 문자열이 아니라 바이트 문자열 (하지에서 반환 된 것으로 생각된다

즉 비 ASCII 문자가 포함될 수있는 str의 인스턴스). 이 바이트는 HTTP 응답 본문에서 수신 된 원시 데이터이며 사용 된 인코딩에 따라 다른 문자열을 나타냅니다. 텍스트 (바이트! = 문자)로 처리되기 전에 "디코딩"되어야합니다.

인코딩이 UTF-8 인 경우,이 코드가 제대로 작동합니다 : 실제 인코딩 (때로는 페이지에서 페이지로) 웹 사이트에 웹 사이트에서 다릅니다 것을

f = urllib2.open('http://www.google.com') 
website = Website() 
website.content = db.Text(f.read(), encoding = 'utf-8-sig') # 'sig' deals with BOM if present 

참고. 사용 된 인코딩은 HTTP 응답의 Content-Type 헤더에 포함되어야합니다 (가져 오는 방법은 this question 참조). 그렇지 않은 경우 HTML 머리 부분의 메타 태그에 포함될 수 있습니다 (이 경우 추출 적절하게 훨씬 더 까다 롭습니다.)

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

인코딩을 지정하지 않은 사이트 또는 잘못된 인코딩을 지정하는 사이트가 있습니다. 당신이 정말로 모든 문자 만 ASCII를 걱정하지 않는 경우

, 당신은 그들을 무시 할 수 있고 함께 할 수 :

내가 ASCII 유니 코드로 변환하는 것이 될 것이라고 생각했을 것이다