有一些方法可以通过特定的http版本协议在python中发送http请求。我认为,使用httplib或urllib是不可能的。
例如:GET/HTTP/6.9
提前谢谢。
问题的简单答案是:你是对的,httplib
和urllib
都没有公共的内置功能。(此外,对于大多数事情,您真的不应该使用urllib
,尤其是urlopen
。)
当然,您可以始终依赖这些模块的实现细节,正如Lukas Graf的回答所示。
或者,您也可以派生其中一个模块并对其进行修改,这可以保证您的代码可以在其他Python 2.x实现上运行。*。请注意,httplib
是其中一个在顶部有指向源代码链接的模块,这意味着它意味着要作为示例代码而不仅仅是一个黑盒库来服务器。
或者,您可以重新实现需要挂接但已公开文档的最低级别功能。对于httplib
,我相信这是httplib.HTTPConnection.putrequest
,它有几百行长。
或者,你可以选择一个不同的库,它有更多的钩子,所以你要钩子的更少。
但实际上,如果你试图创建一个自定义请求来手动对结果进行指纹识别,你为什么要使用HTTP库呢?为什么不这么做呢?
msg = 'GET / HTTP/6.9rnrn'
s = socket.create_connection((host, 80))
with closing(s):
s.send(msg)
buf = ''.join(iter(partial(s.recv, 4096), ''))
*这并没有多大好处,因为永远不会有2.8,所有现有的主要2.7实现都共享该模块的相同来源,而且任何新的2.x实现都不太可能有任何不同。如果你转到3.x,httplib
已经被重新组织和重命名,而urllib
已经被完全删除,所以你已经有更大的变化需要担心了
通过对httplib.HTTPConnection
进行子类化并重新定义类属性_http_vsn_str
:,可以很容易地做到这一点
from httplib import HTTPConnection
class MyHTTPConnection(HTTPConnection):
_http_vsn_str = '6.9'
conn = MyHTTPConnection("www.stackoverflow.com")
conn.request("GET", "/")
response = conn.getresponse()
print "Status: {} {}".format(response.status, response.reason)
print "Headers: {}".format(response.getheaders())
print "Body: {}".format(response.read())
当然,这将导致大多数服务器的400 Bad Request
:
Status: 400 Bad Request
Headers: [('date', 'Tue, 11 Nov 2014 21:21:12 GMT'), ('connection', 'close'), ('content-type', 'text/html; charset=us-ascii'), ('content-length', '311')]
Body: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request</h2>
<hr><p>HTTP Error 400. The request is badly formed.</p>
</BODY></HTML>
使用这个选项使用pycurl是可能的
c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0)
但是,您需要使用linux或mac,因为pycurl在windows 上不受官方支持