2010-02-15 31 views

Trả lời

5

Thay vì xây dựng bằng cách sử dụng ổ cắm riêng vv tôi sẽ sử dụng httplib như vậy sẽ lấy dữ liệu từ máy chủ http và phân tích các tiêu đề vào một cuốn từ điển ví dụ

import httplib 
conn = httplib.HTTPConnection("www.python.org") 
conn.request("GET", "/index.html") 
r1 = conn.getresponse() 

dict = r1.getheaders() 
print(dict) 

cho

[('Content-Length', '16.788'), ('chấp nhận-ranges', 'byte'), ('máy chủ', 'Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.5 Python/2.5.2 '), (' sửa đổi lần cuối ',' Thứ Hai, 15 Tháng Hai 2010 07:30:46 GMT '), (' etag ',' "105800d-4194-47f9e9871d580" '), (' ngày ',' Thứ Hai, 15 Tháng Hai 2010 21:34:18 GMT '), (' kiểu nội dung ',' văn ​​bản/html ')]

và các phương pháp để gửi từ điển như một phần của yêu cầu.

+0

* Họ sẽ cần hỗ trợ tiêu đề gấp * httplib không xử lý gấp chính xác. Xem https: // github.com/shazow/urllib3/issues/3 –

+0

@PiotrDobrogost Tôi không nghĩ rõ ràng RFC nói rằng - nó nói rằng PHẢI có thể kết hợp nhiều trường tiêu đề thành một cặp "tên trường: giá trị trường". ... mà httplib không – Mark

+0

Đó chỉ là một nửa của sự thật :) Phần thứ hai là trong câu trước * Nhiều trường tiêu đề tin nhắn với cùng một tên trường CÓ THỂ có mặt trong một tin nhắn ** nếu và chỉ khi ** toàn bộ trường-giá trị cho trường tiêu đề đó được định nghĩa là danh sách được phân tách bằng dấu phẩy [tức là, # (giá trị)]. * httplib gấp tất cả tiêu đề có cùng tên bất kể điều kiện ở trên. Xem phương thức [addheader] (http://hg.python.org/cpython/file/8527427914a2/Lib/httplib.py#l220) trong 'httplib.py'. –

1

Tôi không hoàn toàn chắc chắn, nhưng this có vẻ là dọc theo dòng của những gì bạn đang tìm kiếm

Hope this helps

3

Trong trường hợp bạn không tìm thấy bất kỳ thư viện giải quyết vấn đề, đây là một ngây thơ, giải pháp chưa được kiểm tra:

def fold(header): 
    line = "%s: %s" % (header[0], header[1]) 
    if len(line) < 998: 
    return line 
    else: #fold 
    lines = [line] 
    while len(lines[-1]) > 998: 
     split_this = lines[-1] 
     #find last space in longest chunk admissible 
     split_here = split_this[:998].rfind(" ") 
     del lines[-1] 
     lines = lines + [split_this[:split_here]), 
         split_this[split_here:])] #this may still be too long 
               #hence the while on lines[-1] 
    return "\n".join(lines) 

def dict2header(data): 
    return "\n".join((fold(header) for header in data.items())) 

def header2dict(data): 
    data = data.replace("\n ", " ").splitlines() 
    headers = {} 
    for line in data: 
    split_here = line.find(":") 
    headers[line[:split_here]] = line[split_here:] 
    return headers 
+0

Tôi sẽ ngạc nhiên nếu điều này thực sự hiệu quả trong mọi trường hợp. :) – badp

+0

Cảm ơn, tôi sẽ sử dụng điều này và sửa lỗi nào tôi tìm thấy nếu tôi không thể nhận được bất kỳ thứ gì khác. –

+0

Tôi đã chuyển câu trả lời này thành wiki cộng đồng, vì vậy bạn có thể hợp nhất các bản sửa lỗi dưới dạng/nếu được yêu cầu. – badp

0

Và đây là phiên bản của tôi mà không cho lặp:

import re 
req_line = re.compile(r'(?P<method>GET|POST)\s+(?P<resource>.+?)\s+(?P<version>HTTP/1.1)') 
field_line = re.compile(r'\s*(?P<key>.+\S)\s*:\s+(?P<value>.+\S)\s*') 

def parse(http_post): 
    first_line_end = http_post.find('\n') 
    headers_end = http_post.find('\n\n') 
    request = req_line.match(
     http_post[:first_line_end] 
    ).groupdict() 
    headers = dict(
     field_line.findall(
      http_post[first_line_end:headers_end] 
     ) 
    ) 
    body = http_post[headers_end + 2:] 
    return request, headers, body 
1

Tôi nhận ra bài này là từ năm 2010, nhưng tôi nghĩ rằng nó tốt nhất để lên tiếng. Tôi đồng ý với Mark's Post cho đến khi lệnh được chỉ định.

Kể từ getheaders trả về một danh sách các hàng và dict constructor xây dựng từ điển từ cặp khóa-giá trị được lưu trữ như các bộ, bạn có thể tạo ra những gì bạn muốn trực tiếp:

import httplib 
conn = httplib.HTTPConnection("www.python.org") 
conn.request("GET", "/index.html") 
response = conn.getresponse() 

headers = dict(response.getheaders()) 
print(headers) 

Bây giờ bạn nhận được:

{ 'content-length': '18891', 'accept-range': 'bytes', 'server': 'Apache/2.2.16 (Debian)', 'sửa đổi lần cuối': 'Thứ Hai, ngày 30 tháng 5 năm 2011 19:50 : 25 GMT ',' etag ':' "105800d-49cb-4a48399368240" ',' ngày ':' Thứ Hai, ngày 30 tháng 5 năm 2011 21:29:32 GMT ',' loại nội dung ':' text/html '}

Nếu bạn muốn những bộ dữ liệu đó trở lại, hãy gọi headers.items().

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