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

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

方法二:基于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

- 3,4行:导入CrawlSpider相关模块

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

  - 9,10,11行:表示为提取Link规则

  - 12行:解析方法

  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中,然后提交给管道进行持久化存储

代码示例:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider):
name = 'chouti'
#allowed_domains = ['dig.chouti.com']
start_urls = ['https://dig.chouti.com/'] #实例化了一个链接提取器对象
#链接提取器:用来提取指定的链接(url)
#allow参数:赋值一个正则表达式
#链接提取器就可以根据正则表达式在页面中提取指定的链接
#提取到的链接会全部交给规则解析器
link = LinkExtractor(allow=r'/all/hot/recent/\d+')
rules = (
#实例化了一个规则解析器对象
#规则解析器接受了链接提取器发送的链接后,就会对这些链接发起请求,获取链接对应的页面内容,就会根据指定的规则对页面内容中指定的数据值进行解析
#callback:指定一个解析规则(方法/函数)
#follow:是否将链接提取器继续作用到连接提取器提取出的链接所表示的页面数据中
Rule(link, callback='parse_item', follow=True),
) def parse_item(self, response):
print(response)

4.简单代码实战应用

  4.1 爬虫文件:

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

import scrapy

from scrapy.linkextractors import LinkExtractor

from scrapy.spiders import CrawlSpider, Rule

from qiubaiBycrawl.items import QiubaibycrawlItem

import re

class QiubaitestSpider(CrawlSpider):

    name = 'qiubaiTest'

    #起始url

    start_urls = ['http://www.qiushibaike.com/']

    #定义链接提取器,且指定其提取规则

    page_link = LinkExtractor(allow=r'/8hr/page/\d+/')

    rules = (

        #定义规则解析器,且指定解析规则通过callback回调函数

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

4.2 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 QiubaibycrawlItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() author = scrapy.Field() #作者 content = scrapy.Field() #内容

4.3 管道文件:

# -*- 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 QiubaibycrawlPipeline(object):

    def __init__(self):

        self.fp = None

    def open_spider(self,spider):

        print('开始爬虫')

        self.fp = open('./data.txt','w')

    def process_item(self, item, spider):

        #将爬虫文件提交的item写入文件进行持久化存储

        self.fp.write(item['author']+':'+item['content']+'\n')

        return item

    def close_spider(self,spider):

        print('结束爬虫')

        self.fp.close()

scrapy框架之CrawlSpider操作的更多相关文章

  1. 爬虫开发11.scrapy框架之CrawlSpider操作

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  2. 爬虫scrapy框架之CrawlSpider

    爬虫scrapy框架之CrawlSpider   引入 提问:如果想要通过爬虫程序去爬取全站数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模 ...

  3. Python网络爬虫之Scrapy框架(CrawlSpider)

    目录 Python网络爬虫之Scrapy框架(CrawlSpider) CrawlSpider使用 爬取糗事百科糗图板块的所有页码数据 Python网络爬虫之Scrapy框架(CrawlSpider) ...

  4. (六--二)scrapy框架之持久化操作

    scrapy框架之持久化操作 基于终端指令的持久化存储 基于管道的持久化存储 1 基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过 ...

  5. scrapy框架之分布式操作

    分布式概念 分布式爬虫: 1.概念:多台机器上可以执行同一个爬虫程序,实现网站数据的分布爬取. 2.原生的scrapy是不可以实现分布式爬虫? a)调度器无法共享 b)管道无法共享 3.scrapy- ...

  6. 6 scrapy框架之分布式操作

    分布式爬虫 一.redis简单回顾 1.启动redis: mac/linux:   redis-server redis.conf windows: redis-server.exe redis-wi ...

  7. 爬虫开发14.scrapy框架之分布式操作

    分布式爬虫 一.redis简单回顾 1.启动redis: mac/linux:   redis-server redis.conf windows: redis-server.exe redis-wi ...

  8. python爬虫入门(八)Scrapy框架之CrawlSpider类

    CrawlSpider类 通过下面的命令可以快速创建 CrawlSpider模板 的代码: scrapy genspider -t crawl tencent tencent.com CrawSpid ...

  9. Scrapy框架之CrawlSpider

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

随机推荐

  1. 当 1117 遇到 MLCC 后

    当 1117 遇到 MLCC 后 AMS1117 很多人用过吧,但是当大容量的 MLCC 时会出现什么呢? 会出现问题,而且严重的问题,输出纹波会变大,会自激,会有声音出来. 这是很多工程师没有注意的 ...

  2. [转]Java之JMX 详解

    一.JMX简介 JMX是一种JAVA的正式规范,它主要目的是让程序有被管理的功能,那么怎么理解所谓的“被管理”呢?试想你开发了一个软件(如WEB网站),它是在24小时不间断运行的,那么你可能会想要“监 ...

  3. TypeScript 之 泛型

    https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Generics.html 泛型:可以支持多种类型的数据 泛型函数的 ...

  4. 通过 DDNS 解决宽带拨号 ip 变化问题

    前面你的文章我已经写了 写了 DMZ 内网映射的 方式. 这样内网主机已经暴露在外网中了. 但是 拨号上网我们的ip是 会变化的.大概规律就是 每次拨号都会变化.如果不拨号,每 24 小时 ip也会自 ...

  5. URL编码规则

    一.问题的由来 问题:当url地址中包含&.+.%等特殊字符(主要是传递参数时,参数的内容中包含这些字符)时,地址无效.比如http://10.190.0.0:108/doc/test+des ...

  6. ASP.NET AJAX入门系列(4):使用UpdatePanel控件(一)

    UpdatePanel可以用来创建丰富的局部更新Web应用程序,它是ASP.NET 2.0 AJAX Extensions中很重要的一个控件,其强大之处在于不用编写任何客户端脚本,只要在一个页面上添加 ...

  7. Linux vi文本编辑器

    vi文本编辑器 1.最基本用法 vi  somefile.4 1/ 首先会进入“一般模式”,此模式只接受各种命令快捷键,不能编辑文件内容 2/ 按i键,就会从一般模式进入编辑模式,此模式下,敲入的都是 ...

  8. nginx http 正向代理

    打开\nginx-1.12.2\conf\nginx.conf, 在http{      } ,大括号内加入 http { #............................. #...... ...

  9. WPF Demo511 控件共用事件

    路由事件: 1.路由事件一般使用的三种策略如下所示: A.Bubble(冒泡模式):事件从自己激发一直传递到根元素; B.Direct(直接模式):只有事件源才有机会相应事件(和传统事件一样); C. ...

  10. NetBeans IDE 多行标签设置方法