Следующие ссылки, Scrapy Web Crawler Framework - PullRequest
9 голосов
/ 06 июля 2011

После нескольких чтений документов Scrapy я все еще не замечаю различий между использованием правил CrawlSpider и реализацией собственного механизма извлечения ссылок в методе обратного вызова.

Я собираюсь написать новый веб-сканер, используяпоследний подход, но только потому, что у меня был плохой опыт в прошлом проекте с использованием правил.Мне бы очень хотелось точно знать, что я делаю и почему.

Кто-нибудь знаком с этим инструментом?

Спасибо за вашу помощь!

Ответы [ 2 ]

11 голосов
/ 06 июля 2011

CrawlSpider наследует BaseSpider.Здесь просто добавлены правила для извлечения и перехода по ссылкам.Если эти правила недостаточно гибки для вас - используйте BaseSpider:

class USpider(BaseSpider):
    """my spider. """

    start_urls = ['http://www.amazon.com/s/?url=search-alias%3Dapparel&sort=relevance-fs-browse-rank']
    allowed_domains = ['amazon.com']

    def parse(self, response):
        '''Parse main category search page and extract subcategory search link.'''
        self.log('Downloaded category search page.', log.DEBUG)
        if response.meta['depth'] > 5:
            self.log('Categories depth limit reached (recursive links?). Stopping further following.', log.WARNING)

        hxs = HtmlXPathSelector(response)
        subcategories = hxs.select("//div[@id='refinements']/*[starts-with(.,'Department')]/following-sibling::ul[1]/li/a[span[@class='refinementLink']]/@href").extract()
        for subcategory in subcategories:
            subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink)
            yield Request(subcategorySearchLink, callback = self.parseSubcategory)

    def parseSubcategory(self, response):
        '''Parse subcategory search page and extract item links.'''
        hxs = HtmlXPathSelector(response)

        for itemLink in hxs.select('//a[@class="title"]/@href').extract():
            itemLink = urlparse.urljoin(response.url, itemLink)
            self.log('Requesting item page: ' + itemLink, log.DEBUG)
            yield Request(itemLink, callback = self.parseItem)

        try:
            nextPageLink = hxs.select("//a[@id='pagnNextLink']/@href").extract()[0]
            nextPageLink = urlparse.urljoin(response.url, nextPageLink)
            self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG)
            yield Request(nextPageLink, callback = self.parseSubcategory)
        except:
            self.log('Whole category parsed: ' + categoryPath, log.DEBUG)

    def parseItem(self, response):
        '''Parse item page and extract product info.'''

        hxs = HtmlXPathSelector(response)
        item = UItem()

        item['brand'] = self.extractText("//div[@class='buying']/span[1]/a[1]", hxs)
        item['title'] = self.extractText("//span[@id='btAsinTitle']", hxs)
        ...

Даже если start_urls BaseSpider не достаточно гибки для вас, переопределите start_requests метод.

1 голос
/ 06 июля 2011

Если вы хотите избирательное сканирование, например выбор ссылок «Next» для разбивки на страницы и т. Д., Лучше написать собственный сканер. Но для общего сканирования вы должны использовать crawlspider и отфильтровать ссылки, которые вам не нужны, используя функцию Rules & process_links.

Взгляните на код сканера в \scrapy\contrib\spiders\crawl.py, он не слишком сложен.

...