天天看点

Scrapy--CrawlSpider全站爬取

CrawlSpider继承了scrapy.spiders类

  • 增加了功能:允许客户自定义方法来搜索url继续爬取。

使用CrawlSpider的优缺点

  • 优点:我们可以方便爬取我们想要的相关url
  • 缺点:由于Rules在获取到url直接运行回调函数,在中间过程我们无法加入其它操作,使之有了局限性。

其他功能:可以配合redis完成增量式爬虫

CrawlSpider的机制:

- 链接提取器: 可以根据指定的规则进行连接的提取
- 规则解析器: 跟据指定的规则对响应数据进行解析
           

Rules

连接提取器,一个包含一个(或多个) Rule 对象的集合(list)。 每个 Rule 对爬取网站的一类URL链接定义了特定表现。 如果多个Rule匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。

rules规则

  • link_extractor:定义需要提取的链接
  • callback:从link_extractor中每获取到匹配的链接时将会调用该函数。也就是规则解析器,我们可以自定义解析方式来获取数据。
  • cb_kwargs 包含传递给回调函数的参数(keyword argument)的字典。
  • follow:如果 callback 为 None, follow 默认设置为 True ,否则默认为 False 。指定是否要跟进url,若为true,则寻找starts_url中所有的url,反之只爬取与链接提取器相关的。
  • process_links 是一个callable或string(该spider 中同名的函数将作为回调函数被调用)。 从link_extractor 中获取到链接列表时将会调用该函数。该方法主要用来过滤。
  • process_request 是一个callable或string(该spider 中同名的函数将作为回调函数被调用)。 该规则提取到每个request时都会调用该函数。该函数必须返回一个request或者None。 (用来过滤request)

警告:当编写爬虫规则时,请避免使用 parse 作为回调函数。 由于 CrawlSpider 使用 parse 方法来实现其逻辑,如果 您覆盖了 parse 方法,crawl spider 将会运行失败。

LinkExtractor

  • LinkExtractor是我们的规则解析器,我们通过它可以制定获取规则(通过正则)来寻找我们需要的url。
  • 若allow里面的内容为空,则全部url都被匹配。

下面是我们的实例:电影天堂下载链接

数据筛选和持久化略,这里我们主要写CrawlSpider

操作代码

  • 创建项目:scrapy startproject 项目名
  • cd 到目录
  • scrapy genspider -t crawl url
  • 启动scrapy:scrapy crawl 爬虫名 --nolog
  • nolog不打印日志
# spider编码:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import MvItem


class BSpider(CrawlSpider):
    name = 'mv'
    # allowed_domains = ['www.baidu.com']
    start_urls = ['https://www.ygdy8.net/html/gndy/oumei/index.html']
    # 定义两个链接提取器,分别为首页和详情页的
    # 由于我们不需要首页的内容,所以首页的链接提取器pass
    link = LinkExtractor(allow=r'list.*?html')
    link_detail = LinkExtractor(allow=r'.*?/\d+\.html')
    # 两个函数为解析器
    rules = (
        Rule(link, callback='parse_item', follow=True,),
        Rule(link_detail, callback='parse_detail', follow=True,),
    )

    def parse_item(self, response):
        pass

    def parse_detail(self, response):
        title = response.xpath('//h1//text()').extract_first()
        downloadlink = response.xpath('//tbody/tr/td/a/text()').extract_first()
        if title and downloadlink and 'ftp' in downloadlink:
            item = BossItem()
            item['title'] = title
            item['downloadlink'] = downloadlink
            yield item
           
# item定义存储字段:
import scrapy


class BossItem(scrapy.Item):
    title = scrapy.Field()
    downloadlink = scrapy.Field()
           

个人感觉CrawlSpider是非常强大的,省时省力,获取我们需要的数据,后面我会写基于CrawlSpider的增量式爬虫。

参考博客:pengjunlee的博客