61

CookieがScrapyとどのように連携するか、およびそれらのCookieをどのように管理するかについて少し混乱しています。

これは基本的に私がやろうとしていることの単純化されたバージョンです: ここに画像の説明を入力してください


ウェブサイトの仕組み:

Webサイトにアクセスすると、セッションCookieを取得します。

あなたが検索をするとき、ウェブサイトはあなたが検索したものを記憶しているので、あなたが結果の次のページに行くようなことをするとき、それはそれが扱っている検索を知っています。


私のスクリプト:

私のスパイダーの開始URLはsearchpage_urlです。

検索ページはによって要求されparse()、検索フォームの応答はに渡されますsearch_generator()

search_generator()次に、と検索フォームの応答yieldを使用した多数の検索要求。FormRequest

これらの各FormRequestとそれに続く子リクエストには、独自のセッションが必要であるため、独自の個別のcookiejarと独自のセッションcookieが必要です。


クッキーのマージを停止するメタオプションについて説明しているドキュメントのセクションを見てきました。それは実際にはどういう意味ですか?それは、リクエストを行うスパイダーが、その存続期間中、独自のcookiejarを持つことを意味しますか?

クッキーがスパイダーごとのレベルにある場合、複数のスパイダーがスポーンされたときにどのように機能しますか?最初のリクエストジェネレーターのみが新しいスパイダーを生成し、それ以降はそのスパイダーのみが将来のリクエストを処理するようにすることは可能ですか?

複数の同時リクエストを無効にする必要があると思います。そうしないと、1つのスパイダーが同じセッションCookieで複数の検索を行い、将来のリクエストは最後に行われた検索にのみ関連しますか?

私は混乱しています、どんな説明も大いに受け取られるでしょう!


編集:

私が今考えたもう1つのオプションは、セッションCookieを完全に手動で管理し、ある要求から別の要求に渡すことです。

これは、Cookieを無効にしてから、検索応答からセッションCookieを取得し、それを後続の各要求に渡すことを意味すると思います。

これはあなたがこの状況ですべきことですか?

4

5 に答える 5

52

3年後、これはまさにあなたが探していたものだと思います: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std: reqmeta-cookiejar

スパイダーのstart_requestsメソッドで次のようなものを使用してください。

for i, url in enumerate(urls):
    yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
        callback=self.parse_page)

また、後続のリクエストでは、毎回明示的にcookiejarを再アタッチする必要があることに注意してください。

def parse_page(self, response):
    # do some processing
    return scrapy.Request("http://www.example.com/otherpage",
        meta={'cookiejar': response.meta['cookiejar']},
        callback=self.parse_other_page)
于 2014-08-26T22:33:09.907 に答える
7
from scrapy.http.cookies import CookieJar
...

class Spider(BaseSpider):
    def parse(self, response):
        '''Parse category page, extract subcategories links.'''

        hxs = HtmlXPathSelector(response)
        subcategories = hxs.select(".../@href")
        for subcategorySearchLink in subcategories:
            subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink)
            self.log('Found subcategory link: ' + subcategorySearchLink), log.DEBUG)
            yield Request(subcategorySearchLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True})
            '''Use dont_merge_cookies to force site generate new PHPSESSID cookie.
            This is needed because the site uses sessions to remember the search parameters.'''

    def extractItemLinks(self, response):
        '''Extract item links from subcategory page and go to next page.'''
        hxs = HtmlXPathSelector(response)
        for itemLink in hxs.select(".../a/@href"):
            itemLink = urlparse.urljoin(response.url, itemLink)
            print 'Requesting item page %s' % itemLink
            yield Request(...)

        nextPageLink = self.getFirst(".../@href", hxs)
        if nextPageLink:
            nextPageLink = urlparse.urljoin(response.url, nextPageLink)
            self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG)
            cookieJar = response.meta.setdefault('cookie_jar', CookieJar())
            cookieJar.extract_cookies(response, response.request)
            request = Request(nextPageLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True, 'cookie_jar': cookieJar})
            cookieJar.add_cookie_header(request) # apply Set-Cookie ourselves
            yield request
        else:
            self.log('Whole subcategory scraped.', log.DEBUG)
于 2011-06-22T08:46:39.353 に答える
1

最も簡単なアプローチは、ScrapyのCookie管理機能を再利用するために、検索クエリをスパイダー引数(コンストラクターで受信される)として使用して、同じスパイダーの複数のインスタンスを実行することだと思います。したがって、複数のスパイダーインスタンスがあり、それぞれが1つの特定の検索クエリとその結果をクロールします。しかし、あなたは自分でスパイダーを実行する必要があります:

scrapy crawl myspider -a search_query=something

または、Scrapydを使用して、JSONAPIを介してすべてのスパイダーを実行できます。

于 2011-02-13T14:33:43.380 に答える
1
def parse(self, response):
    # do something
    yield scrapy.Request(
        url= "http://new-page-to-parse.com/page/4/",
        cookies= {
            'h0':'blah',
            'taeyeon':'pretty'
        },
        callback= self.parse
    )
于 2016-02-12T07:57:58.117 に答える
1

Scrapyには、Cookieをサポートするために実装されたダウンローダーミドルウェアがあります。CookiesMiddleware有効にする必要があります。これは、ブラウザのcookiejarがどのように機能するかを模倣しています。

  • リクエストが通過するCookiesMiddlewareと、このドメインのCookieを読み取り、ヘッダーに設定しますCookie
  • 応答が戻ったら、CookiesMiddlewareサーバーから送信されたCookieをrespヘッダーで読み取りますSet-Cookie。そしてそれをmwのcookiejarに保存/マージします。

クッキーのマージを停止するメタオプションについて説明しているドキュメントのセクションを見てきました。それは実際にはどういう意味ですか?それは、リクエストを行うスパイダーが、その存続期間中、独自のcookiejarを持つことを意味しますか?

クッキーがスパイダーごとのレベルにある場合、複数のスパイダーがスポーンされたときにどのように機能しますか?

すべてのスパイダーには、唯一のダウンロードミドルウェアがあります。したがって、スパイダーには個別のcookiejarがあります。

通常、1つのスパイダーからのすべてのリクエストは1つのcookiejarを共有します。ただし、CookiesMiddlewareこの動作をカスタマイズするオプションがあります

  • Request.meta["dont_merge_cookies"] = TrueCookieこの非常に要求がcookiejarから読み取らないことをmwに通知します。Set-Cookieまた、respからcookiejarにマージしないでください。これは、要求レベルスイッチです。
  • CookiesMiddleware複数のcookiejarをサポートします。リクエストレベルで使用するcookiejarを制御する必要があります。Request.meta["cookiejar"] = custom_cookiejar_name

のドキュメントと関連するソースコードをご覧くださいCookiesMiddleware

于 2021-08-04T10:59:13.720 に答える