2011-01-16 33 views
6

Tôi đang cố gắng làm việc với các dịch vụ web HORRIBLE tại Commission Junction (CJ). Tôi có thể yêu cầu khách hàng kết nối và nhận thông tin từ CJ, nhưng cơ sở dữ liệu của họ dường như bao gồm một loạt các ký tự xấu gây ra một UnicideDecodeError.Cách khắc phục sự cố unicode khi sử dụng dịch vụ web với Python Suds

Ngay bây giờ tôi đang làm:

from suds.client import Client 
wsdlLink = 'https://link-search.api.cj.com/wsdl/version2/linkSearchServiceV2.wsdl' 
client = Client(wsdlLink) 
result = client.service.searchLinks(developerKey='XXX', websiteId='XXX', promotionType='coupon') 

này hoạt động tốt cho đến khi tôi đạt mức kỷ lục mà có cái gì đó như 'CorpNet® Giảm 10% Dịch vụ Bất kỳ' thì ® gây ra nó để phá vỡ và tôi nhận được

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 758: ordinal not in range(128)" error. 

Có cách nào để mã hóa ® trên đầu của tôi để nó không bị vỡ khi SUDS đọc trong kết quả không?

CẬP NHẬT: Để làm rõ, ® đến từ cơ sở dữ liệu CJ và phản hồi của chúng. SO bằng cách nào đó tôi cần giải mã các ký tự không phải ascii TRƯỚC KHI SUDS giao dịch với câu trả lời. Tôi không chắc chắn làm thế nào (hoặc nếu) điều này được thực hiện trong SUDs.

+0

đảm bảo rằng bạn không kết hợp các đối tượng 'str' và' unicode', ví dụ: 'u'a '+' ®'' sẽ gây ra lỗi. Giải mã đầu vào thành Unicode càng sớm càng tốt. – jfs

Trả lời

3

Implicit UnicodeDecodeErrors là thứ bạn nhận được khi cố thêm các đối tượng str và unicode. Python sau đó sẽ cố gắng giải mã str thành unicode, nhưng sử dụng mã hóa ASCII. Nếu str của bạn sau đó có chứa bất cứ điều gì mà không phải là ascii, bạn sẽ nhận được lỗi này.

giải pháp của bạn là giải mã nó bằng tay như sau:

thestring = thestring.decode('utf8') 

Cố gắng, càng nhiều càng tốt, để giải mã bất kỳ chuỗi thể chứa các ký tự khác ASCII không như soo như bạn đang đưa nó từ bất cứ bạn nhận được nó từ, trong trường hợp này là suds.

Sau đó, nếu suds không thể xử lý Unicode (có thể là trường hợp) hãy đảm bảo bạn mã hóa nó ngay trước khi chuyển văn bản trở lại suds (hoặc bất kỳ thư viện nào khác bị hỏng nếu bạn cho nó unicode).

Điều đó sẽ giải quyết mọi thứ một cách độc đáo. Nó có thể là một thay đổi lớn, vì bạn cần phải di chuyển tất cả các xử lý nội bộ của bạn từ str sang unicode, nhưng nó có giá trị nó. :)

+0

Lennart. Vấn đề là các ký tự không phải ascii thực sự nằm trong cơ sở dữ liệu CJ và trong phản hồi mà chúng gửi. Vì vậy, không chắc chắn làm thế nào tôi có thể giải mã phản ứng của họ trước khi SUDS cố gắng phân tích nó và ném lỗi. Tôi cần một cách nào đó để gửi yêu cầu, giải mã phản hồi và sau đó phân tích cú pháp phản hồi. Nhưng tôi không thấy một cách để làm điều này trong SUD. – chris

+0

@chris: Vì vậy, lỗi xảy ra trong suds, ngay cả trước khi mã của bạn xử lý dữ liệu? Trong trường hợp đó, đó là một lỗi, hoặc trong suds hoặc trong máy chủ. Có lẽ máy chủ gửi dữ liệu được mã hóa trong UTF khi nó tuyên bố nó là cái gì khác? –

+0

