1. Scrapy框架介绍

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,是一个基于Twisted的异步处理框架,是纯Python实现的爬虫框架,架构清晰,模块之间的耦合程度低,可扩展性极强,可以灵活的完成各种需求。

2.Scrapy项目的创建以及运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1. 创建爬虫的项目  
终端输入:scrapy startproject 项目的名字
注意:项目的名字不允许数字开头,也不能包含中文

2.项目结构
项目名字
项目名字
spiders文件夹(存储爬虫文件)
init
自定义的爬虫文件 是实现爬虫核心功能文件☆☆☆☆☆
init
items 定义数据结构的地方,爬取的数据都包含哪些
middleware 中间件 代理
pipelines 管道文件,里面只有一个类 用于处理下载的数据
默认是300优先级,值越小优先级越高(1-1000)
setting 配置文件 比如是否遵循robots协议 ua定义等

3.创建爬虫文件
(1)跳转到spiders文件夹 cd 目录名字/目录名字/spiders
要在spiders文件夹中创建爬虫文件
cd 项目的名字\项目的名字\spiders
cd scrapy_baidu\scrapy_baidu\spiders

(2)scrapy genspider 爬虫名字 网页的域名

创建爬虫文件
scrapy genspider 爬虫文件的名字 要爬取网页
scrapy genspider baidu http://baidu.com

一般情况下不需要加http协议 因为start_urls的值是根据allow_domains修改的
所以添加了http的话 start_urls就需要手动修改了
3.运行爬虫代码
scrapy crawl 爬虫的名字
scrapy crawl baidu

3.Scrapy架构

  • Engine:引擎。处理整个系统的数据流处理、触发事务、是整个框架的核心,会自动组织所有的请求对象,分发给下载器。
  • Downloader:下载器。从引擎处获取到请求对象后,下载网页内容,请求数据并将网页内容返回给Spiders蜘蛛。
  • Spiders:蜘蛛。内部定义了爬取的逻辑和网页的解析规则,主要负责解析响应并生成提取结果和新的请求。换句话说,Spiders就是定义爬取动作以及分析某个或者某些网页的地方。
  • Scheduler:调度器。接受引擎发过来的请求并将其加入到队列中,在引擎再次请求的时候将请求提供给引擎。
  • Item Pipeline:项目管道。是最终处理数据的管道,会预留接口供我们存储数据,负责处理由Spiders从网页中抽取的项目,主要任务是负责清洗、验证和存储数据。

4. Scrapy工作原理(数据流)

Scrapy的数据流是引擎控制的,数据流过程如下:

  1. Engine首先打开一个网站,找到处理该网站的Spider,并向Spider请求第一个要爬取的url。
  2. Engine将要爬取的url传给调度器Scheduler。
  3. 调度器Scheduler将url生成请求对象放入指定的队列中。
  4. 从队列中出队一个请求,Engine将请求交给下载器DownLoader进行处理。
  5. 下载器Downloader发送请求获取互联网数据。
  6. 一旦页面下载完毕,DownLoader生成该页面的Response,返回给Engine。
  7. Engine从下载器中接收到Response,将其给到Spider。
  8. Spider通过xpath进行解析,得到数据或者新的请求url。
  9. Spider将解析得到的数据或者请求返回给Engine。
  10. Engine判断该数据是数据还是请求url,将数据讲给项目管道处理,是url则继续交给调入器重复3-9步骤。

Demo 汽车之家宝马价格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import scrapy


class CarSpider(scrapy.Spider):
name = 'car'
allowed_domains = ['https://car.autohome.com.cn/price/brand-15.html']
#如果请求的接口是html为结尾的,不需要加/
start_urls = ['https://car.autohome.com.cn/price/brand-15.html']

def parse(self, response):
#//div[@class="main-title"]/a/text()

name_list = response.xpath('//div[@class="main-title"]/a/text()')
price_list = response.xpath('//span[@class="font-arial"]/text()')
for i in range(len(name_list)):
name = name_list[i].extract()
price = price_list[i].extract()
print(name +' '+ price)