阅读背景:

Python笔记:爬虫框架Scrapy之Spider的原理

来源:互联网 
Scrapy中的Spider概述 在Scrapy中,要抓取网站的链接配置、抓取逻辑、解析逻辑里其实都是在Spider中配置的。 Spider要做的事就是有两件:定义抓取网站的动作和分析爬取下来的网页。 Scrapy中的Spider运行流程 以初始的URL初始化Request,并设置回调函数。请求成功时Response生成并作为参数传给该回调函数。 在回调函数内分析返回的网页内容。返回结果两种形式,一种为字典或Item数据对象;另一种是解析到下一个链接。 如果返回的是字典或Item对象,我们可以将结果存入文件,也可以使用Pipeline处理并保存。 如果返回Request,Response会被传递给Request中定义的回调函数参数,即再次使用选择器来分析生成数据Item。 Spider类分析 Spider类源代码:打开文件Python36/Lib/site-packages/scrapy/spiders/__init__.py (windows目录) import logging import warnings from scrapy import signals from scrapy.http import Request from scrapy.utils.trackref import object_ref from scrapy.utils.url import url_is_from_spider from scrapy.utils.deprecate import create_deprecated_class from scrapy.exceptions import ScrapyDeprecationWarning from scrapy.utils.deprecate import method_is_overridden #所有爬虫的基类,自定义的爬虫必须从继承此类 class Spider(object_ref): #定义spider名字的字符串(string)。spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。 #name是spider最重要的属性,而且是必须的。 #一般做法是以该网站(domain)(加或不加 后缀 )来命名spider。 例如,如果spider爬取 douban.com ,该spider通常会被命名为 douban name = None custom_settings = None #初始化,提取爬虫名字,start_ruls def __init__(self, name=None, **kwargs): if name is not None: self.name = name # 如果爬虫没有名字,中断后续操作则报错 elif not getattr(self, 'name', None): raise ValueError("%s must have a name" % type(self).__name__) # python 对象或类型通过内置成员__dict__来存储成员信息 self.__dict__.update(kwargs) #URL列表。当没有指定的URL时,spider将从该列表中开始进行爬取。因此,第一个被获取到的页面的URL将是该列表之一。 后续的URL将会从获取到的数据中提取。 if not hasattr(self, 'start_urls'): self.start_urls = [] @property def logger(self): logger = logging.getLogger(self.name) return logging.LoggerAdapter(logger, {'spider': self}) # 打印Scrapy执行后的log信息 def log(self, message, level=log.DEBUG, **kw): log.msg(message, spider=self, level=level, **kw) @classmethod def from_crawler(cls, crawler, *args, **kwargs): spider = cls(*args, **kwargs) spider._set_crawler(crawler) return spider #判断对象object的属性是否存在,不存在做断言处理 def set_crawler(self, crawler): assert not hasattr(self, '_crawler'), "Spider already bounded to %s" % crawler self._set_crawler(crawler) def _set_crawler(self, crawler): self.crawler = crawler self.settings = crawler.settings crawler.signals.connect(self.close, signals.spider_closed) #@property #def crawler(self): # assert hasattr(self, '_crawler'), "Spider not bounded to any crawler" # return self._crawler #@property #def settings(self): # return self.crawler.settings #该方法将读取start_urls内的地址,并为每一个地址生成一个Request对象,交给Scrapy下载并返回Response #该方法仅调用一次 def start_requests(self): for url in self.start_urls: yield self.make_requests_from_url(url) #start_requests()中调用,实际生成Request的函数。 #Request对象默认的回调函数为parse(),提交的方式为get def make_requests_from_url(self, url): return Request(url, dont_filter=True) #默认的Request对象回调函数,处理返回的response。 #生成Item或者Request对象。用户必须实现这个类 def parse(self, response): raise NotImplementedError @classmethod def handles_request(cls, request): return url_is_from_spider(request.url, cls) @staticmethod def close(spider, reason): closed = getattr(spider, 'closed', None) if callable(closed): return closed(reason) def __str__(self): return "<%s %r at 0x%0x>" % (type(self).__name__, self.name, id(self)) __repr__ = __str__ Spider类继承自scrapy.spiders.Spider. Spider类这个提供了start_requests()方法的默认实现,读取并请求start_urls属性,并调用parse()方法解析结果。 Spider类的属性和方法: name:爬虫名称,必须唯一的,可以生成多个相同的Spider实例,数量没有限制。 allowed_domains: 允许爬取的域名,是可选配置,不在此范围的链接不会被跟进爬取。 start_urls: 它是起始URL列表,当我们没有实现start_requests()方法时,默认会从这个列表开始抓取。 custom_settings: 它是一个字典,专属于Spider的配置,此设置会覆盖项目全局的设置,必须定义成类变量。 crawler:它是由from_crawler()方法设置的,Crawler对象包含了很多项目组件,可以获取settings等配置信息。 settings: 利用它我们可以直接获取项目的全局设置变量。 start_requests(): 使用start_urls里面的URL来构造Request,而且Request是GET请求方法。 parse(): 当Response没有指定回调函数时,该方法会默认被调用。 closed(): 当Spider关闭时,该方法会调用。 百度文库搜索信息案例 Scrapy中的Spider概述 在Scrapy中,要抓取网站的链接配置、抓取逻辑、解析逻辑里其实



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: