Scrapy爬虫框架快速上手

  • 1. 网络爬虫技术
  • 2. Scrapy框架简介
  • 3. Scrapy框架的基本构成
  • 4. HTML基础
  • 4.1 XPath
  • 4.2 解析语法
  • 5. scrapy案例演示
  • 5.1 scrapy安装
  • 5.2 scrapy框架的使用
  • 5.2 创建爬虫项目
  • 6. 日志等级与日志保存
  • 7. 导出为json或scv格式
  • 参考资料


1. 网络爬虫技术

任何网络爬虫程序都是将我们浏览网页的行为自动化、程序化,因此一般都要按照如下步骤进行:
(1)准备需要访问的网页完整地址。即网页的域名加上查询字符串。
(2)得到所要访问的网页地址后,还需要确定访问方式。一般来说,有两种方式:GET或者POST。
(3)提交网页请求后,即可获得请求的响应,即Response,通常会得到这个网页源码。
(4)得到网页源码后,需要对信息进行分解,从结构化源码中提取所需要的内容,这个过程称为Parsing。在Python中,比较有名的是BeautifulSoup。
(5)得到目标信息后,保存到数据库或者文本中。

2. Scrapy框架简介

Scrapy是基于事件驱动的Twisted框架下用纯Python写的爬虫框架,用于抓取Web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘监测自动化测试。其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 后来也应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。

3. Scrapy框架的基本构成

Scrapy框架包括5个主要的组件和2个中间件Hook。这五大组件分别是调度器(Scheduler)下载器(Downloader)爬虫(Spider)实体管道(Item Pipline)Scrapy引擎(Scrapy Engine)。它们的具体用途如下:

  • 调度器(Scheduler):把它假设成为一个URL(抓取网页的网址或者说是链接)的优先队列,由它来决定下一个要抓取的网址是 什么,同时去除重复的网址(不做无用功)。用户可以自己的需求定制调度器。
  • 下载器(Downloader):是所有组件中负担最大的,它用于高速地下载网络上的资源。Scrapy的下载器代码不会太复杂,但效率高,主要的原因是Scrapy下载器是建立在Twisted这个高效的异步模型上的(其实整个框架都在建立在这个模型上的)。
  • 爬虫(Spider):是用户最关心的部份。用户定制自己的爬虫(通过定制正则表达式等语法),用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。 用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。
  • 实体管道(Item Pipeline):用于处理爬虫(spider)提取的实体。主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。
  • Scrapy引擎(Scrapy Engine):Scrapy引擎是整个框架的核心。它用来控制调试器、下载器、爬虫。实际上,引擎相当于计算机的CPU,它控制着整个流程。

除此之外,还有:

  • Moddlewares:engine和Spiders,engine和Downloader之间一些额外的操作,hook的方式提供给开发者。

从上面可知,只要实现Spiders(要爬取什么网站,怎么解析)和Item Piplines(如何处理解析后的内容)就可以了,其他的有框架帮你完成。如下图所示:

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架


整个程序的执行流程如下:

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架_02


注意在调用下载器时,往往有一个下载器中间件,使下载速度提速。

  1. Spider发起爬虫请求,将第一个要爬取的URL给engine,告诉它任务来了
  2. engine将请求添加到scheduler调度队列中,说任务就交给你了,给我安排好
  3. scheduler调度队列中的请求很多,按照队列顺序取出一个请求给engine,并请求engine帮忙转发给下载器downloader
  4. engine说没问题,于是就告诉下载器downloader需要下载的任务
  5. downloader访问Internet获取资源,并将结果response交给engine
  6. engine将第一个请求的爬取结果交给spider,并告诉他可以进行解析了
  7. spider对爬取结果进行解析,产生目标字段,并将其转发给piplines
  8. piplines接收到字段,保存起来。

