总结自:Spiders — Scrapy 2.5.0 documentation

Spider

1、综述

①在回调函数Parse及其他自写的回调函数中,必须返回Item对象、Request对象、或前两种对象的迭代器形式。这些Requests同样也必须包含一个回调函数,之后它们的Response会被特定的回调函数处理;

注:除了start_request方法,其他方法的回调函数必须手动实现在Spider中,如果不写回调函数,会默认视为parse方法。

②在回调函数中,我们通常通过Selector(或BeautifulSoup、lxml、...)爬取页面内容,并用爬取到的数据构造Items

③这些从Spider中返回的Item通常会经过Pipeline处理之后放入数据库或者通过输出命令时的输出参数,直接输出到文件中。

2、属性

属性 说明
name Spider的名字,通常直接命名为域名,即网址中不加前缀和后缀的部分
allowed_domains 可选,允许访问的网址范围;只有当OffsiteMiddleware开启时才起作用
start_urls 一个URL List;爬虫开始的URL
custom_settings 关于要被重写的Settings的Dict;具体设置项见Built-in settings reference.
crawler 该参数通过方法from_crawler()设置,标识了爬虫绑定的Crawler对象
settings 一个Setting对象,标识爬虫运行时的配置
logger 日志

3、方法

方法 说明
from_crawler 被Scrapy用于创造spiders,通常不用管,因为该方法和__init__作用差不多,处理要传入的参数时,只需用处理__init__的方法就可以
start_requests Scrapy开始时调用该方法处理start_urls,该方法必须返回一个Request对象。Scrapy只调用该方法一次,所以用该方法创建Generator是安全的。
parse 默认回调函数(当Request并没有指定回调函数时起作用)
log 发送日志信息
closed 当Spider关闭时被调用。该方法与spider_closed标记相关联

3.5、部分方法的说明

①start_requests

如果没有重写该方法,该方法默认会对start_url中的每个URL使用方法Request(url,dont_filter=True)。

重写示例:如果你想在一开始模拟一个登录的POST请求,可以这样写:

def start_requests(self):
return [scrapy.FormRequest('http://www.example.com/login'),
formdata={'user':'jon','pass':'secret'},
callback=self.logged_in)]
def logged_in(self,response):
pass

②parse

默认回调函数;该方法返回:a、爬取到的数据(以Item形式);b、更多后续URL(以Iterable of Request形式);

其他回调函数同样需要返回以上两种数据,这里所说的几种返回形式如下:

# a、item
item['attr1']=values1
...
return item # b、request
return scrapy.Request(...) # a与b的iterable形式
yield item
yield scrapy.Request(...)

4、命令行传入Spider参数

Spider可以接收参数来修正其行为。这些参数的一般用法是:a、定义起始URLs;b、限制爬取网页的特定部分;c、也能用来设置Spider的部分功能;

Spider参数在命令行运行crawl命令时,通过-a项传递进来,传递方式为:-a attr=value

例如:

scrapy crawl myspider -a category=electronics

Spiders可以在其__init__方法中(Spider.py文件中重写__init__,而不是__init__文件中)访问这些传递进来的参数:

import scrapy
class MySpider(scrapy.Spider):
name='myspider' def __init__(self,category=None,*args,**kws):
super(MySpider,self).__init__(*args,**kw)
self.start_urls=[f'http://www.example.com/categories/{category}']

默认的__init__方法将接收任何Spider参数并将它们复制为Spiders的属性,所以这些传递进来的参数,可以在Spiders.py中的任意方法中通过self.attr的方式访问。

需要注意的是,这些传递进来的参数全都是string,且名字不要设置为start_urls

5、继承Spider

Scrapy中有许多有用的继承Spider,你可以用它们作为父类写自己的Spider。

在以下的例子中,假设我们项目中的Item文件为:

import scrapy
class TestItem(scrapy.Item):
id=scrapy.Field()
name=scrapy.Field()
description=scrapy.Field()

5.1、CrawlSpider

这个Spider是爬取有规律的URL时最常用的Spider,因为其提供了一个方便的机制去获取一系列具有一定规则的URL。

①属性

