Có chức năng tiêu chuẩn nào sẽ chuyển đổi tiêu đề http thành từ điển python và một để chuyển đổi lại không?Chuyển đổi tiêu đề http (chuỗi) thành từ điển python
Tất nhiên, họ sẽ cần hỗ trợ gấp đầu trang.
Có chức năng tiêu chuẩn nào sẽ chuyển đổi tiêu đề http thành từ điển python và một để chuyển đổi lại không?Chuyển đổi tiêu đề http (chuỗi) thành từ điển python
Tất nhiên, họ sẽ cần hỗ trợ gấp đầu trang.
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.
* 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 –
@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
Đó 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'. –
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
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
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
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. –
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
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
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()
.
Bạn lấy tiêu đề http từ đâu? – Mark
từ một đối tượng tệp (được tạo từ ổ cắm) –