Python网络爬虫-Scrapy框架

Scrapy框架

安装

Scrapy是第三方的库,直接来一手

1
pip install scrapy

依赖问题看报错解决

框架解析

Scrapy框架用的5个模块加2个中间件

模块:

  1. SPIDERS
  2. ENGINE
  3. SCHEDULER
  4. DOWNLOADER
  5. ITEM PIPELINES

中间件:

  1. Spider Middleware
  2. Downloader Middleware

各模块形成三条数据流路径,其中传输的数据有REQUESTS/RESPONSE/ITEMS
请求和响应不BB,ITEMS是一种容器,类似字典,我们通过编写SPIDER来将页面中非结构化的数据解析出来并存入ITEM中,成为结构化的信息。
模块功能通过名字很容易理解:

  • ENGINE是负责将数据分发到各模块的中枢
  • SPIDERS是我们编写的小爬虫,负责爬取内容并解析数据
  • SCHEDULER负责调度请求顺序
  • DOWNLOADER下载器,负责请求,实实在在的页面访问,并拿到响应
  • ITEM PIPELINES负责数据(ITMES)的处理

模块形成的三条数据流路径:

  1. SPIDERS提供的REQUESTS请求经ENGINE中转到SCHEDULER
  2. SCHEDULER中的REQUESTS请求由ENGINE提交给DOWNLOADERDOWNLOADER将对应的响应(RESPONSE)经ENGINE返回给SPIDERS
  3. SPIDERSRESPONSE中解析出ITEMSREQUESTS,其中REQUESTS会从第一条路径继续重复,而ITEMS就会经ENGINE到达ITEM PIPELINES

用文字描述很抽象,因为懒得找图床来放图片,但是也很清晰了。

关于中间件
首先两个中间件连接在相应模块与ENGINE模块之间,可以自定义,但一般不用改动
Spider中间件用于处理Response中提取的Rqeuests和Items,自定义可以定义一些方法,比如当Response通过Spider中间件时会调用process_spider_input(response, spider)返回None,异常时也会调用process_spider_exception(response, exception, spider),这些方法主体都可以自行编写。
Downloader中间件处理request和response,可以设定全局参数,比如代理ip,自定义头等,是反反爬虫的关键。

scrapy框架能单独写一本书出来,靠这一小节视频学的都是皮毛,但是上手还是非常容易的。作为一个成熟的框架,即使是一个python新手也能很快用起来,这个框架入门其实就是做填空题,五个模块中我们只需要配置好生成的SPIDER和对应的ITEM PIPELINE即可,其它的模块功能框架已经实现了。

对比requests库

两者是python爬虫的两条重要路线,它们都可以对页面进行请求和爬取,有丰富的文档,入门简单。同时两者都没有处理js,提交表单,应对验证码等功能(可拓展)。

不同点:

requests Scrapy
页面级爬虫 网站级爬虫
功能库 框架
并发性考虑不足,性能较差 并发性好,性能较高
重点在于页面下载 重点在于爬虫结构
定制灵活 一般定制灵活,深度定制困难
上手十分简单 入门稍难

路线选择:

非常小的需求,requests库
不太小的需求,Scrapy框架
定制程度很高的需求(不考虑规模),自搭框架,requests > Scrapy

Scrapy常用命令

scrapy库提供了scrapy终端

>scrapy -h

即可看到使用帮助

常用命令

命令 说明 格式
startproject 创建一个新工程 scrapy startproject <name> [dir]
genspider 创建一个爬虫 scrapy genspider [options] <name> <domain>
settings 获得爬虫配置信息 scrapy settings [options]
crawl 运行一个爬虫 scrapy crawl <spider>
list 列出工程中所有爬虫 scrapy list
shell 启动URL调试命令行 scrapy shell [url]

Scrapy框架简单使用

scrapy简单使用步骤

  1. 建立一个爬虫工程
  2. 在工程中生成一个scrapy爬虫
  3. 配置生成的spider爬虫
  4. 运行爬虫,获取网页

1.建立一个爬虫工程

创建工程,使用startproject