第1步到第8步,一个请求终于完成了。是不是觉得很多余?ENGIINE夹在中间当传话筒,能不能直接跳过?可以考虑跳过了会怎么样。这里需要分析一下:

  • scheduler的作用是任务调度,控制任务的并发,防止engine处理不过来
  • engine:因为是基于Twisted框架的,当事件来(比如转发请求)的时候,通过回调的方式来执行对应的事件。engine让所有操作统一起来,都是按照事件的方式来组织其他组件,其他组件以低耦合的方式运作。

4. HTML基础

4.1 XPath

写爬虫最重要的是解析网页的内容,这个部分就介绍下通过XPath来解析网页,提取内容。

python爬虫调度框架 python爬虫框架scrapy 教程_数据挖掘_03

4.2 解析语法

  • a/b:'/'在xpath里表示层级关系,左边的a是父节点,右边的b是子节点
  • a//b:表示a下边所有的b,直接或者间接的
  • [@]:选择具有某个属性的点
  • //div[@class],//a[@x]:选择具有class属性的div节点,选择具有x属性的a节点
  • //div[@class=“container”]:选择具有class属性的值为container的div节点
  • //a[contains(@id,“abc”)]:选择id属性里有abc的a标签

示例:

response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').get_all()
# 获取所有class属性为taglist的div,下一层ul下的所有li下所有的a下所有img标签下data-original的属性
# data-original这里放的是图片的url地址

其他语法可参考https://www.w3school.com.cn/xpath/xpath_syntax.asp

5. scrapy案例演示

5.1 scrapy安装

Scrapy 是用纯python编写的,它依赖于几个关键的python包(以及其他包):

  • lxml 一个高效的XML和HTML解析器
  • parsel ,一个写在lxml上面的html/xml数据提取库,
  • w3lib ,用于处理URL和网页编码的多用途帮助程序
  • twisted 异步网络框架
  • cryptography 和 pyOpenSSL ,处理各种网络级安全需求
# 安装
pip install scrapy

5.2 scrapy框架的使用

大概分成四步:

  1. 创建一个scrapy项目
scrapy startproject firstSpider
  1. 生成一个爬虫
scrapy genspider baidu www.baidu.com
  1. 提取数据
完善spider 使用xpath等
  1. 保存数据
pipeline中保存数据
  1. 运行程序
  • 在命令行中运行
scrapy crawl firstSpider     # firstSpider爬虫的名字
  • 在PyCharm中运行爬虫
from scrapy import cmdline
cmdline.execute("scrapy crawl firstSpider".split())

5.2 创建爬虫项目

(base) D:\MyProjects\Code600\com\spider\scrapy>scrapy startproject firstSpider
New Scrapy project 'firstSpider', using template directory 'd:\anaconda\lib\site-packages\scrapy\templates\project', created in:
    D:\MyProjects\Code600\com\spider\scrapy\firstSpider

You can start your first spider with:
    cd firstSpider
    scrapy genspider example example.com

(base) D:\MyProjects\Code600\com\spider\scrapy>cd firstSpider
(base) D:\MyProjects\Code600\com\spider\scrapy>scrapy genspider baidu www.baidu.com
Created spider 'baidu' using template 'basic' in module:
  firstSpider.spiders.baidu

文件结构如下:

python爬虫调度框架 python爬虫框架scrapy 教程_scapy_04


文件说明:

|-ProjectName #项目文件夹

|-ProjectName #项目目录

|-items.py #定义数据结构

|-middlewares.py #中间件

|-pipelines.py #数据处理

|-settings.py #全局配置

|-spiders

|-init.py #爬虫文件

|-baidu.py

|-scrapy.cfg #项目基本配置文件

spiders下的baidu.py是scrapy自动为我们生成的

import scrapy
class BaiduSpider(scrapy.Spider):
    name = 'baidu'
    allowed_domains = ['www.baidu.com']
    start_urls = ['http://www.baidu.com/']

    def parse(self, response):
        pass

其中,执行需要到scrapy.cfg同级别的目录执行

scrapy crawl firstSpider

