理解Scrapy的CrawlSpider规则

8 投票
1 回答
4037 浏览
提问于 2025-04-18 18:16

我在使用继承自CrawlSpider的自己的爬虫时,遇到了一些问题,特别是关于规则字段的使用。我这个爬虫是想在旧金山的黄页上爬取披萨店的信息。

我尝试把规则设置得简单一些,只是想看看爬虫是否能通过响应中的链接进行爬取,但我没有看到这样的情况。我的结果只是发出了请求去获取下一页,然后又发出了请求去获取后续的页面。

我有两个问题: 1. 当响应到达时,爬虫是先处理规则再调用回调函数吗?还是相反? 2. 规则是什么时候应用的?

编辑: 我搞明白了。我重写了CrawlSpider中的解析方法。查看那个类中的解析方法后,我意识到正是在那里检查规则并爬取那些网站。

注意:要知道你在重写什么

这是我的代码:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy import Selector
from yellowPages.items import YellowpagesItem
from scrapy.http import Request

class YellowPageSpider(CrawlSpider):
    name = "yellowpages"
    allowed_domains = ['www.yellowpages.com']
    businesses = []

    # start with one page
    start_urls = ['http://www.yellowpages.com/san-francisco-ca/pizza?g=san%20francisco%2C%20ca&q=pizza']

    rules = (Rule (SgmlLinkExtractor()
    , callback="parse_items", follow= True),
    )

    base_url = 'http://www.yellowpages.com'

    def parse(self, response):
        yield Request(response.url, callback=self.parse_business_listings_page)

    def parse_items(self, response):
        print "PARSE ITEMS. Visiting %s" % response.url
        return []

    def parse_business_listings_page(self, response):
        print "Visiting %s" % response.url

        self.businesses.append(self.extract_businesses_from_response(response))
        hxs = Selector(response)
        li_tags = hxs.xpath('//*[@id="main-content"]/div[4]/div[5]/ul/li')
        next_exist = False

        # Check to see if there's a "Next". If there is, store the links.
        # If not, return. 
        # This requires a linear search through the list of li_tags. Is there a faster way?
        for li in li_tags:
            li_text = li.xpath('.//a/text()').extract()
            li_data_page = li.xpath('.//a/@data-page').extract()
            # Note: sometimes li_text is an empty list so check to see if it is nonempty first
            if (li_text and li_text[0] == 'Next'):
                next_exist = True
                next_page_num = li_data_page[0]
                url = 'http://www.yellowpages.com/san-francisco-ca/pizza?g=san%20francisco%2C%20ca&q=pizza&page='+next_page_num
                yield Request(url, callback=self.parse_business_listings_page)

1 个回答

2


针对你的两个问题,直接说重点吧。

  1. 在发出请求之前,爬虫的规则会先被处理。如果响应不符合允许的域名,理论上会收到响应,但会被丢弃。

  2. 爬虫规则在发出请求之前就会被使用。

注意!

在你的例子中,当你调用 parse() 方法时……虽然在你的情况下你是对的吧?!需要运行一下才能确认,但对于你们这些读者来说,除非你在爬虫中明确重写了 parse() 方法……在使用爬虫时,爬虫中的 parse() 方法相当于 crawl spider 中的 parse_item()。在爬虫中,parse() 是一个独立的逻辑函数……在规则集中作为回调使用是不应该的。

https://doc.scrapy.org/en/latest/topics/spiders.html

撰写回答