3

ストリーミング中に URL を取得して解析するための高速な方法が必要です。理想的には、これは超高速であるべきです。私が選んだ言語は Python です。私はツイストがこれを行うことができるという直感を持っていますが、例を見つけるのに途方に暮れています.

4

2 に答える 2

7

ストリーミング方式で HTTP 応答を処理する必要がある場合は、いくつかのオプションがあります。

あなたはそれを行うことができますdownloadPage

from xml.sax import make_parser
from twisted.web.client import downloadPage

class StreamingXMLParser:
    def __init__(self):
        self._parser = make_parser()

    def write(self, bytes):
        self._parser.feed(bytes)

    def close(self):
        self._parser.feed('', True)

parser = StreamingXMLParser()
d = downloadPage(url, parser)
# d fires when the response is completely received

これが機能するのは、渡されたファイルのようなdownloadPageオブジェクトに応答本文を書き込むためです。ここでは、メソッドを使用してオブジェクトを渡すことでその要件を満たしますが、データをディスクに置く代わりに XML として段階的に解析します。writeclose

別のアプローチは、HTTPPageGetterレベルで物事にフックすることです。 HTTPPageGetterによって内部的に使用されるプロトコルですgetPage

class StreamingXMLParsingHTTPClient(HTTPPageGetter):
    def connectionMade(self):
        HTTPPageGetter.connectionMade(self)
        self._parser = make_parser()

    def handleResponsePart(self, bytes):
        self._parser.feed(bytes)

    def handleResponseEnd(self):
        self._parser.feed('', True)
        self.handleResponse(None) # Whatever you pass to handleResponse will be the result of the Deferred below.

factory = HTTPClientFactory(url)
factory.protocol = StreamingXMLParsingHTTPClient
reactor.connectTCP(host, port, factory)
d = factory.deferred
# d fires when the response is completely received

最後に、新しい HTTP クライアント API が間もなく登場します。これはまだどのリリースにも含まれていないため、前の 2 つのアプローチほど直接的に役立つわけではありませんが、多少優れているので、将来何がもたらされるかを理解するために含めることにします。:) 新しい API では、応答本文を受信するプロトコルを指定できます。したがって、次のようにします。

class StreamingXMLParser(Protocol):
    def __init__(self):
        self.done = Deferred()

    def connectionMade(self):
        self._parser = make_parser()

    def dataReceived(self, bytes):
        self._parser.feed(bytes)

    def connectionLost(self, reason):
        self._parser.feed('', True)
        self.done.callback(None)

from twisted.web.client import Agent
from twisted.internet import reactor

agent = Agent(reactor)
d = agent.request('GET', url, headers, None)
def cbRequest(response):
    # You can look at the response headers here if you like.
    protocol = StreamingXMLParser()
    response.deliverBody(protocol)
    return protocol.done
d.addCallback(cbRequest) # d fires when the response is fully received and parsed
于 2009-11-06T21:16:18.097 に答える