Scrapy Spider

爬虫 Spider 是一个定义如何抓取某个网站的类,包括如何执行抓取以及如何从其网页中提取结构化数据。换句话说,Spider是您定义用于为特定网站抓取和解析网页的自定义行为的位置。

 

1. Spider 工作流程

对于一个爬虫 Spider,工作流程如下:

  • 首先,生成用于抓取第一个 URL 的初始请求,然后指定处理响应的回调函数。第一个执行的请求,通过调用 start_requests() 方法生成,在里面指定 URL和解析函数。
  • 其次,在回调函数中,通常使用选择器来解析响应的网页内容,并返回提取的数据,保存在 Item 对象。
  • 最后,从爬虫返回的 Item 对象存储到数据库或者文件中。

整个流程循环执行,这个循环适用于任何种类的爬虫。

 

2. scrapy.spiders.Spider 类

scrapy.spiders.Spider 是最简单的爬虫,每个其他爬虫必须继承的爬虫基类。scrapy.spiders.Spider 不提供任何特殊功能,只是提供了一个默认start_requests()实现,并使用 parse 处理每个响应结果。以下是 scrapy.spiders.Spider 的一些常用的属性。

1)name

定义此爬虫名称的字符串。爬虫名称必须唯一。它是最重要的爬虫属性,是必需的。

2)allowed_domains

允许爬虫抓取域的列表,不在列表中的域不会被抓取。

3)start_urls

当爬虫起始抓取的网址列表。

4)settings

运行此爬虫的配置。这是一个 Settings实例。

5)custom_settings

运行此爬虫时的项目自定义配置。

6)start_requests()

此方法必须返回一个可迭代的第一个请求。有了start_requests(),就不需要写 start_urls,写了也没有用。

 

2. Spider 范例

例如,抓取多个 URL:

import scrapy

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]

    def parse(self, response):
        self.logger.info('A response from %s just arrived!', response.url)

例如,从回调中再次产生多个抓取请求:

import scrapy

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield {"title": h3}

        for url in response.xpath('//a/@href').extract():
            yield scrapy.Request(url, callback=self.parse)

你可以直接使用 start_requests(),而不是 start_urls:

import scrapy
from myproject.items import MyItem

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']

    def start_requests(self):
        yield scrapy.Request('http://www.example.com/1.html', self.parse)
        yield scrapy.Request('http://www.example.com/2.html', self.parse)
        yield scrapy.Request('http://www.example.com/3.html', self.parse)

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield MyItem(title=h3)

        for url in response.xpath('//a/@href').extract():
            yield scrapy.Request(url, callback=self.parse)

 

3. Spider 参数

爬虫可以接收修改其行为的参数。爬虫参数常见用法是定义起始 URL 或某些限制。

Spider crawl 命令中可以使用该 -a 选项传递参数。例如:

scrapy crawl myspider -a category=electronics

爬虫可以在他们的init方法中访问参数:

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'

    def __init__(self, category=None, *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs)
        self.start_urls = ['http://www.example.com/categories/%s' % category]
        # ...

默认的init方法将获取任何爬虫参数,并将它们作为属性复制到爬虫。上面的例子也可以写成如下::

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'

    def start_requests(self):
        yield scrapy.Request('http://www.example.com/categories/%s' % self.category)

请记住,spider参数只是字符串。爬虫不会自己做任何解析。