1
2
3
4
5
6
7
E:\北京理工网络爬虫\project>scrapy startproject scrapydemo
New Scrapy project 'scrapydemo', using template directory 'd:\python\python37\lib\site-packages\scrapy\templates\project', created in:
E:\北京理工网络爬虫\project\scrapydemo

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

这样就创建了一个工程,在目录下产生了一个scrapydemo的工程文件夹

  • scrapydemo/——————外层目录
    • scrapy.cfg—————-部署配置,在服务器上部署scrapy时使用,本地不用
    • scrapydemo/—————框架的用户自定义Python代码
      • __init__.py——-初始化脚本
      • items.py————–Items代码模板(继承类)
      • middlewares.py——–Middlewares代码模板(继承类)
      • pipelines.py———-Pipelines代码模板(继承类)
      • settings.py———–Scrapy爬虫配置文件
      • spiders/————–Spiders代码模板目录(继承类)
        • __init__.py——初始文件,无需修改

2.在工程中生成一个scrapy爬虫

切换到工程文件夹中,使用genspider生成一个爬虫

1
2
3
E:\北京理工网络爬虫\project\scrapydemo>scrapy genspider demo python123.io
Created spider 'demo' using template 'basic' in module:
scrapydemo.spiders.demo

在spiders目录下就生成了一个demo.py文件,它就是我们的小爬虫。这里是通过命令行来生成,我们也可以手工生成。看一下它的初始内容。

demo.py

1
2
3
4
5
6
7
8
9
10
11
12
# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
name = 'demo'
allowed_domains = ['python123.io']
start_urls = ['http://python123.io/']

def parse(self, response):
pass

3.配置生成的spider爬虫

通过编辑demo.py来配置我们的爬虫。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
name = 'demo'
# allowed_domains = ['python123.io']
start_urls = ['http://python123.io/ws/demo.html']

def parse(self, response):
fname = response.url.split('/')[-1]
with open(fname, 'wb') as f:
f.write(response.body)

里面有一个爬虫类,叫什么无所谓,只要继承scrapy.Spider类就可以了。现在简单使用,只爬取一个页面,直接改初始url。parse方法中传进来了一个response对象,通过编写该方法来提取我们的信息,这里使用对象的url属性来提取html文件名字并且将body属性写入到本地文件。其实就是将页面下载下来。

4.运行爬虫,获取网页

命令行执行:

1
>scrapy crawl demo

爬取结束后目录下多了一个demo.html

1
2
3
4
5
6
<html><head><title>This is a python demo page</title></head>
<body>
<p class="title"><b>The demo python introduces several python courses.</b></p>
<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>
</body></html>

这里就没有用到item pipelines,因为我们实现的是页面下载,所以并不需要提取什么信息,直接让spider将响应主体保存就可以了。后面再做更深入的使用。

Scrapy框架中的数据类型

Request类

class scrapy.http.Request()
Request对象表示一个HTTP请求
由Spider生成,由Downloader执行

属性或方法 说明
.url Request对应的请求URL地址
.method 对应的请求方法,'GET' 'POST'等
.headers 字典类型风格的请求头
.body 请求内容主体,字符串类型
.meta 用户添加的扩展信息,在Scrapy内部模块间传递信息使用
.copy() 复制该请求

Response类

class scrapy.http.Response()
Response对象表示一个HTTP响应
由Downloader生成,由Spider处理

属性或方法 说明
.url Response对应的URL地址
.status HTTP状态码,默认是200
.headers Response对应的头部信息
.body Response对应的内容信息,字符串类型
.flags 一组标记
.request 产生Response类型对应的Request对象
.copy() 复制该响应

Item类

class scrapy.item.Item()
Item对象表示一个从HTML页面中提取的信息内容
由Spider生成,由Item Pipeline处理
Item类似字典类型,可以按照字典类型操作

Scrapy爬虫提取信息的方法

scrapy爬虫支持多种html信息提取方法:

  • Beautiful Soup
  • lxml
  • re
  • XPath Selector
  • CSS Selector

CSS Selector

用法:

1
<HTML>.css('a::attr(href)').extract()  

CSS Selector由W3C组织维护并规范

文章作者: SNCKER
文章链接: https://sncker.github.io/blog/2019/08/04/Python网络爬虫-Scrapy框架/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SNCKER's blog