2009-06-20 35 views
45

Tôi cần lưu trữ nội dung của trang web có thể bằng bất kỳ ngôn ngữ nào. Và tôi cần có khả năng tìm kiếm nội dung cho chuỗi Unicode.urllib2 đọc to Unicode

Tôi đã thử một cái gì đó như:

import urllib2 

req = urllib2.urlopen('http://lenta.ru') 
content = req.read() 

Nội dung là một dòng byte, vì vậy tôi có thể tìm kiếm nó cho một chuỗi Unicode.

Tôi cần một cách nào đó khi tôi làm urlopen và sau đó đọc để sử dụng bộ ký tự từ các tiêu đề để giải mã nội dung và mã hóa thành UTF-8.

+0

Mã hóa được thực hiện bằng cách sử dụng hàm từ thư viện urllib không phải từ urllib2. Từ http://www.voidspace.org.uk/python/articles/urllib2.shtml#headers – Macarse

+1

@Macarse đây không phải là mã hóa mà Vitaly đề cập đến, anh ta đang đề cập đến giải mã và mã hóa ngữ cảnh yêu cầu thực tế với '[byte string] '. decode (' [charset] ') và u' [unicode string] '. encode (' utf-8 '). Bạn đang tham chiếu đến các tham số yêu cầu mã hóa. –

+0

liên quan: [Một cách hay để lấy bảng mã/mã hóa phản hồi HTTP bằng Python] (http://stackoverflow.com/q/14592762/4279) – jfs

Trả lời

96

Sau khi hoạt động bạn thực hiện, bạn sẽ thấy:

>>> req.headers['content-type'] 
'text/html; charset=windows-1251' 

và như vậy:

>>> encoding=req.headers['content-type'].split('charset=')[-1] 
>>> ucontent = unicode(content, encoding) 

ucontent bây giờ là một chuỗi Unicode (của 140.655 ký tự) - ví dụ như vậy để hiển thị một phần của nó, nếu thiết bị đầu cuối của bạn là UTF-8:

>>> print ucontent[76:110].encode('utf-8') 
<title>Lenta.ru: Главное: </title> 

và bạn có thể tìm kiếm, v.v ...

Chỉnh sửa: Unicode I/O thường phức tạp (có thể là những gì đang nắm giữ người hỏi ban đầu) nhưng tôi sẽ bỏ qua vấn đề khó khăn khi nhập chuỗi Unicode vào trình thông dịch Python tương tác (hoàn toàn không liên quan đến câu hỏi gốc) để hiển thị như thế nào, một khi một chuỗi Unicode được nhập chính xác (tôi đang làm nó bằng codepoints - goofy nhưng không phức tạp ;-), tìm kiếm là hoàn toàn không có trí tuệ (và do đó hy vọng câu hỏi ban đầu đã được trả lời triệt để). Một lần nữa giả định một thiết bị đầu cuối UTF-8:

>>> x=u'\u0413\u043b\u0430\u0432\u043d\u043e\u0435' 
>>> print x.encode('utf-8') 
Главное 
>>> x in ucontent 
True 
>>> ucontent.find(x) 
93 

Note: Hãy ghi nhớ rằng phương pháp này có thể không làm việc cho tất cả các trang web, kể từ một số trang web chỉ định mã hóa ký tự bên trong các tài liệu phục vụ (sử dụng thẻ meta http-equiv , ví dụ).

+0

Xin chào Alex, cảm ơn bạn đã trả lời. Nhưng nếu tôi làm: u'Главное 'trong ucontent nó trả về Sai. Có cách nào tốt hơn để thực hiện tìm kiếm không? –

+2

Bạn nhập chuỗi u '...' như thế nào? Unicode I/O là khó khăn, như thiết bị đầu cuối của bạn và Python phải được trên bước sóng giống hệt nhau. Sử dụng codepoints Unicode rõ ràng (nhàm chán nhưng không khôn lanh) hoạt động tốt, hãy để tôi chỉnh sửa câu trả lời của tôi để hiển thị điều đó. –

+0

Tôi đang nhập bằng bảng điều khiển, Nếu tôi cần làm điều này cho một bài kiểm tra đơn vị, tôi nên đặt mã hóa: ở đầu tệp? –

9

Để phân tích Content-Type tiêu đề http, bạn có thể sử dụng cgi.parse_header chức năng:

import cgi 
import urllib2 

r = urllib2.urlopen('http://lenta.ru') 
_, params = cgi.parse_header(r.headers.get('Content-Type', '')) 
encoding = params.get('charset', 'utf-8') 
unicode_text = r.read().decode(encoding) 

Một cách khác để có được charset:

>>> import urllib2 
>>> r = urllib2.urlopen('http://lenta.ru') 
>>> r.headers.getparam('charset') 
'utf-8' 

Hoặc bằng Python 3:

>>> import urllib.request 
>>> r = urllib.request.urlopen('http://lenta.ru') 
>>> r.headers.get_content_charset() 
'utf-8' 

Character mã hóa cũng có thể được chỉ định bên trong tài liệu html ví dụ: <meta charset="utf-8">.

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