本篇内容:

Scrapy核心架构和其组件的功能
Scrapy的工作流
Scrapy的中文输出储存
介绍CrawSpider
编写了一个爬虫实战来进行我们的mysql数据库操作

Scrapy的核心架构

如下图所示:
主要组件包括了Scrapy引擎,调度器,管道,下载中间件,下载器,spider蜘蛛,爬虫中间件,实体管道(Item Pipeline)等。


1、Scrapy引擎:
scrapy引擎是整个scrapy架构的核心,负责控制整个数据处理流程,以及一些事物吃力。scrapy引擎与调度器、实体管道、中间件、下载器等组件都有关系,其出入整个框架的中心位置,对各项组件进行控制及协调。

2、调度器:
调度器主要实现储存待爬取的网址,并确定这些网址的优先级,决定下一次爬取哪个网址等。调度器会从引擎中接收request请求并存入优先队列中。

3、下载器:
下载器主要实现对网络上要爬取的网页资源进行高速下载,由于该组件需要通过网络进行大量数据的传输,所以该组件的压力负担也会比其他的多。下载器下载了对应的网页资源后,也会将这些数据传递给Scrapy引擎,再由Scrapy引擎传递给对应的爬虫进行处理。

4、下载中间件:
下载中间件是处于下载器和引擎之间的一个特定的组件。是用于全局修改Scrapy request和response的一个轻量、底层的系统。

5、蜘蛛spider:
spider是定义如何抓取某个网站(或一组网站)的类,包括如何执行抓取(即关注链接)以及如何从其网页中提取结构化数据(即抓取项目)。换句话说,Spider是您定义用于为特定网站(或在某些情况下,一组网站)抓取和解析网页的自定义行为的位置。

6、爬虫中间件:
爬虫中间件是处于Scrapy引擎与爬虫组件之间的一个特定的组件,主要用于对爬虫组件和Scrapy引擎之间的通信进行处理。同时,在爬虫中间件中可以加入一些自定义代码,很轻松的实现Scrapy功能的扩展。
7、实体管道:
实体管道主要用于接收从蜘蛛组件中提取出来的项目。接收后,会对这些item进行对应的处理。常见的处理主要由:清洗、验证、储存到数据库中。

Scrapy工作流

我们已经知道了Scrapy框架中主要由哪些组件,以及各项组件的具体作用有什么呢,各项数据在组件中又是怎么进行的呢。

1、将网址传递给scrapy引擎。
2、scrapy引擎将网址传给下载中间件
3、下载中间键将网址给下载器
4、下载器像网址发送request请求进行下载
5、网址接收请求,将响应返回给下载器
6、下载器将收到的响应返回给下载中间件
7、下载中间件与scrapy引擎通信
8、scrapy将response响应信息传递给爬虫中间件
9、爬虫中间件将响应传递给对应的爬虫进行处理
10、爬虫处理之后,会提取出来的数据和新的请求信息,将处理的信息传递给爬虫中间件
11、爬虫中间件将处理后的信息传递给Scrapy引擎
12、scrapy接收到信息之后,会将项目实体传递给实体管道进行进一步处理,同时将新的信息传递给调度器。
13、随后再重复执行1-12步,一直到调度器中没有网址或异常退出为止。

以上就是Scrapy框架中各项组件的工作流程。此时相信我们队Scrapu框架数据处理的过程就又了比较详细的了解。

Scrapy中文输出与中文存储

使用Scrapy抓取中文时,输出一般是unicode,要输出中文也只需要稍作改动。

单纯交互输出
如代码:

title = sel.xpath('a/text()').extract()
print title

此时输出的是title对应中文的unicode格式,只需要指定“utf-8”编码即可输出中文,如下:

title = sel.xpath('a/text()').extract()
for t in title:print t.encode('utf-8')

这里需要注意的是“encode()”函数是字符串专有的,而title是一个列表,因此需要对title中的每一个执行该操作。

存储
存储中文数据可以利用pipeline实现

1.定义pipeline

#coding: utf-8
import codecs
import jsonclass TutorialPipeline(object):def __init__(self):self.file = codecs.open('data_cn.json', 'wb', encoding='utf-8')def process_item(self, item, spider):line = json.dumps(dict(item)) + '\n'self.file.write(line.decode("unicode_escape"))return item

上述方法将得到的item解码,以便正常显示中文,并保存到定义的json文件中。

2.注册自定义的pipeline
为了启动pipeline,必须将其加入到“ITEM_PIPLINES”的配置中,在settings.py中加入下面一句:

