3-----Scrapy框架之CrawlSpier操作

CrawlSpider

提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法?

方法一:基于 Scrapy框架中的 Spider的递归爬取进行实现(Request模块递归回调parse方法)。

方法二:基于 CrawlSpider的自动爬取进行实现(更加简洁和高效)。

CrawlSpider

一、简介

  CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能。其中最显著的功能是”LinkExtractors链接提取器“。Spider是所有爬虫的基类,其设计原则只是为了爬取 start_url列表中网页,而从爬取到的网页中提取出的 url进行继续的爬取工作使用 CrawlSpider更适。

二、使用

1、创建scrapy工程:

  scrapy startproject projectName

2、创建爬虫文件:

  scrapy genspider -t crawl spiderName www.xxx.com

  此指令对比以前的指令多了 "-t crawl",表示创建的爬虫文件是基于 CrawlSpider这个类的,而不再是 Spider这个基类。

3、观察生成的爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class ChoutidemoSpider(CrawlSpider):
    name = 'choutiDemo'
    #allowed_domains = ['www.chouti.com']
    start_urls = ['http://www.chouti.com/']

    rules = (
        Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        i = {}
        #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
        #i['name'] = response.xpath('//div[@id="name"]').extract()
        #i['description'] = response.xpath('//div[@id="description"]').extract()
        return i

2,3行:导入CrawlSpider相关模块

7行:表示该爬虫程序是基于CrawlSpider类的

12,13,14行:表示为提取Link规则

16行:解析方法

  CrawlSpider类和 Spider类的最大不同是 CrawlSpider多了一个rules属性,其作用是定义”提取动作“。在 rules中可以包含一个或多个 Rule对象,在 Rule对象中包含了 LinkExtractor对象。

3-1、LinkExtractor:顾名思义,链接提取器。

LinkExtractor(
  allow
=r'Items/'# 满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。   deny=xxx, # 满足正则表达式的则不会被提取。   restrict_xpaths=xxx, # 满足xpath表达式的值会被提取   restrict_css=xxx, # 满足css表达式的值会被提取   deny_domains=xxx, # 不会被提取的链接的domains。     )

作用:提取response中符合规则的链接。

3-2、 Rule : 规则解析器。根据链接提取器中提取到的链接,根据指定规则提取解析器链接网页中的内容。

 Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True)

参数介绍:

  参数1:指定链接提取器

  参数2:指定规则解析器解析数据的规则(回调函数)

  参数3:是否将链接提取器继续作用到链接提取器提取出的链接网页中。当 callback为None,参数 3的默认值为true。

3-3、 rules=( ):指定不同规则解析器。一个Rule对象表示一种提取规则。

3-4 、CrawlSpider整体爬取流程:

  a)爬虫文件首先根据起始url,获取该url的网页内容。

  b)链接提取器会根据指定提取规则将步骤a中网页内容中的链接进行提取。

  c)规则解析器会根据指定解析规则将链接提取器中提取到的链接中的网页内容根据指定的规则进行解析。

  d)将解析数据封装到 item中,然后提交给管道进行持久化存储。

4、简单代码实战应用

scrapy startproject qiubaiPro

cd qiubai

scrapy genspider -t crawl qiubai www.qiushibaike.com

开启中间件 settings.py

# 伪装头部
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
# 忽略robos协议
ROBOTSTXT_OBEY = False 
# 开启管道 
ITEM_PIPELINES = {
   'qiubaiPro.pipelines.QiubaiproPipeline': 300,
} 
# 中间件,可以不开启,这块用不到
SPIDER_MIDDLEWARES = {
   'qiubaiPro.middlewares.QiubaiproSpiderMiddleware': 543,
}

爬虫文件

qiubai.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from qiubaiPro.items import QiubaiProlItem
import re


class QiubaiSpider(CrawlSpider):
    name = 'qiubai'
    # 起始url
    start_urls = ['https://www.qiushibaike.com/8hr/']

    # 定义链接提取器,且指定其提取规则
    page_link = LinkExtractor(allow=r'/8hr/page/\d+/')
    # 可以指定多个link,这个爬取第一页,和...隐藏的页码,定义/8hr/$开头的所有
    link1 = LinkExtractor(allow=r'/8hr/$')
    rules = (
        # 定义规则解析器,且指定解析规则通过callback回调函数
        Rule(page_link, callback='parse_item', follow=True),
        Rule(link1, callback='parse_item', follow=True),
    )

    # 自定义规则解析器的解析规则函数
    def parse_item(self, response):
        print(response)
        div_list = response.xpath('//div[@id="content-left"]/div')
        for div in div_list:
            # 定义item
            item = QiubaiProlItem()
            # 根据xpath表达式提取糗百中段子的作者
            item['author'] = div.xpath('./div/a[2]/h2/text()').extract_first().strip('\n')
            # print(item['author'])
            # 根据xpath表达式提取糗百中段子的内容
            item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract_first().strip('\n')
            # print(item['content'])

            yield item  # 将item提交至管道

item文件:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class QiubaiProlItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author = scrapy.Field() #作者
    content = scrapy.Field() #内容

管道文件

pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

class QiubaiproPipeline(object):

    def __init__(self):
        self.fp = None

    def open_spider(self, spider):
        print('开始爬虫')
        self.fp = open('./data.txt', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        # 将爬虫文件提交的item写入文件进行持久化存储
        self.fp.write(item['author'] + ':\n' + item['content'] + '\n')
        return item

    def close_spider(self, spider):
        print('结束爬虫')
        self.fp.close()

运行:

E:\lnh\day26\qiubaiPro>scrapy crawl qiubai --nolog

 

 

posted @ 2018-11-05 09:40  王竹笙  阅读(1184)  评论(0编辑  收藏  举报