除了继承自Spider的那些属性外(见本节第2部分),还有一个属性rules

rules:一个Rule对象List,List中的每个Rule都定义了一个爬取URL的规则。如果有多种rules同时匹配了同一个URL,那么只会使用这些rule中第一个(按顺序)。

关于Rule对象,可以看5.1.③

②方法

除了继承自Spider的方法外,还有一个方法parse_start_url

该方法只为start_urls中的URL提供处理方法(原因是,首页的URL可能与那些规则并不一致,需要额外处理,这个处理函数就是该方法)。该方法同样必须返回a、Item对象;b、Request对象;c、包含上述两项的Iterable对象。

③Rule

scrapy.spiders.Rule(
link_extractor, callback,
cb_kewargs, follow, errback,
process_links, process_request
)

参数:

参数 说明
link_extractor

Link Extractor对象;定义了需要爬取的URL规则。

如果省略该项,那么视为无规则,将提取所有URL

callback

回调函数;对符合规则的URL用回调函数进行处理。

回调函数构造时,接收Response作为其第一个参数且必须返回一个Item或Request对象(或它们的Iterable)。这些Response对象将包含这些Link的文本信息,如果要访问它们的话,可以在Reponse对象的meta属性(meta是Dict)中,通过link_text作为Key访问

cb_kwargs 一个Dict;其中包含了传入回调函数中的参数
follow Boolean;每个Response中的link是否应该遵循Rule进行跟进(即每个Response中如果有符合Rule的URL,是否也对该URL进行爬取),如果没指定callback,那么该项默认为True,否则为False
process_links 符合Rule的Link进行处理的函数。可以用于筛选。当调用该方法之后,才会再调用callback方法。
process_request 对通过Rule提取到的Request调用该方法。该方法接收两个参数:Request与Response(产生参数Request的那个Response)。必须返回一个Request对象或None。
errback 异常处理调用函数

注意:

当自己写CrawlSpider子类时,需要明确指定callback响应函数,否则会产生预期之外的错误。

④例子

import scrapy
from scrapy.spiders import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor class MySpider(CrawlSpider):
name='example'
allowed_domains=['example.com']
start_urls=['http://www.example.com']
rules=(
Rule(LinkExtractor(allow=('category\.php',),deny=('subsection\.php',))),
Rule(LinkExtractor(allow=('item\.php',)),callback='parse_item'),
)
def parse_item(self,response):
self.logger.info('Hi,this is an item page!%s',response.url)
item=scrapy.Item()
item['id']=response.xpath('//td[@id="item_id"]/text()').re(r'ID:(\d+)')
item['name']=response.xpath('//td[@id="item_name"]/text()').extract()[0]
item['description']=response.xpath('//td[@id="item_description"]/text()').extract()[0]
item['link_text']=response.meta['link_text']
url=response.xpath('//td[@id="additional_data"]/@href').get()
return response.follow(url,self.parse_additional_page,cb_kwargs=dict(item=item))
def parse_additional_page(self,response,item):
item['additional_data']=response.xpath('//p[@id="additional_data"]/text()').get()
return item

这个Spider的作用是爬取example.com的首页,并收集category、item的链接,用parse_item爬取后续页面。对每个Item Response,一些数据将会从该HTML中通XPath表达式提取出来,并且这些数据将会填充到Item项。