ITEM_PIPELINES = {'tutorial.pipelines.TutorialPipeline':300  }

其中根目录是tutorial,pipelines是我的pipeline文件名,TutorialPipeline是类名

CrawlSpider详解:

在Scrapy基础——Spider中,我简要地说了一下Spider类。Spider基本上能做很多事情了,但是如果你想爬取知乎或者是简书全站的话,你可能需要一个更强大的武器。
CrawlSpider基于Spider,但是可以说是为全站爬取而生。
简要说明:

  • CrawlSpider是爬取那些具有一定规则网站的常用的爬虫,它基于Spider并有一些独特属性rules:
    是Rule对象的集合,用于匹配目标网站并排除干扰

  • parse_start_url: 用于爬取起始响应,必须要返回Item,Request中的一个。

  • 因为rules是Rule对象的集合,所以这里也要介绍一下Rule。它有几个参数:link_extractor、callback=None、cb_kwargs=None、follow=None、process_links=None、process_request=None

  • 其中的link_extractor既可以自己定义,也可以使用已有LinkExtractor类,主要参数为:

    allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。
    deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
    allow_domains:会被提取的链接的domains。
    deny_domains:一定不会被提取链接的domains。
    restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。还有一个类似的restrict_css

问题:CrawlSpider如何工作的?

因为CrawlSpider继承了Spider,所以具有Spider的所有函数。
首先由start_requests对start_urls中的每一个url发起请求,这个请求会被parse接收。
在Spider里面的parse需要我们定义,但CrawlSpider定义parse去解析响应。
根据有无callback,follow和self.follow_links执行不同的操作

def _parse_response(self, response, callback, cb_kwargs, follow=True):    ##如果传入了callback,使用这个callback解析页面并获取解析得到的reques或itemif callback:cb_res = callback(response, **cb_kwargs) or ()cb_res = self.process_results(response, cb_res)            for requests_or_item in iterate_spider_output(cb_res):                yield requests_or_item    ## 其次判断有无follow,用_requests_to_follow解析响应是否有符合要求的link。if follow and self._follow_links:for request_or_item in self._requests_to_follow(response):                yield request_or_item

爬取豆瓣电影前250信息:

为了讲解后面的操作数据到数据库,这里插入scrapy框架爬取豆瓣网站信息。
首先创建项目,cmd输入命令

scrapy startproject doubanmovie

在spiders文件夹下创建文件MySpider.py。
在MySpider.py中创建类DoubanMovie继承自scrapy.Spider,同时定义以下属性和方法

name : 爬虫的唯一标识符
start_urls : 初始爬取的url列表
parse() : 每个初始url访问后生成的Response对象作为唯一参数传给该方法,该方法解析返回的Response,提取数据,生成item,同时生成进一步要处理的url的request对象

在settings文件中添加下面一行:

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'

在doubanmovie文件夹下创建文件MovieItems.py,在该文件下编写存放爬取到的数据的容器
创建类MovieItem继承自scrapy.Item,定义各种属性,语句类似以下

name = scrapy.Field()

整个parse()方法代码如下

 def parse(self, response):selector = scrapy.Selector(response)# 解析出各个电影movies = selector.xpath('//div[@class="item"]')# 存放电影信息item = MovieItem()for movie in movies:# 电影各种语言名字的列表titles = movie.xpath('.//span[@class="title"]/text()').extract()# 将中文名与英文名合成一个字符串name = ''for title in titles:name += title.strip()item['name'] = name# 电影信息列表infos = movie.xpath('.//div[@class="bd"]/p/text()').extract()# 电影信息合成一个字符串fullInfo = ''for info in infos:fullInfo += info.strip()item['info'] = fullInfo# 提取评分信息item['rating'] = movie.xpath('.//span[@class="rating_num"]/text()').extract()[0].strip()# 提取评价人数item['num'] = movie.xpath('.//div[@class="star"]/span[last()]/text()').extract()[0].strip()[:-3]# 提取经典语句,quote可能为空quote = movie.xpath('.//span[@class="inq"]/text()').extract()if quote:quote = quote[0].strip()item['quote'] = quote# 提取电影图片item['img_url'] = movie.xpath('.//img/@src').extract()[0]yield itemnext_page = selector.xpath('//span[@class="next"]/a/@href').extract()[0]url = 'https://movie.douban.com/top250' + next_pageif next_page:yield scrapy.Request(url, callback=self.parse)