Lennart - Đúng. Tôi khá chắc chắn nó đang xảy ra tại máy chủ (mà tôi không thể kiểm soát). Commission Junction dường như không hỗ trợ các dịch vụ web và tôi đã hy vọng có một số cách để sửa dữ liệu trước khi nó được đưa trở lại vào SUD. Tôi đã nghĩ đó là một cảnh quay dài, nhưng tôi nghĩ có lẽ tôi đã bỏ lỡ điều gì đó. – chris

1

Ký tự "đã đăng ký" là U + 00AE và được mã hóa là "\xc2\xae" bằng UTF-8. Dường như bạn có một đối tượng str được mã hóa bằng UTF-8 nhưng một số mã đang hoạt động (có thể theo mặc định) your_str_object.decode("ascii") sẽ không thành công với thông báo lỗi bạn đã hiển thị.

Những gì bạn cần làm là hiển thị cho chúng tôi một ví dụ hoàn chỉnh (ví dụ: TẤT CẢ mã cần thiết để nhận lỗi), cộng với thông báo lỗi đầy đủ và truy xuất lại, để ít nhất chúng tôi có thể đoán được sự cố trong mã của bạn hay trong mã được nhập.

+0

Để rõ ràng. Dữ liệu gây ra lỗi nằm trong thư trả lời từ dịch vụ web. Vì vậy, tôi gửi một yêu cầu hoạt động, nhưng vấn đề xảy ra khi CJ trả lời lại với ký tự "đã đăng ký" trong phản hồi. Vì vậy, những gì tôi cần làm là bằng cách nào đó làm sạch nhân vật TRƯỚC KHI SUDS cố gắng phân tích nó. Theo như mã, những gì bạn thấy ở trên là tất cả những gì bạn cần làm với SUDS để nhận phản hồi dịch vụ web và lỗi SUD. – chris

+0

@chris: Tất cả ** bạn ** cần làm là những gì mọi người nên làm khi hỏi về sự cố đang tăng ngoại lệ: chạy mã tối thiểu cần thiết để gây ra sự cố và sao chép/dán thông báo lỗi đầy đủ và truy xuất lại chỉnh sửa câu hỏi của bạn. Nhân tiện, làm cách nào bạn biết rằng đó là ký tự "đã đăng ký" trong phản hồi? –

+0

John - mã tôi chạy là những gì tôi đặt trong câu hỏi, và lỗi là "UnicodeDecodeError: 'ascii' codec không thể giải mã byte 0xc2 ở vị trí 759: thứ tự không nằm trong phạm vi (128)". Không chắc chắn những gì bạn đang yêu cầu vượt ra ngoài đó. Tôi biết đó là ký tự "đã đăng ký" vì tôi có thể sử dụng một trình khách xà phòng khác không phá vỡ các ký tự ascii và thấy rằng trên các kết quả phá vỡ ký tự "đã đăng ký" được bao gồm trong phản hồi. Khi kết quả không bao gồm ký tự "đã đăng ký", kết quả sẽ được trả về đúng. Vấn đề đã kết thúc trong SUD, tôi đã thực hiện một bản vá lỗi. Cảm ơn – chris

0

Tôi đang sử dụng SUDS để giao tiếp với Salesforce thông qua API SOAP của họ. Tôi chạy vào tình huống tương tự cho đến khi tôi theo lời khuyên của @ J.F.Sabastian bằng cách không trộn str và unicode chuỗi các loại. Ví dụ, đi qua một chuỗi SOQL như thế này không làm việc với bọt 0.3.9:

qstr = u"select Id, FirstName, LastName from Contact where FirstName='%s' and LastName='%s'" % (u'Jorge', u'López') 

Tôi dường như không cần phải làm str.decode ("utf-8") một trong hai.

Nếu bạn đang chạy tập lệnh của mình từ PyDev trên Eclipse, bạn có thể muốn vào Project => Properties và dưới phần Tài nguyên, đặt "Mã hóa tệp văn bản" thành UTF-8, trên máy Mac của tôi, mặc định là "MacRoman ". Tôi giả sử trên Windoze, mặc định là Cp1252 hoặc ISO-8859-1 (tiếng Latinh).Bạn cũng có thể thiết lập điều này trong không gian làm việc của bạn dự án của bạn kế thừa cài đặt này từ không gian làm việc của họ. Điều này chỉ ảnh hưởng đến mã nguồn của chương trình.

Các vấn đề liên quan