从上可知,我们要写的是spiders里的具体的spider类和items.py和pipelines.py(对应的ITEM PIPELINES)


这里再看一下spdier项目的配置文件,打开文件settings.py

BOT_NAME = 'firstSpider' # 项目名
USER_AGENT = 'Mozilla/5.0' # 默认是注释的,这个东西非常重要,如果不写很容易被判断为电脑,简单写一个Mozilla/5.0即可
ROBOTSTXT_OBEY = False # 是否遵循机器人协议,默认是true,需要改为false,否则很多东西爬不了

python爬虫调度框架 python爬虫框架scrapy 教程_python_05

CONCURRENT_REQUESTS = 32 # 最大并发数,很好理解,就是同时允许开启多少个爬虫线程
DOWNLOAD_DELAY = 3 # 下载延迟时间,单位是秒,控制爬虫爬取的频率,根据你的项目调整,不要太快也不要太慢,默认是3秒,即爬一个停3秒,设置为1秒性价比较高,如果要爬取的文件较多,可以写零点几秒
COOKIES_ENABLED = False # 是否保存COOKIES,默认关闭,开机可以记录爬取过程中的COKIE,非常好用的一个参数

# 默认请求头,上面写了一个USER_AGENT,其实这个东西就是放在请求头里面的,这个东西可以根据你爬取的内容做相应设置。
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'en',
}

python爬虫调度框架 python爬虫框架scrapy 教程_数据挖掘_06

# 项目管道,300为优先级,数值越低越爬取的优先度越高
ITEM_PIPELINES = {
    'firstSpider.pipelines.FirstspiderPipeline': 300,
    'firstSpider.pipelines.ImagesspiderPipeline': 200,
}

比如这里写了两个管道,一个爬取网页的管道,一个抓取图片的管道,我调整了他们的优先级,如果有爬虫数据,优先执行爬取图片操作。

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架_07


这里我们尝试用scrapy做一下爬取,打开spider.py下的baidu.py(取决于你scrapy genspider 爬虫名 域名时输入的爬虫名

输入以下代码,我们使用xpath提取百度首页的标题title:

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架_08


打开一个终端cmd,输入scrapy crawl baidu(爬虫名),就可以看到一大堆输出信息,而其中就包括我们要的内容:

python爬虫调度框架 python爬虫框架scrapy 教程_python_09


注意:执行scrapy crawl需要在项目目录内操作。

python爬虫调度框架 python爬虫框架scrapy 教程_数据挖掘_10


使用终端运行太麻烦了,而且不能提取数据,我们一个写一个run文件作为程序的入口,splite是必须写的,目的是把字符串转为列表形式,第一个参数是scrapy,第二个crawl,第三个baidu。

from scrapy import cmdline

cmdline.execute('scrapy crawl baidu'.split())

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架_11


注意:run.py文件需要位于项目目录内

python爬虫调度框架 python爬虫框架scrapy 教程_数据挖掘_12

6. 日志等级与日志保存

setting.py里面可以设置日志的等级与日志存放的路径。
相关变量

  • LOG_LEVEL= “”
  • LOG_FILE=“日志名.log”
    日志等级分为
  1. DEBUG 调试信息
  2. INFO 一般信息
  3. WARNING 警告
  4. ERROR 普通错误
  5. CRITICAL 严重错误

如果设置LOG_LEVEL="WARNING",就只会WARNING等级之下的ERRORCRITICAL,默认等级是1

7. 导出为json或scv格式

执行爬虫文件时添加-o选项即可

scrapy crawl 项目名 -o *.csv

scrapy crawl 项目名 -o *.json

对于json文件,在setting.js文件里添加,设置编码格式,否则会乱码:

FEED_EXPORT_ENCODING='utf-8'

示例:

from scrapy import cmdline
 
cmdline.execute('scrapy crawl baidu -o baidu.csv'.split())

python爬虫调度框架 python爬虫框架scrapy 教程_python爬虫调度框架_13