数据存储:
目前选择将数据存放在json文件中,对数据库的处理在下面会讲解
在doubanmovie文件夹下创建文件MoviePipelines.py,编写类MoviePipeline,重写方法process_item(self, item, spider)用于处理数据。

import scrapy
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.exceptions import DropItem
class ImagePipeline(ImagesPipeline):def get_media_requests(self, item, info):yield scrapy.Request(item['image_url'])def item_completed(self, results, item, info):image_url = [x['path'] for ok, x in results if ok]if not image_url:raise DropItem("Item contains no images")item['image_url'] = image_urlreturn item

同时在settings文件中注册并设置下载目录:

ITEM_PIPELINES = {'doubanmovie.MoviePipelines.MoviePipeline': 1,'doubanmovie.ImgPipelines.ImgPipeline': 100,
}

在settings文件中将ROBOTSTXT_OBEY改为False,让scrapy不遵守robot协议,即可正常下载图片

IMAGES_STORE = 'E:\\img\\'

scrapy数据存入mysql数据库:

将爬取的各种信息通过json存在文件中,不过对数据的进一步使用显然放在数据库中更加方便,这里将数据存入mysql数据库以便以后利用。

首先在项目settings文件中添加与数据库连接相关的变量

MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'zzz'
MYSQL_USER = 'root'
MYSQL_PASSWD = '111'

创建数据库和表

class MovieItem(scrapy.Item):# 电影名字name = scrapy.Field()# 电影信息info = scrapy.Field()# 评分rating = scrapy.Field()# 评论人数num = scrapy.Field()# 经典语句quote = scrapy.Field()# 电影图片img_url = scrapy.Field()

据此创建数据库表,创建数据库的时候加上DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci,以防出现乱码

create database douban DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
use douban;
CREATE TABLE doubanmovie (name VARCHAR(100) NOT NULL, # 电影名字info VARCHAR(150), # 电影信息rating VARCHAR(10), # 评分num VARCHAR(10), # 评论人数quote VARCHAR(100), # 经典语句img_url VARCHAR(100), # 电影图片
)

在MoviePipelines.py文件中创建类DBPipeline,在其中进行对数据库的操作。
首先连接数据库,获取cursor以便之后对数据就行增删查改

def __init__(self):# 连接数据库self.connect = pymysql.connect(host=settings.MYSQL_HOST,db=settings.MYSQL_DBNAME,user=settings.MYSQL_USER,passwd=settings.MYSQL_PASSWD,charset='utf8',use_unicode=True)# 通过cursor执行增删查改self.cursor = self.connect.cursor();

注意这里charset属性为 ‘utf8’,中间没有-,在调试过程中因为这个-搞了半天

之后重载方法process_item(self, item, spider),在其中执行数据的增删查改,通过cursor编写sql语句,然后使用self.connect.commit()提交sql语句

def process_item(self, item, spider):try:# 插入数据self.cursor.execute("""insert into doubanmovie(name, info, rating, num ,quote, img_url)value (%s, %s, %s, %s, %s, %s)""",(item['name'],item['info'],item['rating'],item['num'],item['quote'],item['img_url']))# 提交sql语句self.connect.commit()except Exception as error:# 出现错误时打印错误日志log(error)return item

最后在settings文件中注册DBPipeline

ITEM_PIPELINES = {'doubanmovie.MoviePipelines.MoviePipeline': 1,'doubanmovie.ImgPipelines.ImgPipeline': 100,'doubanmovie.MoviePipelines.DBPipeline': 10,
}

可以尝试运行了。
然而爬取的数据是250条,在数据库存储中只有239条
查看MySpider.py文件

quote = movie.xpath('.//span[@class="inq"]/text()').extract()
if quote:quote = quote[0].strip()
item['quote'] = quote

如果网页中quote属性不存在,那么将item插入数据库时就会出错,增加一条else语句

if quote:quote = quote[0].strip()
else:quote = ' '
item['quote'] = quote

本篇到此为止了。本篇内容讲解了Scrapy核心架构和其组件的功能,Scrapy的工作量。以及Scrapy的中文输出储存,介绍了CrawSpider。并编写了一个爬虫实战来进行我们的mysql数据库操作。
理论上差不多可以了,后面的内容将会讲解各种实战项目,希望大家多多关注。

