Python爬虫第十课:Scrapy框架(1)

前面的关卡中,我们学习了如何用协程来提升爬虫的速度,并且通过项目实操,将协程运用于抓取HI运动的食物数据。

不知道你会不会有这样一种感觉:要写出一个完整的爬虫程序需要做很多琐碎的工作。比如,要针对不同的网站制定不同的解析方式;要导入不同功能的模块;还要编写各种爬取流程的代码。

我们在日常工作中会使用PPT模板来制作PPT。那么有没有一个现成的爬虫模板,让我们能够改之即用,也就是说对这个模板进行适当的修改,就能完成一个爬虫项目的开发呢?

这种模板在Python中还真的存在,只不过我们一般称之为框架。

就像PPT模板会帮你设置好背景、字体和颜色一样,一个爬虫框架里包含了能实现爬虫整个流程的各种模块,。

这一关,我们要学习的就是一个功能强大的爬虫框架——Scrapy。

一、Scrapy是什么

在我们之前的课程中,我们需要不同模块实现不同的功能:使用requests模块进行请求、使用csv模块存储数据等。而在Scrapy里,你不需要这么做,因为很多爬虫需要涉及的功能,比如麻烦的异步,在Scrapy框架都自动实现了

我们之前编写爬虫的方式,就相当于我们在自己装修一个毛坯房。需要自己去找施工队来「水电施工」「泥工砌墙贴砖」「木工吊顶打柜子」「油漆工刷乳胶漆」等等…而框架就相当于一个精装房,拎包入住!

1)Scrapy的结构

Python爬虫第十课:Scrapy框架(1)_第1张图片
上面的这张图是Scrapy的整个结构。你可以把整个Scrapy框架当成是你所在的部门。最中心位置的Scrapy Engine(引擎)就是你所在部门的大boss,负责统筹规划你这个部门的四大职能。

以爬虫流程的顺序来依次介绍Scrapy爬虫部门的4大职能:

  • Scheduler(调度器)主要负责处理引擎发送过来的requests对象(即网页请求的相关信息集合,包括params,data,cookies,request headers…等),会把请求的url以有序的方式排列成队,并等待引擎来提取(功能上类似于gevent库的queue模块)。

  • Downloader(下载器)则是负责处理引擎发送过来的requests,进行网页爬取,并将返回的response(爬取到的内容)交给引擎。它对应的是爬虫流程【获取数据】这一步。

  • Spiders(爬虫)的主要任务是创建requests对象和接受引擎发送过来的response(Downloader部门爬取到的内容),从中解析并提取出有用的数据。它对应的是爬虫流程【解析数据】和【提取数据】这两步。

  • Item Pipeline(数据管道)负责存储和处理Spiders提取到的有用数据。这个对应的是爬虫流程【存储数据】这一步。

  • Downloader Middlewares(下载中间件)的工作相当于下载器的助手,比如会提前对引擎发送的诸多requests做出处理。

  • Spider Middlewares(爬虫中间件)的工作则相当于爬虫的助手,比如会提前接收并处理引擎发送来的response,过滤掉一些重复无用的东西。

Python爬虫第十课:Scrapy框架(1)_第2张图片

3)Scrapy的工作原理


从这个图中可以看出 Scrapy 框架的工作原理,即是——引擎就是大Boss,统领其他成员协同工作。

在使用 Scrapy 的时候。我们不需要去关心爬虫的每个流程。并且Scrapy中的网络请求都是默认异步模式,请求和返回都会由引擎去自动分配处理。

如果某个请求出现异常,框架也会帮我们做异常处理,跳过这个异常的请求,继续去执行后面的程序。

所以说,我们使用 Scrapy 可以省掉很多的时间和工作!就像我们直接住进精装房一样!

二、Scrapy的用法

现在,我们已经初步了解Scrapy的结构以及工作原理。接下来,为了熟悉Scrapy的用法,我们使用它来完成一个小项目——爬取豆瓣Top250图书。

1)明确目标与分析过程

我们还是来遵循「项目实现」的三步骤:、

  1. 明确目标
  2. 分析过程
  3. 代码实现

我们在代码实现部分,重点讲解Scrapy的使用方法。

明确目标,让我们观察一下要爬取的网站:https://book.douban.com/top250。豆瓣Top250图书一共有10页,每页有25本书籍。

我们的初步目标是:先只爬取前三页书籍的信息,总共是 25 x 3 = 75 本,包含书名、出版信息和书籍评分。

那就是分析要爬取的网页结构。 既然我们要爬取书籍信息,我们就得先判断这些信息被存在了哪里。

右击打开“检查”工具,点开Network,刷新页面,然后点击第0个请求top250,看Response.

我们能在里面找到书名、出版信息,说明我们想要的书籍信息就藏在这个网址的HTML里。

https://book.douban.com/top250?start=25

我们可以看到,网址发生了变化,后面多了?start=25。现在的你,应该一眼就能猜到后面的数字应该是代表一页的25本书籍吧?

你可以翻到第3页,验证一下猜想是不是正确的。

事实证明,我们猜对了。每翻一页,网址后面的数字都会增加25,说明这个start的参数就是代表每页的25本书籍。

