it-swarm.com.de

Scrapy - wie man Cookies/Sitzungen verwaltet

Ich bin etwas verwirrt darüber, wie Cookies mit Scrapy funktionieren und wie Sie diese Cookies verwalten.

Dies ist im Grunde eine vereinfachte Version dessen, was ich versuche: enter image description here


So funktioniert die Website:

Wenn Sie die Website besuchen, erhalten Sie ein Session-Cookie.

Wenn Sie eine Suche durchführen, merkt sich die Website, wonach Sie gesucht haben. Wenn Sie also beispielsweise die nächste Ergebnisseite aufrufen, weiß sie, welche Suche sie ausführt.


Mein Skript:

Meine Spinne hat eine Start-URL von searchpage_url

Die Suchseite wird von parse() angefordert und die Antwort des Suchformulars wird an search_generator() übergeben.

search_generator()s dann yields viele Suchanfragen mit FormRequest und der Antwort des Suchformulars.

Für jede dieser FormRequests und nachfolgende untergeordnete Anforderungen muss eine eigene Sitzung vorhanden sein. Daher muss ihre eigene individuelle Cookie-Box und ein eigener Session-Cookie vorhanden sein.


Ich habe den Abschnitt der Dokumente gesehen, in dem es um eine Meta-Option geht, die verhindert, dass Cookies zusammengeführt werden. Was heißt das eigentlich? Bedeutet das, dass die Spinne, die die Anfrage stellt, für den Rest ihres Lebens eine eigene Keksdose hat?

Wenn sich die Cookies dann auf einer Spinnenebene befinden, wie funktioniert es dann, wenn mehrere Spinnen erzeugt werden? Ist es möglich, dass nur der erste Anforderungsgenerator neue Spinnen hervorbringt und sichergestellt wird, dass nur diese Spinne künftige Anforderungen bearbeitet?

Ich gehe davon aus, dass ich mehrere gleichzeitige Anfragen deaktivieren muss. Andernfalls führt ein Spider mehrere Suchvorgänge unter demselben Session-Cookie durch, und zukünftige Anfragen beziehen sich nur auf die zuletzt durchgeführte Suche.

Ich bin verwirrt, jede Klarstellung würde großartig aufgenommen werden!


BEARBEITEN:

Eine weitere Option, an die ich gerade gedacht habe, ist die manuelle Verwaltung des Sitzungscookies und die Weitergabe von einer Anfrage an die andere.

Ich denke, das würde bedeuten, Cookies zu deaktivieren ... und dann das Sitzungscookie aus der Suchantwort zu nehmen und an jede nachfolgende Anfrage weiterzugeben.

Ist es das, was Sie in dieser Situation tun sollten?

45
Acorn

Drei Jahre später denke ich, dass Sie genau das haben, wonach Sie gesucht haben: http://doc.scrapy.org/de/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar

Verwenden Sie einfach so etwas in der start_requests-Methode Ihrer Spinne:

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

Denken Sie daran, dass Sie für nachfolgende Anfragen die Cookie-Box jedes Mal explizit erneut anbringen müssen:

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)
35
Noah_S
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)
5
warvariuc

Ich denke, der einfachste Ansatz wäre, mehrere Instanzen derselben Spinne mit der Suchabfrage als Spinnenargument auszuführen (das im Konstruktor empfangen würde), um die Cookies-Verwaltungsfunktion von Scrapy wiederzuverwenden. Sie haben also mehrere Spider-Instanzen, von denen jede eine bestimmte Suchabfrage und ihre Ergebnisse durchsucht. Aber du musst die Spinnen selbst laufen lassen mit: 

scrapy crawl myspider -a search_query=something

Oder Sie können Scrapyd verwenden, um alle Spider über die JSON-API auszuführen.

1
Pablo Hoffman
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
    )
0
MKatleast3