Scrapy,Spider是一个负责定义如何通过一个网站的链接并从网页中提取信息的类.
Scrapy的默认spider如下 −
scrapy.Spider
它是一个Spider,其他的Spiders都必须从它那里继承。它有以下类别 −
class scrapy.spiders.Spider
下表显示了scrapy.Spider类的字段 −
| 字段 | 说明 | 
|---|---|
| name | 它是你的Spider的名字. | 
| allowed_domains | 它是一个Spider抓取的域的列表. | 
| start_urls | 这是一个URL的列表,它将是以后抓取的根,Spider将从这里开始抓取. | 
| custom_settings | 这些是设置,当运行Spider时,将从项目范围的配置中被覆盖. | 
| crawler | 它是一个属性,链接到Spider实例所绑定的爬虫对象. | 
| settings | 这些是运行Spider的设置. | 
| logger | 它是一个Python日志记录器,用于发送日志信息. | 
| from_crawler(crawler,*args,**kwargs) | 它是一个类方法,可以创建你的Spider。其参数是 − crawler − 一个爬虫,Spider实例将被绑定到该爬虫 args(list) − 这些参数被传递给方法 _init_ (). kwargs(dict) − 这些关键字参数被传递给方法 _init_().  | 
| start_requests() | 当没有指定特定的URL,并且Spider被打开进行爬虫时,Scrapy调用start_requests()方法. | 
| make_requests_from_url(url) | 它是一种用于将urls转换为请求的方法. | 
| parse(response) | 该方法处理响应,并返回更多的URL后的废旧数据. | 
| log(message[,level,component]) | 它是一个通过Spider记录器发送日志信息的方法. | 
| closed(reason) | 这个方法在Spider关闭时被调用. | 
Spider 参数
Spider参数用于指定起始URL,使用带-a选项的爬行命令传递,如下所示 −
scrapy crawl first_scrapy -a group = accessories
下面的代码演示了一个Spider如何接收参数 −
import scrapy 
class FirstSpider(scrapy.Spider): 
   name = "first" 
   def __init__(self, group = None, *args, **kwargs): 
      super(FirstSpider, self).__init__(*args, **kwargs) 
      self.start_urls = ["http://www.example.com/group/%s" % group]
通用Spiders
你可以使用通用Spider来对你的Spider进行分类。它们的目的是根据某些规则跟踪网站上的所有链接,从所有页面中提取数据。
对于以下Spider使用的例子,让我们假设我们有一个项目,有以下字段 −
import scrapy 
from scrapy.item import Item, Field 
class First_scrapyItem(scrapy.Item): 
   product_title = Field() 
   product_link = Field() 
   product_description = Field() 
CrawlSpider
CrawlSpider定义了一套规则来跟踪链接和刮除一个以上的页面。它有以下的类 −
class scrapy.spiders.CrawlSpider
以下是CrawlSpider类的属性 −
规则
它是一个规则对象的列表,定义了爬虫如何跟踪链接.
下表显示了CrawlSpider类的规则 −
| 规则 | 说明 | 
|---|---|
| LinkExtractor | 它规定了Spider如何跟踪链接并提取数据. | 
| callback | 它将在每个页面被爬取后被调用. | 
| follow | 它指定是否继续跟踪链接. | 
parse_start_url(response)
它通过允许解析初始响应来返回项目或请求对象.
注意 − 在编写规则时,请确保重命名parse函数,而不是parse,因为parse函数被CrawlSpider用来实现其逻辑.
让我们看一下下面的例子,Spider开始爬行demoexample.com的主页,收集所有的页面、链接,并用parse_items方法进行解析 −
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class DemoSpider(CrawlSpider):
   name = "demo"
   allowed_domains = ["www.demoexample.com"]
   start_urls = ["http://www.demoexample.com"]
   rules = ( 
      Rule(LinkExtractor(allow =(), restrict_xpaths = ("//div[@class = 'next']",)),
         callback = "parse_item", follow = True),
   )
   def parse_item(self, response):
      item = DemoItem()
      item["product_title"] = response.xpath("a/text()").extract()
      item["product_link"] = response.xpath("a/@href").extract()
      item["product_description"] = response.xpath("div[@class = 'desc']/text()").extract()
      return items