我们要爬取的网址的构造规律就出来了。只要改变?start=后面的数字(翻一页加25),我们就能得到每一页的网址。

找到了网址的构造规律之后,我们就可以重点来分析HTML的结构,看看等下怎么才能提取出我们想要的书籍信息。

还是是右击打开“检查”工具,点击Elements,再点击光标,把鼠标依次移到书名、出版信息、评分处,就能在HTML里找到这些书籍信息。如下图,《追风筝的人》的书籍信息就全部放在

标签里。

仔细观察你就会发现,其实每一页的25本书籍信息都分别藏在了一个
标签里。不过这个标签没有class属性,也没有id属性,不方便我们提取信息。

我们得继续再找一个既方便我们提取,又能包含所有书籍信息的标签。

我们可以看看

标签下的元素,好像刚好都能满足我们的要求,既有class属性,又包含了书籍的信息。

我们只要取出元素下元素的title属性的值、

元素、元素,就能得到书名、出版信息和评分的数据。

页面分析完毕,接着进入代码实现的步骤,要开始写 Scrapy 的代码啦。

2)代码实现——创建项目

如果你想着自己本地的电脑使用Scrapy,需要提前安装好它。

  • Windows:在终端输入命令:pip install scrapy;
  • mac:在终端输入命令:pip3 install scrapy

创建Scrapy项目

首先,在本地电脑打开终端,然后跳转到你想要保存项目的目录下。

  • windows:Win+R,输入cmd;
  • mac:command+空格,搜索“终端”

假设你想跳转到D盘里名为Python文件夹中的scrapy_project子文件夹。

  1. 你需要再命令行输入d:,就会跳转到D盘
  2. 再输入cd Python,就能跳转到Python文件夹。
  3. 接着输入cd scrapy_project,就能跳转到Python文件夹里的scrapy_project子文件夹。
  4. 再输入一行能帮我们创建Scrapy项目的命令:scrapy startproject douban(douban就是Scrapy项目的名字)。按下enter键,一个Scrapy项目就创建成功了。

在mac系统中的终端里,也是使用cd命令来跳转到你要的文件夹位置

Python爬虫第十课:Scrapy框架(1)_第3张图片
整个scrapy项目的结构,如下图所示:
Python爬虫第十课:Scrapy框架(1)_第4张图片
Scrapy项目里每个文件都有它对应的具体功能。例如:

  • settings.py 是scrapy里的各种设置
  • items.py是用来定义数据的
  • pipelines.py是用来处理数据的,它们对应的就是Scrapy的结构中的Item Pipeline(数据管道)。

如前所述,spiders是放置爬虫的目录。我们可以在spiders这个文件夹里创建爬虫文件。

我们来把这个文件,命名为Book_douban_Top250。后面的大部分代码都需要在这个Book_douban_Top250.py文件里编写。
Python爬虫第十课:Scrapy框架(1)_第5张图片

代码实现——编辑爬虫

先在Book_douban_Top250.py文件里导入我们需要的模块。

import scrapy
import bs4
  • 导入BeautifulSoup用于解析和提取数据;
  • 导入scrapy是待会我们要用创建类的方式写这个爬虫,我们所创建的类将直接继承scrapy中的scrapy.Spider类。这样,有许多好用的属性和方法,就能够直接使用。

接着我们开始编写爬虫的核心代码。

在Scrapy中,每个爬虫的代码结构基本都如下所示:

import scrapy
import bs4

class DoubanSpider(scrapy.Spider):
    name = 'book_douban'
    allowed_domains = ['book.douban.com']
    start_urls = ['https://book.douban.com/top250?start=0']
    
    def parse(self, response):
        print(response.text)

代码解释

  • 第1行代码:定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。

  • 第2行代码:name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'book_douban’意思是定义爬虫的名字为book_douban。等会我们启动爬虫的时候,要用到这个名字。

  • 第3行代码:allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。

    为什么会有这个设置呢?
    当你在爬取大量数据时,经常是从一个URL开始爬取,然后关联爬取更多的网页。
    假设我们在今天的爬虫目标是爬豆瓣top250每本书籍的书评信息,我们会先爬取书单,再找到每本书的URL,再进入每本书的详情页面去抓取评论。
    allowed_domains就限制了我们这种关联爬取的URL,一定在book.douban.com这个域名之下,不会跳转到某个奇怪的广告页面。

  • 第4行代码:start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。

  • 第5行代码:parse是Scrapy里默认处理response的一个方法。

是不是觉得和之前自己手动写爬虫的完全不一样了呢?怎么连 requests.get() 都没有了呀?其实在框架里,我们并不需要写这一句。

scrapy框架会为我们代劳做这件事,写好你的请求,接下来你就可以直接写对 response 如何做处理了。

豆瓣Top250图书一共有10页,每一页的网址我们都知道。我们可以把10页网址都塞进start_urls的列表里。


我们可以利用豆瓣Top250图书的网址规律,用for循环构造出每个网址,再把网址添加进start_urls的列表里。
Python爬虫第十课:Scrapy框架(1)_第6张图片
完善后的代码如下:

import

你可能感兴趣的:(python,爬虫)