Scrapy CrawlSpider什么都没爬

时间:2017-06-19 00:18:08

标签: python scrapy scrapy-spider

我正在尝试抓取Booking.Com。蜘蛛打开和关闭,无需打开和抓取网址。[输出] [1]       [1]:https://i.stack.imgur.com/9hDt6.png     我是python和Scrapy的新手。这是我到目前为止编写的代码。请指出我做错了什么。

import scrapy
import urllib
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import Selector
from scrapy.item import Item
from scrapy.loader import ItemLoader
from CinemaScraper.items import CinemascraperItem


class trip(CrawlSpider):
 name="tripadvisor"

def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)


def parse(self, response):
        reviewsurl = response.xpath('//a[@class="show_all_reviews_btn"]/@href')
        url = response.urljoin(reviewsurl[0].extract())
        self.pageNumber = 1
        return scrapy.Request(url, callback=self.parse_reviews)


def parse_reviews(self, response):
     for rev in response.xpath('//li[starts-with(@class,"review_item")]'):
            item =CinemascraperItem()
            #sometimes the title is empty because of some reason, not sure when it happens but this works
            title = rev.xpath('.//*[@class="review_item_header_content"]/span[@itemprop="name"]/text()')
            if title:
                item['title'] = title[0].extract()
                positive_content = rev.xpath('.//p[@class="review_pos"]//span/text()')
                if positive_content:
                    item['positive_content'] = positive_content[0].extract()
                negative_content = rev.xpath('.//p[@class="review_neg"]/span/text()')
                if negative_content:
                    item['negative_content'] = negative_content[0].extract()
                item['score'] = rev.xpath('./*[@class="review_item_header_score_container"]/span')[0].extract()
                #tags are separated by ;
                item['tags'] = ";".join(rev.xpath('.//ul[@class="review_item_info_tags/text()').extract())
                yield item

     next_page = response.xpath('//a[@id="review_next_page_link"]/@href')
     if next_page:
      url = response.urljoin(next_page[0].extract())
      yield scrapy.Request(url, self.parse_reviews)

2 个答案:

答案 0 :(得分:2)

我想指出,在您的问题中,您谈到的是一个网站booking.com,但在您的蜘蛛网中,您可以找到该网站的链接,这些链接是scrapy教程的官方文档......将继续使用报价网站为了解释....

好的,我们开始......所以在您的代码片段中,您使用的是爬虫蜘蛛,其中值得一提的是,解析函数已经是Crawl蜘蛛背后逻辑的一部分。就像我之前提到的那样,通过将你的解析重命名为不同的名称,例如parse_item,这是你创建滚动蜘蛛时的默认初始函数,但如果你真实地将它命名为你想要的任何名称。通过这样做,我相信我应该抓住网站,但这完全取决于您的代码是否正确。

Screenshot of official Doc: Crawl Spider uses parse function as logic

简而言之,通用蜘蛛和它们爬行蜘蛛之间的区别在于,当使用爬行蜘蛛时,您使用诸如链接提取器之类的模块,并且规则设置某些参数,以便当起始URL遵循其模式为用于浏览页面,有各种有用的参数来做到这一点...其中最后一个规则集是汽车回到你抛光它们的那个。 换句话说......抓取蜘蛛会根据需要创建请求导航的逻辑。

enter image description here

请注意,在规则集中....我输入..." / page。" ....使用"。"是一个正则表达式,说.... "从页面进入...此页面上的任何链接都遵循模式.... / page"它将跟随AND回调到parse_item ..."

这是一个超级简单的例子......因为你可以输入模式来JUST跟随或JUST回调你的项目解析函数......

使用普通蜘蛛,您需要手动训练网站导航以获得您想要的内容...

Example generic spider

CrawlSpider

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from quotes.items import QuotesItem