Scrapy(六):Spider的更多相关文章

  1. eclipse+PyDev 中报错"scrapy.spiders.Spider" ,可用"# @UndefinedVariable"压制.

    # -*- coding:utf-8 -*- ''' Created on 2015年10月22日 (1.1) 例子来源: http://scrapy-chs.readthedocs.org/zh_C ...

  2. 让Scrapy的Spider更通用

    1,引言 <Scrapy的架构初探>一文所讲的Spider是整个架构中最定制化的一个部件,Spider负责把网页内容提取出来,而不同数据采集目标的内容结构不一样,几乎需要为每一类网页都做定 ...

  3. scrapy - 给scrapy 的spider 传值

    scrapy - 给scrapy 的spider 传值 方法一: 在命令行用crawl控制spider爬取的时候,加上-a选项,例如: scrapy crawl myspider -a categor ...

  4. scrapy分布式Spider源码分析及实现过程

    分布式框架scrapy_redis实现了一套完整的组件,其中也实现了spider,RedisSpider是在继承原scrapy的Spider的基础上略有改动,初始URL不在从start_urls列表中 ...

  5. Scrapy:为spider指定pipeline

    当一个Scrapy项目中有多个spider去爬取多个网站时,往往需要多个pipeline,这时就需要为每个spider指定其对应的pipeline. [通过程序来运行spider],可以通过修改配置s ...

  6. Scrapy框架-Spider和CrawlSpider的区别

    目录 1.目标 2.方法1:通过Spider爬取 3. 通过CrawlSpider爬取 1.目标 http://wz.sun0769.com/index.php/question/questionTy ...

  7. Scrapy框架-Spider

    目录 1. Spider 2.Scrapy源代码 2.1. Scrapy主要属性和方法 3.parse()方法的工作机制 1. Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取 ...

  8. scrapy之spider模块

    scrapy中的spider的用法 : 1.scrapy命令行可以传参数给构造器 scrapy crawl myspider -a category=electronics 构造器接收传入的参数 im ...

  9. 爬虫框架Scrapy之Spider

    Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作及 ...

  10. Scrapy的Spider类和CrawlSpider类

    Scrapy shell 用来调试Scrapy 项目代码的 命令行工具,启动的时候预定义了Scrapy的一些对象 设置 shell Scrapy 的shell是基于运行环境中的python 解释器sh ...

随机推荐

  1. linux面试题(重点)

    1.No space left on device ,但df -h,磁盘空间还很富余?原因是 Inode 耗尽.可以使用df -i检查.磁盘中中产生了很多小的临时文件,造成在磁盘空间耗尽之前文件系统的 ...

  2. java中的线程是如何工作的。

    来自对此文章的编辑. https://mp.weixin.qq.com/s?biz=MzA5NDg3MjAwMQ==&mid=2457103451&idx=1&sn=ba302 ...

  3. PostgreSQL逻辑订阅

    测试环境:PostgreSQL 13.2 1.逻辑订阅简介 由于物理复制只能做到这个集群的复制,不能正对某个对象(表)进行复制,且物理复制的备库只能读,不能写.相反,逻辑订阅同时支持主备库读写,且可以 ...

  4. 《Effective TypeScript》条款22 - 类型收缩

    本文主要记录书中关于TypeScript类型收缩的内容 本文主要内容如下 类型收缩的一些方法 条件判断 抛错误 instanceof 和 in 属性检查 "标签联合"或" ...

  5. JS Map与Set

    笔记整理自:廖雪峰老师的JS教程 Map JavaScript的对象有个小问题,就是键必须是字符串.但实际上Number或者其他数据类型作为键也是非常合理的. 为了解决这个问题,最新的ES6规范引入了 ...

  6. 报错 Illegal key size or default parameters

    简介: java中使用AES对称加密后,请求报错: Caused by: java.lang.RuntimeException: java.security.InvalidKeyException: ...

  7. push自定义动画

    // //  ViewController.m //  ViewControllerAnimation // //  Created by mac on 15/5/26. //  Copyright ...

  8. 动态路由与RIP协议

    动态路由与RIP协议 目录 动态路由与RIP协议 一.动态路由(Dynamic Route) 1.动态路由概述 2.动态路由特点 3.动态路由协议 (1)动态路由协议概述 (2)度量值 (3)收敛 4 ...

  9. Spark RDD学习

    RDD(弹性分布式数据集)是Spark的核心抽象.它是一组元素,在集群的节点之间进行分区,以便我们可以对其执行各种并行操作. 创建RDD的两种方式: 并行化驱动程序中的现有数据: 引用外部存储系统中的 ...

  10. Centos7系统使用yum遇到的问题failure: repodata/repomd.xml from base: [Errno 256] No more mirrors to try.

    简单粗暴重新安装yum. 1.查看linux上所有的yum包 # rpm -qa|grep yum 2.逐个卸载,如 # rpm -e yum-plugin-fastestmirror-1.1.31- ...