007:Scrapy核心架构和高级运用相关推荐

  1. 英伟达十年力作:新一代光线追踪显卡 Quadro RTX及核心架构Turing,可支持AI运算...

    作者 | 琥珀 出品 | AI科技大本营(公众号ID:rgznai100) 北京时间 8 月 14 日清晨,英伟达(NVIDIA)CEO 黄仁勋准时出席在温哥华举办的 SIGGRAPH 2018 计算 ...

  2. Hadoop核心架构(1)

    在大数据的发展过程中,出现了一批专门应用与大数据的处理分析工具,如Hadoop,Hbase,Hive,Spark等,我们先从最基础的Hadoop开始进行介绍 Hadoop是apache基金会下所开发的 ...

  3. 负载均衡10年发展,应用交付成核心架构

    负载均衡10年发展,应用交付成核心架构 编者按:十年前,很少有人知道网络负载均衡,十年后,网络负载均衡已经成为网络应用的重要设备,特别是大型网络应用的核心设备.如今,负载均衡设备市场甚至并驾与基础路由 ...

  4. 【Unity学习笔记】b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别)

    [Unity学习笔记]b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别) 自己跟着学完了,写了不少代码,会放在CSDN代码库,因为老师并没有提供源码,录屏也不是完全连续,所以难 ...

  5. 3D引擎架构设计高级篇

    3D引擎架构设计最核心的技术包括:引擎框架设计,引擎内存管理,大场景加载以及卸载,引擎的渲染,模型骨骼插件:其他的模块还有粒子,AI,行为树,UI等等吧. 市场上对于引擎开发的需求也是比较大的,而且薪 ...

  6. Scrapy 框架架构

    Scrapy 框架架构 目录 Scrapy 框架架构 前言 一.核心组成 二.数据流 三.项目结构 总结 前言 Scrapy (/ˈskreɪpaɪ/) 是一个用于抓取网站和提取结构化数据的应用程序框 ...

  7. android核心架构Framework组件介绍

    作为一个android开发者,核心架构是必须要了解的.只有了解每个核心层的作用,才能更深入的理解和学习.本篇主要讲解Java Framework层核心代码流程. 文章目录 一,Android系统架构 ...

  8. W75 - 999、云计算架构师高级认证

    初学耗时:999h 注:CSDN手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端. 『   因为要去见那个不一般的人,所以我就不能是一般人.』  W99.阿里大学征服路 - W系列总纲   ...

  9. 哈罗python的学费多少-哈啰出行招聘Java、算法、大数据开发、安卓、iOS、运维架构专家/高级专家等...

    简历请发hanlongjie05932@hellobike.com 资深IOS开发工程师 工作职责: 1.负责IOS平台应用产品的研发工作: 2.负责根据产品需求完成模块设计.编码.编码集成工作: 3 ...

最新文章

  1. 如何有条件地向React组件添加属性?
  2. 窗体皮肤ssk 跟背景图片冲突_夫西地酸+阿达帕林~我要好皮肤
  3. c++观察者模式observer
  4. 在局域网访问_局域网访问共享文件需要密码怎么办?取消访问密码的方法
  5. 【安富莱二代示波器教程】第8章 示波器设计—测量功能
  6. hive 导出json格式 文件_hive存储json格式文件
  7. 黑客攻防:关于工业网络安全的那些事
  8. 字段的某记录相同,但是时间不同,找到MySQL里面最新的数据
  9. JavaScript小效果的实现(笔记)
  10. Actor编程模型——Erlang/OTP
  11. 从原理到应用,一文带你了解小程序插件能力
  12. (转)基于Ajax的应用程序架构汇总
  13. [LeetCode]12. Integer to Roman
  14. Qt5中this application has requested the runtime to terminate it in an unusual way 无法运行问题的解决
  15. oracle日期如何比较,Oracle日期比较
  16. 【转载】金山词霸”屏幕取词技术揭密(讨论稿)
  17. 推荐 四种优秀的数据库设计工具
  18. 基于HFSS阵列天线设计
  19. 一天一看————以太网交换机的基本原理与配置!
  20. CSS反爬获取伪元素的值

热门文章

  1. [渝粤教育] 郑州工程技术学院 大学计算机基础 参考 资料
  2. 江苏转本计算机一级,江苏“专转本”新规:考生需获计算机一级及以上证书
  3. 如何利用朋友圈做好微信营销之路
  4. 2020-01-01T00:00:00.000000Z 日期格式转换
  5. GTX 295 VS C1060 矩阵乘法测试(cublas)
  6. 拓扑排序 by zyz on 2021/4/11
  7. Unity3d轻量渲染管线(LWRP)民间文档
  8. Flutter·变换·先旋转再平移与先平移再旋转
  9. Paul Graham:未来的互联网创业
  10. JavaWeb(华清远见)