2016-11-22 167 views
1

我目前在使用扭曲的python库访问通过https托管的内容时遇到了一些问题。我对这个图书馆很陌生,并且假设我缺少一些导致问题的概念,但可能不是基于这个例子。扭曲的HTTPS客户端

这里是一个网页的链接中,我收集到的例子: https://twistedmatrix.com/documents/current/web/howto/client.html

在标题基于SSL的HTTP

from twisted.python.log import err 
 
from twisted.web.client import Agent 
 
from twisted.internet import reactor 
 
from twisted.internet.ssl import optionsForClientTLS 
 

 
def display(response): 
 
    print("Received response") 
 
    print(response) 
 

 
def main(): 
 
    contextFactory = optionsForClientTLS(u"https://example.com/") 
 
    agent = Agent(reactor, contextFactory) 
 
    d = agent.request("GET", "https://example.com/") 
 
    d.addCallbacks(display, err) 
 
    d.addCallback(lambda ignored: reactor.stop()) 
 
    reactor.run() 
 

 
if __name__ == "__main__": 
 
    main()

运行此代码,它直线上升失败。我得到的,看起来像这样的错误:

Traceback (most recent call last): 
 
    File "https.py", line 19, in <module> 
 
    main() 
 
    File "https.py", line 11, in main 
 
    contextFactory = optionsForClientTLS(u"https://example.com/") 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1336, in optionsForClientTLS 
 
    return ClientTLSOptions(hostname, certificateOptions.getContext()) 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1198, in __init__ 
 
    self._hostnameBytes = _idnaBytes(hostname) 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 86, in _idnaBytes 
 
    return idna.encode(text) 
 
    File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 355, in encode 
 
    result.append(alabel(label)) 
 
    File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 276, in alabel 
 
    check_label(label) 
 
    File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 253, in check_label 
 
    raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) 
 
idna.core.InvalidCodepoint: Codepoint U+003A at position 6 of u'https://example' not allowed

此错误导致我相信参数传递到optionsForClientTLS是不正确的。它需要一个主机名,而不是一个完整的URL,所以我简化了参数example.com。一旦完成这一更改,该功能就会成功完成。

不幸的是,在做出更改之后,脚本现在在调用agent.request时失败。它提供的错误是这样的:

Traceback (most recent call last): 
 
    File "https.py", line 19, in <module> 
 
    main() 
 
    File "https.py", line 13, in main 
 
    d = agent.request("GET", "https://example.com/") 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1596, in request 
 
    endpoint = self._getEndpoint(parsedURI) 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1580, in _getEndpoint 
 
    return self._endpointFactory.endpointForURI(uri) 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1456, in endpointForURI 
 
    uri.port) 
 
    File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 982, in creatorForNetloc 
 
    context = self._webContextFactory.getContext(hostname, port) 
 
AttributeError: 'ClientTLSOptions' object has no attribute 'getContext'

这个错误使我相信,通过optionsForClientTLS正在生产的对象是不是有望在创建要传递到代理的对象类型。正在尝试调用一个不存在的函数。尽管如此,我有两个问题。

  1. 此示例已弃用?前面的例子使得http请求都像魅力一样工作。我做错了什么,或者这个例子不再有效?
  2. 我只是在寻找一种简单的方法来使用HTTPS从服务器检索数据。如果以这种方式做事不是解决方案,是否有人熟悉HTTPS请求如何使用twisted?

回答

1

是的,你是绝对正确的,在文档上的例子是错误的。我注意到了错误while working w/ treq。请尝试从v14开始关注this example。这就是说,你应该使用treq而不是尝试直接使用Twisted。大部分繁重的工作已经为你照顾。这里是你的榜样的简单的换算:

from __future__ import print_function 
import treq 
from twisted.internet import defer, task 
from twisted.python.log import err 

@defer.inlineCallbacks 
def display(response): 
    content = yield treq.content(response) 
    print('Content: {0}'.format(content)) 

def main(reactor): 
    d = treq.get('https://twistedmatrix.com') 
    d.addCallback(display) 
    d.addErrback(err) 
    return d 

task.react(main) 

正如你可以看到treq照顾的SSL东西给你。 display()回调函数可用于提取HTTP响应的各个组件,如标头,状态码,主体等。如果您只需要单个组件(如响应主体),则可以进一步简化如下:

def main(reactor): 
    d = treq.get('https://twistedmatrix.com') 
    d.addCallback(treq.content)  # get response content when available 
    d.addErrback(err) 
    d.addCallback(print) 
    return d 

task.react(main) 
+0

你是圣人!非常感谢你的帮助。Treq的工作非常好,可以让我继续工作。你是一颗宝石,我感谢你和你所做的一切。 – w33t

+0

我很高兴能够帮助:D很高兴听到人们在DMV区域使用Python/Twisted。 –