XMLFeedSpider
它是Spider的基类,用于从XML馈送中爬取并迭代节点。它有以下的类 −
class scrapy.spiders.XMLFeedSpider
下表显示了用于设置迭代器和标签名称的类属性 −
| 属性 | 描述 | 
|---|---|
| iterator | 它定义了要使用的迭代器。它可以是iternodes、html或xml。默认是iternodes. | 
| itertag | 它是一个带有节点名称的字符串,可以进行迭代 | 
| namespaces | 它由(prefix, uri)图元列表定义,使用register_namespace()方法自动注册命名空间. | 
| adapt_response(response) | 它接收响应,并在spider开始解析之前,尽快修改从spider中间件到达的响应体 | 
| parse_node(response,selector) | 它在为每个匹配所提供的标签名称的节点调用时接收响应和一个选择器. 注意 − 如果你不覆盖这个方法,你的Spider就不会工作.  | 
| process_results(response,results) | 它返回一个结果列表和由Spider返回的响应. | 
CSVFeedSpider
它遍历每一行,接收一个CSV文件作为响应,并调用parse_row()方法。它有以下的类 −
class scrapy.spiders.CSVFeedSpider
下表显示了关于CSV文件可以设置的选项 −
| 选项 | 描述 | 
|---|---|
| delimiter | 它是一个字符串,包含每个字段的逗号(’,’)分隔符. | 
| quotechar | 它是一个字符串,包含每个字段的引号('”‘). | 
| headers | 它是一个可以从中提取字段的报表列表. | 
| parse_row(response,row) | 它收到了一个响应,每一行都有一个头的密钥. | 
CSVFeedSpider 示例
from scrapy.spiders import CSVFeedSpider
from demoproject.items import DemoItem  
class DemoSpider(CSVFeedSpider): 
   name = "demo" 
   allowed_domains = ["www.demoexample.com"] 
   start_urls = ["http://www.demoexample.com/feed.csv"] 
   delimiter = ";" 
   quotechar = "'" 
   headers = ["product_title", "product_link", "product_description"]  
   def parse_row(self, response, row): 
      self.logger.info("This is row: %r", row)  
      item = DemoItem() 
      item["product_title"] = row["product_title"] 
      item["product_link"] = row["product_link"] 
      item["product_description"] = row["product_description"] 
      return item
SitemapSpider
SitemapSpider在Sitemaps的帮助下,通过定位robots.txt中的URL来抓取一个网站。它有以下类 −
class scrapy.spiders.SitemapSpider
下表显示了SitemapSpider的字段 −
| 字段 | 描述 | 
|---|---|
| sitemap_urls | 你想抓取的指向网站地图的URL列表. | 
| sitemap_rules | 它是一个图元列表(regex,callback),其中regex是一个正则表达式,callback用于处理匹配正则表达式的URLs. | 
| sitemap_follow | 这是一个网站地图的词条列表,需要遵循的是. | 
| sitemap_alternate_links | 指定单一网址的备用链接. | 
SitemapSpider 示例
以下是SitemapSpider对所有URLs的处理情况 −
from scrapy.spiders import SitemapSpider  
class DemoSpider(SitemapSpider): 
   urls = ["http://www.demoexample.com/sitemap.xml"]  
   def parse(self, response): 
      # You can scrap items here
以下是SitemapSpider处理一些带回调的URL的情况 −
from scrapy.spiders import SitemapSpider  
class DemoSpider(SitemapSpider): 
   urls = ["http://www.demoexample.com/sitemap.xml"] 
   rules = [ 
      ("/item/", "parse_item"), 
      ("/group/", "parse_group"), 
   ]  
   def parse_item(self, response): 
      # you can scrap item here  
   def parse_group(self, response): 
      # you can scrap group here 
以下代码显示robots.txt中的网站地图,其url有/sitemap_company −
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider): 
   urls = ["http://www.demoexample.com/robots.txt"] 
   rules = [ 
      ("/company/", "parse_company"), 
   ] 
   sitemap_follow = ["/sitemap_company"]  
   def parse_company(self, response): 
      # you can scrap company here 
你甚至可以将SitemapSpider与其他URL结合起来,如以下命令所示.
from scrapy.spiders import SitemapSpider  
class DemoSpider(SitemapSpider): 
   urls = ["http://www.demoexample.com/robots.txt"] 
   rules = [ 
      ("/company/", "parse_company"), 
   ]  
   other_urls = ["http://www.demoexample.com/contact-us"] 
   def start_requests(self): 
      requests = list(super(DemoSpider, self).start_requests()) 
      requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls] 
      return requests 
   def parse_company(self, response): 
      # you can scrap company here... 
   def parse_other(self, response): 
      # you can scrap other here... 
极客教程