1

以前、Node.js でアプリケーション、特にデータ スクレイパーを作成しました。これらのタイプのアプリケーションには Web フロント エンドがありませんでしたが、単に cron ジョブとタイミングを合わせて、Web ページをプルするための複雑な HTTP GET 要求を非同期的に作成し、結果からデータをスクレイピングして保存するプロセスでした。

私が書く関数のサンプルは次のようになります:

// Node.js

var request = require("request");

function scrapeEverything() {
    var listOfIds = [23423, 52356, 63462, 34673, 67436];

    for (var i = 0; i < listOfIds.length; i++) {
        request({uri: "http://mydatasite.com/?data_id = " + listOfIds[i]},
                function(err, response, body) {
                     var jsonobj = JSON.parse(body);
                      storeMyData(jsonobj);
                });
    }
}

この関数は ID をループし、一連の非同期 GET 要求を作成し、そこからデータを保存します。

私は現在、Python でスクレーパーを作成しており、Tornado を使用して同じことを試みていますが、ドキュメントに記載されているものはすべて、Tornado が Web サーバーとして機能していることを示しており、これは私が探しているものではありません。誰でもこれを行う方法を知っていますか?

4

3 に答える 3

2

一緒に投げると思っていたよりも少し複雑な答えですが、Tornado ioloop と AsyncHTTPClient を使用してデータをフェッチする方法の簡単なデモです。私は実際にトルネードでウェブクローラーを書いたので、「ヘッドレス」で使用できます。

import tornado.ioloop
import tornado.httpclient

class Fetcher(object):
    def __init__(self, ioloop):
        self.ioloop = ioloop
        self.client = tornado.httpclient.AsyncHTTPClient(io_loop=ioloop)

    def fetch(self, url):
        self.client.fetch(url, self.handle_response)

    @property
    def active(self):
        """True if there are active fetching happening"""

        return len(self.client.active) != 0

    def handle_response(self, response):
        if response.error:
            print "Error:", response.error
        else:
            print "Got %d bytes" % (len(response.body))

        if not self.active:
            self.ioloop.stop()

def main():
    ioloop = tornado.ioloop.IOLoop.instance()
    ioloop.add_callback(scrapeEverything)
    ioloop.start()

def scrapeEverything():
    fetcher = Fetcher(tornado.ioloop.IOLoop.instance())

    listOfIds = [23423, 52356, 63462, 34673, 67436]

    for id in listOfIds:
        fetcher.fetch("http://mydatasite.com/?data_id=%d" % id)

if __name__ == '__main__':
    main()
于 2012-07-18T18:29:14.337 に答える
1

トルネードに代わるものを受け入れている場合 (urllib2 の代わりにソケット プログラミングを使用してスクレイピングすると仮定します)、非同期、並行 (および分散、フォールト トレラント) プログラミングのフレームワークであるasyncoroに興味があるかもしれません。asyncoro を使用したプログラミングは、いくつかの構文上の変更を除いて、スレッドのプログラミングと非常によく似ています。問題は asyncoro で次のように実装できます。

import asyncoro, socket

def process(url, coro=None):
    # create asynchronous socket
    sock = asyncoro.AsynCoroSocket(socket.socket())
    # parse url to get host, port; prepare get_request
    yield sock.connect((host, port))
    yield sock.send(get_request)
    body = yield sock.recv()
    # ...
    # process body

for i in [23423, 52356, 63462, 34673, 67436]:
    asyncoro.Coro(process, "http://mydatasite.com/?data_id = %s" % i)
于 2012-07-18T15:12:11.747 に答える
0

外部ライブラリを必要としないネイティブ ソリューションを試すこともできます。Linux の場合、これは epoll に基づいており、次のようになります。使用例:

# ------------------------------------------------------------------------------------
def sampleCallback(status, data, request):
    print 'fetched:', status, len(data)
    print data

# ------------------------------------------------------------------------------------
fetch(HttpRequest('google.com:80', 'GET', '/', None, sampleCallback))
于 2015-06-10T11:11:27.847 に答える