蜘蛛是定义如何刮取特定站点(或一组站点)的类,包括如何执行爬网(即跟踪链接)以及如何从页面(即抓取项目)中提取结构化数据。换句话说,Spiders是您定义用于特定站点(或某些情况下,一组站点)的爬网和解析页面的自定义行为的位置。
对于蜘蛛来说,刮擦周期会如下所示:
您首先生成初始请求来爬取第一个URL,并指定一个回调函数,使用从这些请求下载的响应来调用该函数。
第一个要执行的请求是通过调用start_requests()方法获得的,该方法(默认情况下)生成对start_urls和parse方法中指定的URL的请求作为请求的回调函数。
在回调函数中,您将解析响应(网页),并使用提取的数据,Item对象,Request对象或这些对象的可迭代返回任何一个dicts。那些请求还将包含一个回调(可能是相同的),然后将被Scrapy下载,然后他们的响应由指定的回调处理。
在回调函数中,您通常使用选择器来解析页面内容(但您也可以使用BeautifulSoup,lxml或任何您喜欢的任何机制),并生成具有解析数据的项目。
最后,从蜘蛛返回的项目通常会持续到数据库(在某些项目管道中),或者使用Feed导出将其写入文件。
即使这个循环(或多或少)适用于任何种类的蜘蛛,但是为了不同的目的,有各种各样的默认蜘蛛捆绑到Scrapy中。我们将在这里谈论这些类型。
这是最简单的蜘蛛,每个蜘蛛必须继承的蜘蛛(包括与Scrapy捆绑在一起的蜘蛛,以及您自己编写的蜘蛛)。 它不提供任何特殊功能。 它只提供一个默认的start_requests()实现,它从start_urls spider属性发送请求,并为每个结果响应调用spider的方法解析。
名称
一个字符串,用于定义此蜘蛛的名称。 蜘蛛名称是如何通过Scrapy找到(并实例化的),因此它必须是唯一的。 但是,没有什么可以阻止您实例化同一个蜘蛛的多个实例。 这是最重要的蜘蛛属性,它是必需的。
如果蜘蛛刮了一个域,通常的做法是在域名之后命名蜘蛛,有或没有TLD。 所以,例如,爬网mywebsite.com的蜘蛛通常会被称为mywebsite。
注意
在Python 2中,这只能是ASCII。
allowed_domains
一个包含这个蜘蛛允许爬网的域的字符串的可选列表。如果启用了OffsiteMiddleware,将不会遵循不属于此列表中指定的域名(或其子域)的URL的请求。
假设您的目标网址是https://www.example.com/1.html,然后将“example.com”添加到列表中。
start_urls
当没有指定特定URL时,蜘蛛将开始抓取的网址列表。那么下载的第一页就是这些列表。随后的URL将从包含在起始URL中的数据连续生成。
自定义设置
运行此蜘蛛时将从项目宽配置中覆盖的设置字典。由于在实例化之前更新了设置,因此必须将其定义为类属性。
有关可用内置设置的列表,请参阅:内置设置参考。
履带式
该属性由初始化类之后由from_crawler()类方法设置,并链接到此蜘蛛实例绑定到的Crawler对象。
Crawlers在项目中封装了大量组件以进行单一访问(如扩展,中间件,信号管理器等)。请参阅Crawler API了解更多关于它们。
设置
运行这个蜘蛛的配置。这是一个设置实例,有关此主题的详细介绍,请参阅设置主题。
记录仪
Python记录器用Spider的名字创建。您可以使用它通过它发送日志消息,如从Spiders记录中所述。
from_crawler(crawler,* args,** kwargs)
这是Scrapy用来创建你的蜘蛛的类方法。
您可能不需要直接覆盖它,因为默认实现充当__init __()方法的代理,使用给定的参数args和命名参数kwargs进行调用。
尽管如此,该方法会在新实例中设置抓取工具和设置属性,以便稍后在蜘蛛代码中进行访问。
参数:
爬行器(履带式实例) - 蜘蛛将被绑定到的爬行器
args(list) - 传递给__init __()方法的参数
kwargs(dict) - 传递给__init __()方法的关键字参数
start_requests()
此方法必须返回一个可迭代的第一个请求爬网为这个蜘蛛。当蜘蛛打开刮刀时,它被Scrapy称为。 Scrapy仅将其称为一次,因此可以安全地将start_requests()作为生成器实现。
默认实现为start_urls中的每个url生成Request(url,dont_filter = True)。
如果要更改用于开始抓取域的请求,则这是要覆盖的方法。例如,如果您需要首先登录使用POST请求,您可以:
class MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
return [scrapy.FormRequest("http://www.example.com/login",
formdata={'user': 'john', 'pass': 'secret'},
callback=self.logged_in)]
def logged_in(self, response):
# here you would extract links to follow and return Requests for
# each of them, with another callback
pass
解析(响应)
这是Scrapy用于处理下载的响应时的默认回调,当它们的请求没有指定回调时。
解析方法负责处理响应并返回刮除的数据和/或更多URL。其他请求回调与Spider类具有相同的要求。
此方法以及任何其他请求回调必须返回Request和/或dicts或Item对象的可迭代。
参数:response(Response) - 对解析的响应
log(message [,level,component])
通过Spider的记录器发送日志消息的包装器,保持向后兼容。有关更多信息,请参阅从Spiders登录。
封闭的(原因)
当蜘蛛关闭时调用。该方法为spider_closed信号的signals.connect()提供了一个快捷方式。
蜘蛛可以接收修改其行为的参数。蜘蛛参数的一些常见用途是定义起始URL或将爬网限制在站点的某些部分,但可用于配置蜘蛛的任何功能。
Spider参数通过使用-a选项的crawl命令传递。例如:
刮擦爬虫myspider -a category = electronics
Spider可以使用__init__方法访问参数:
进口刮板
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__方法将采用任何蜘蛛参数,并将其复制到蜘蛛作为属性。上面的例子也可以写成如下:
进口刮板
MySpider类(scrapy.Spider):
name ='myspider'
def start\_requests(self):
yield scrapy.Request('http://www.example.com/categories/%s'%self.category)
请记住,蜘蛛参数只是字符串。蜘蛛不会自己做任何解析。如果要从命令行设置start_urls属性,则必须使用ast.literal_eval或json.loads等将其自身解析为列表,然后将其设置为属性。否则,您将引发一个start_urls字符串(一个非常常见的python陷阱)的迭代,导致每个字符被视为一个单独的URL。
一个有效的用例是设置HttpAuthMiddleware或UserAgentMiddleware使用的用户代理使用的http身份凭证:
scrapy crawl myspider -a http_user = myuser -a http_pass = mypassword -a user_agent = mybot
Spider参数也可以通过Scrapyd schedule.json API传递。请参阅Scrapyd文档。
Scrapy带有一些有用的通用蜘蛛,您可以使用它来对蜘蛛进行子类化。 他们的目的是为几个常见的刮取案例提供方便的功能,例如基于某些规则的站点上的所有链接,从Sitemaps抓取,或解析XML / CSV Feed。
对于以下蜘蛛中使用的示例,我们假设您有一个在myproject.items模块中声明的TestItem项目: