1

CrawlSpider から派生したスパイダーがあります。URL が特定の形式の場合、parse_item という名前の関数へのコールバックを行います。

rules = (
    Rule( 
        LinkExtractor( 
            allow=('/whatever/', )
        )
    ), 

    Rule(
        LinkExtractor(
            allow=('/whatever/detailpage/1234/')
        ), 
        callback='parse_item'
    ),
)

スパイダーのステータスは only_new=True です。この状態が有効になっている場合、データベースに既に存在する URL をクロールしたくありません。

クロールしたい新しい詳細ページが 5 つあるが、クロールしたくない詳細ページが 1000 ある場合、1000 ではなく 5 つのリクエストを送信したいので、リクエストが完了する前に URL を確認したいと思います。

ただし、コールバック関数では、リクエストは既に行われています。次のようなことをしたいと思います:

rules = (
   (...)

    Rule(
        LinkExtractor(
            allow=('/whatever/detailpage/1234/')
        ), 
        callback_before_request='check_if_request_is_nessesary'
    ),
)

def check_if_request_is_nessesary(spider, url):
    if spider.only_new and url_exists_in_database():
        raise IgnoreRequest
    else:
        do_request_and_call_parse_item(url)

これはミドルウェアなどで可能ですか?

4

1 に答える 1

3

process_linksRuleの属性を探しています。これLinkにより、 によって返されるオブジェクトのリストをフィルタリングするために使用する callable またはメソッド名を指定できますLinkExtractor

コードは次のようになります。

rules = (
   (...)

    Rule(
        LinkExtractor(
            allow=('/whatever/detailpage/1234/')
        ), 
        process_links='filter_links_already_seen'
    ),
)

def filter_links_already_seen(self, links):
    for link in links:
        if self.only_new and url_exists_in_database(link.url):
            continue
        else:
            yield link
于 2014-12-25T21:17:45.417 に答える