如何从pycurl多卷曲请求中获取响应主体

时间:2013-03-30 22:15:26

标签: python python-2.7 pycurl stringio

执行curl多个请求时,我无法获得任何空响应。没有抛出异常,但响应值没有内容(在下面的代码段中注释)

以下是我的代码的简化版本:

from StringIO import StringIO

import pycurl


class CurlStream(object):
    curl_count = 0
    curl_storage = []

    def __init__(self):
        self.curl_multi = pycurl.CurlMulti()

    def add_request(self, request, post_fields=None):
        self.curl_count += 1
        curl = self._create_curl(request, post_fields)
        self.curl_multi.add_handle(curl)

    def perform(self):
        while self.curl_count:
            while True:
                response, self.curl_count = self.curl_multi.perform()
                if response != pycurl.E_CALL_MULTI_PERFORM:
                    break
            self.curl_multi.select(1.0)

    def read_all(self):
        for response in self.curl_storage:
            print response.getvalue() # this does nothing --prints blank lines

    def close(self):
        self.curl_multi.close()

    def _create_curl(self, request, post_fields):
        curl = pycurl.Curl()
        output = StringIO()
        self.curl_storage.append(output)
        curl.setopt(curl.URL, request)
        curl.setopt(curl.WRITEFUNCTION, output.write)
        curl.setopt(curl.TIMEOUT, 20)
        return curl


def main():
    curl_stream = CurlStream()
    curl_stream.add_request('http://www.google.com')
    curl_stream.add_request('http://www.example.com')
    curl_stream.perform()
    curl_stream.read_all()
    curl_stream.close()

if __name__ == '__main__':
    main()

我使用相同的选项发出单个请求而不使用curl multi,它可以正常工作。

1 个答案:

答案 0 :(得分:1)

好的,所以当我将_create_curl方法更改为此(添加write_out进行调试)时,我发现它有效:

def _create_curl(self, request, post_fields):
    curl = pycurl.Curl()
    curl.setopt(curl.URL, request)
    curl.setopt(curl.WRITEFUNCTION, self.write_out)
    curl.setopt(curl.TIMEOUT, 20)

    # Below is the important bit, I am now adding each curl object to a list
    self.curl_storage.append(curl)
    return curl

def write_out(self, data):
        print data
        return len(data)

问题是当将curl对象添加到multicurl对象时,我没有保留对单个curl对象的任何引用,因此它是自动关闭的。

根据curl close()方法的pycurl docs

  

对应于libcurl中的curl_easy_cleanup。这个方法是   当Curl对象不再具有任何内容时,由pycurl自动调用   引用它,但也可以明确调用。