class QcrawlSpider(CrawlSpider):
    name = 'qCrawl'
    allowed_domains = ['quotes.toscrape.com']
    start_urls = ['http://quotes.toscrape.com/']

    rules = (
        Rule(LinkExtractor(allow=r'page/.*'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        item = QuotesItem()
        item['quote'] =response.css('span.text::text').extract()
        item['author'] = response.css('small.author::text').extract()
        yield item

Generic Spider

import scrapy
from quotes.items import QuotesItem

class QspiSpider(scrapy.Spider):
    name = "qSpi"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ['http://quotes.toscrape.com']

    def parse(self, response):
        for quote in response.css("div.quote"):
            item = QuotesItem()
            item['quote'] = quote.css('span.text::text').extract()
            item['author'] = quote.css('small.author::text').extract()
            item['tags'] = quote.css("div.tags > a.tag::text").extract()
            yield item

        for nextPage in response.css('li.next a::attr(href)').extract():
            yield scrapy.Request(response.urljoin(nextPage))

编辑:应OP要求的附加信息

  

" ...我无法理解如何在Rule参数中添加参数"

好的......让我们看看官方文档只是为了重申抓取蜘蛛的定义......

enter image description here

因此爬行蜘蛛通过使用规则集创建了跟随链接的逻辑...现在让我说我想用爬行蜘蛛抓取craigslist仅用于待售的待售物品....我希望你注意到用红色的东西......

enter image description here

对于第一个是显示当我在craigslist house hold items items页面

所以我们收集了......"搜索/ hsh ..."将从提单页面的第一页开始显示持有物品清单的页面。

对于大红色数字" 2" ...表示当我们在实际发布的项目中时...所有项目似乎都有" ... / hsh /。 .."所以在previs页面里面的任何链接都有这个模式,我想跟随并从那里刮掉...所以我的蜘蛛会像... ...

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from craigListCrawl.items import CraiglistcrawlItem

class CcrawlexSpider(CrawlSpider):
    name = 'cCrawlEx'
    allowed_domains = ['columbia.craigslist.org']
    start_urls = ['https://columbia.craigslist.org/']

    rules = (
        Rule(LinkExtractor(allow=r'search/hsa.*'), follow=True),
        Rule(LinkExtractor(allow=r'hsh.*'), callback='parse_item'),
    )

    def parse_item(self, response):
        item = CraiglistcrawlItem()
        item['title'] = response.css('title::text').extract()
        item['description'] = response.xpath("//meta[@property='og:description']/@content").extract()
        item['followLink'] = response.xpath("//meta[@property='og:url']/@content").extract()
        yield item

我想让你把它想象一下你从登陆页面到你的内容页面所采取的步骤......所以我们登陆了这个页面,这是我们的start_url ... tSo我们说房子保留项目有一个模式,所以你可以看到第一个规则......

  

规则(LinkExtractor(允许= r'搜索/ hsa。*'),follow = True)

这里它说允许正则表达式模式"搜索/ hsa。"遵循...记住"。"是一个正则表达式,用于匹配" search / hsa"之后的任何内容。在这种情况下至少。

所以逻辑继续,然后说任何带有模式的链接" hsh。*"将被调用回我的parse_item

如果您认为它是从页面到另一个的步骤,那么"点击"它应该有所帮助......虽然完全可以接受,但是通用蜘蛛会给你最大的控制权,因为你的scrapy项目最终会占用资源,这意味着写得好的蜘蛛应该更精确,速度更快。

答案 1 :(得分:0)

您在 CrawlSpider 子类上覆盖解析方法,不建议按documentation进行

  

编写爬网蜘蛛规则时,请避免使用parse作为回调   CrawlSpider使用parse方法本身来实现其逻辑。   因此,如果您覆盖解析方法,则爬行蜘蛛将不再存在   工作

虽然,我没有在您的蜘蛛中看到规则,因此我建议您切换到scrapy.spiders.Spider而不是scrapy.spiders.CrawlSpider。只需从Spider类继承并再次运行它,它应该按预期工作。