前言
Scrapy功能非常强大,爬虫效率高,相关扩展组件多,可配置性和可扩展程度非常高,它几乎可以应对所有的反爬网站,是目前python中使用最广泛的爬虫框架。
一、scrapy框架介绍
scrapy框架
- Scrapy Engine(引擎): 引擎负责控制数据流在系统的所有组件中流动,并在相应动作发生时触发事件。
- Scheduler(调度器): 调度器从引擎接受request并将他们入队,以便之后引擎请求他们时提供给引擎。
- Downloader(下载器): 下载器负责获取页面数据并提供给引擎,而后提供给spider。
- Spider(爬虫): Spider是Scrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些)网站。
- Item Pipeline(管道): Item Pipeline负责处理被spider提取出来的item。典型的处理有清理、 验证及持久化(例如存储到数据库中)。
- Downloader Middlewares(下载中间件): 下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的response。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。
- Spider Middlewares(Spider中间件): Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。
数据流
- 首先在spider中编写请求的url,相当于引擎问spider想处理那些request请求,这时spider就会做出回应,将已编写的request请求发送给engin引擎;
- engine引擎将spider发送过的的请求发给scheduler调度器,调度器会将request请求排序成队列;
- engine引擎将会请求scheduler调度器是否已将request请求入队,若已入队,则scheduler调度器将请求队列发送给engine引擎;
- engine引擎将scheduler调度器发送过来的的request请求队列,发送给downloader下载器。downloader下载器若成功下了请求的内容,则将response发送给引擎,引擎再将response发送给spider进行处理。若downloader下载器下载出错,则downloader下载器会将出错的请求发送给engine引擎,engine引擎再讲请求发送给scheduler调度器再次进行排队调度;
- spider接收engine引擎发送过来的数据,对数据进行分析。该数据由两部分组成,一部分是我们请求的数据,这部分数据会交给Item、Pipline进行数据存储或者清洗;另一部分是新的请求,spider会将新的请求发送给引擎,然后引擎再将这些新的请求发送到调度器进行排队。然后重复1、2、3、4操作,直到获取到全部的信息为止。
下面这张图讲的比较有趣。
创建scrapy项目实例,可以参考这篇文章:
https://blog.csdn.net/suwuzs/article/details/118091474?spm=1001.2014.3001.5501
二、scrapy爬虫实例
1.爬虫步骤
- 新建项目
创建项目可以直接用scrapy命令生成
scrapy startproject douy
创建Spider创建前,先进入入douy这个文件夹
cd douy
scrapy genspider dy douyu.com
genspider命令,第一个参数是Spider的名称,第二个参数是网站域名
创建之后可以用pycharm打开文件
-
明确目标
开发者选项来分析网页,找到自己想要提取的数据。 -
制作爬虫
在dy.py文件中写爬虫代码。
import scrapy
import json
from douy.items import DouyItem
class DySpider(scrapy.Spider):
name = 'dy'
allowed_domains = ['www.douyu.com']
base_url = 'https://m.douyu.com/api/room/list?page={}&type=yz'
offset = 1
start_urls = [base_url.format(offset)]
def parse(self, response):
#解析数据
data_list = json.loads(response.body)['data']
if len(data_list['list']) == 0:#data_list是否有数据
return
for data in data_list['list']:
item = DouyItem()
print(item)
item['nickname'] = data['nickname']
item['verticalSrc'] = data['verticalSrc']
yield item
#下面的是回调然后循环爬取
#self.offset += 1
#url = self.base_url.format(self.offset)
#yield scrapy.Request(url,callback=self.parse,dont_filter=True)
- 存储内容
在pipelines中存储下载的图片
import scrapy
from scrapy.pipelines.images import ImagesPipeline
class DouyPipeline(ImagesPipeline):
def get_media_requests(self,item,info):
image_link = item['verticalSrc']
yield scrapy.Request(image_link)
在设置里面打开ITEM_PIPELINES。
2.运行结果
这里只爬取了一页,所以只下载了几张图片。