当我尝试使用请求加载外部URL的django视图时,我得到一个'module'对象没有属性'create_connection'。但是,当我使用urllib2或来自交互式shell的相同请求代码时,它可以工作。
我的环境:
我实际上使用2种不同的API来完成不同的功能。他们都需要请求,他们都提出了这个错误:
Exception Type: AttributeError
Exception Value: 'module' object has no attribute 'create_connection'
Exception Location: /my/virtualenv/dir/lib/python2.5/site-packages/requests/packages/urllib3/connectionpool.py in connect, line 67
例外中提到的行是:
sock = socket.create_connection((self.host, self.port), self.timeout)
看起来python 2.5附带的socket版本没有create_connection方法(它在2.6中添加)。但是,我尝试从virtualenv中的python交互式shell运行完全相同的代码,一切正常。另外,请求0.10.0应该与python 2.5一起使用。
我创建了以下2个测试视图,因为我怀疑请求是问题的一部分:
def get_requests(request):
import requests
r = requests.get("https://google.ca")
return HttpResponse(r.text)
def get_urllib(request):
import urllib2
r = urllib2.urlopen('https://google.ca')
return HttpResponse(r.read())
urllib视图有效,请求视图给出了与上面相同的错误。
urllib工作的事实向我表明Apache有权连接到互联网(这不是防火墙问题)。
我在尝试查看时已经完成了tcpdump,并且请求甚至都没有尝试连接。
有什么想法吗?请不要建议使用除请求之外的其他内容,因为我使用了2个不同的第三方API。
感谢。
答案 0 :(得分:1)
在使用安装了ssl
模块的Python 2.5中的HTTPS中,看起来您遇到了请求0.10.0(或者,实际上是在urllib3中)中的错误。
如果您浏览0.10.0 source,则可以看到如果安装了ssl
并且您发出了HTTPS请求,那么您将转到VerifiedHTTPSConnection.connect
方法。 HTTPSConnectionPool
来源的评论中也对此进行了解释。但是你甚至不需要追踪源代码,因为你已经从追溯中看到了这一点。
如果您查看the source该方法,它会无条件地调用socket.create_connection
,这可以保证在2.5中失败。
任何人都有可能修复这个错误的可能性非常小。看起来它是在0.10.0中引入的,而0.10.1只是通过降低2.5支持来解决它。 (我对此并不积极,因为我无法在错误跟踪器中找到它。)
那么,你能做些什么呢?
首先,请注意,虽然create_connection
比connect
“更高级别”,但只有在确定要创建哪种类型的套接字之前,它才进行名称查找。如果您知道自己只关心IPv4,可以将其替换为:
self.sock = socket.socket()
self.sock.settimeout(self.timeout)
self.sock.connect((self.host, self.port))
如果你关心IPv6,你可以借用create_connection
代替urllib3.connectionpool.VerifiedHTTPConnection.connect
。
所以,你有几个选择:
create_connection
以使用变通方法代替urllib3.connectionpool.VerifiedHTTPConnection.connect
。socket
在运行时。create_connection
在运行时添加{{1}}实现。但是,鉴于历史,我不想保证0.10.0不会有Python 2.5的进一步问题。
答案 1 :(得分:0)
从0.10.1开始,请求放弃了对Python 2.5的支持。
升级您的Python或使用请求0.10.0版本的请求。
0.10.1(2012-01-23)
PYTHON 3支持!下降2.5支持。 (向后不兼容)
答案 2 :(得分:0)
使用请求0.9.3。这对Python 2.5肯定有用。我们需要Python 2.5支持,并且Kenneth告诉我们使用该版本,或者这是我们发现的最新版本,它实际上在实践中有效。如果您需要返回使用该版本,请注意任何API差异。
答案 3 :(得分:0)
as abarnert pointed out,这是由请求0.10.0中的错误引起的,并且由于在版本0.10.1中删除了python 2.5支持,因此无法修复。
所以我编辑了这个文件requests / packages / urllib3 / connectionpool.py(第67行)。
原始行:
sock = socket.create_connection((self.host, self.port), self.timeout)
我将其替换为:
try:
sock = socket.create_connection((self.host, self.port), self.timeout)
except AttributeError:
# python 2.5 fix
sock = socket.socket()
if self.timeout is not None:
sock.settimeout(self.timeout)
sock.connect((self.host, self.port))
通过此更改,一切正常。