scrapy爬虫框架开发
一、介绍
scrapy作为老牌的爬虫框架,可以添加中间件用于异步高并发。
提高爬虫效率。
以下是它的架构图。
管道是多个队列,会看优先级,数据依次经过各个管道。

二、简单启动
废话不多说,我们直接开始介绍常用api,最后会做一个爬取豆瓣示例。
我们先来安装一下(windows版本)
pip install Sracpy然后创建一个文件夹,用来存放我们的scrapy项目
scrapy startproject 项目名称这个时候就会在对应目录下创建一个工程文件夹。如下图。tutorial是默认的项目名称。

这里顺便来介绍一下各个文件的作用。
- items用于数据封装
- spiders文件夹用于编写我们的脚本
- middlewares用于中间件组装
- pipelines是管道,用于存储
- scrapy.cfg是个配置文件,我们不需要对他做任何操作
- settings是配置文件,里面有很多配置,我们需要操作。
下面我们直接来爬取豆瓣代码,来顺便讲解一下常用的api。
走起~
三、快速启动
好啦,我们继续介绍常用api以及原生scrapy写法
import scrapydef get_urls(start_url): urls = [] for i in range(0,2): new_url = start_url + str(i*25) urls.append(new_url) return urlsclass Douban(scrapy.Spider): name = "douban" start_urls = get_urls("https://book.douban.com/top250?start=") def start_requests(self): headers = { "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "pragma": "no-cache", "priority": "u=2, i", "user-agent": "Mozilla/" } for url in self.start_urls: yield scrapy.Request(url=url, headers=headers, callback=self.parse) def parse(self, response): self.log("哇了解到哈佛安抚v奥iu符号发哈") yield response.url主程序从第七行开始
我们定义了一个类,继承了scrapy.Spider
- 它必须一个类变量即
name = "douban",这也是在scrapy里唯一标识它的地方! start_urls是一个列表,用于存放即将要爬取的url- start_requests是爬虫程序,我们可以在里面添加请求头。如果不需要请求头,这里可以删除,scrapy会自动去用url列表爬取
- parse是解析函数,用于将响应数据解析传给管道
写好上面的程序后,接着我们直接来启动我们的程序
到达对应顶级目录比如我的就是scrapy,看我之前放的文件树图输入:scrapy crawl douban爬虫即可启动!我们可以在终端看到我们的标记哇了解到哈佛安抚v奥iu符号发哈,这代表程序能够正常执行。
四、实战案例
我们来写一个获取某网站cos图片的程序,顺便讲解api
案例是https://dimtown.com/cosplay/
import scrapyimport osfrom ..items import cosItem
def get_urls(): urls = [] for i in range(1,101): new_url = f"https://dimtown.com/cosplay/page/{i}" urls.append(new_url) return urls
class Cosplay(scrapy.Spider): name = "cos" start_urls = get_urls() #这里是利用requests进行下载,比较稳定,但是速度慢。 # def get_src(self,url): # try: # response = requests.get(url) # file_name = url.split('/')[-1] # file_path = os.path.join(r'D:\yuanrenxue\scrapy\tutorial\tutorial\cosplay', file_name) # if response.status_code == 200: # with open(file_path,'wb') as f: # f.write(response.content) # self.log("下载成功") # except Exception as e: # self.logger.error(e)
def start_requests(self): headers = {#这里填入你自己的headers信息,可以不带cookie } for url in self.start_urls: yield scrapy.Request(url=url, headers=headers, callback=self.parse) def parse(self, response): lis = response.xpath('//*[@id="index_ajax_list"]/li') for li in lis: obj = li.xpath('.//img[@class="cardImage"]/@data-original').extract() if obj: # self.get_src(obj) item = cosItem() item['image_urls'] = obj # 注意这里必须传一个列表 yield item # 交给管道处理下载我们在这里利用到了xpath,他是一个非常强大的解析器。
放心我们下一篇文章就讲一下。😎
li.xpath('.//img[@class="cardImage"]/@data-original').extract()我们可以对reponse对象做xpath解析,得到的依然是selector对象,利用extract方法能拿到对应节点,返回的是一个列表。
如果你不想要返回列表,可以利用extract_first方法,他会返回列表中第一个元素。
上述代码非常简单,但是需要的配置可就有的说了。
你再去看看架构图。
其实我们主要写的部分是spider,即对数据做解析后yield给引擎。然后引擎自己去分配任务。
item = cosItem()这里的cosItem对象是便于管道存储,它的定义如下
items.pyclass cosItem(scrapy.Item): image_urls = scrapy.Field() # 必须叫 image_urls,存放图片链接的列表 images = scrapy.Field()接着就是管道的定义,用于帮助我们存储数据
from scrapy.pipelines.images import ImagesPipelinefrom scrapy import Request
class MyImagesPipeline(ImagesPipeline): # 发送图片下载请求,并将 item 中的信息通过 meta 传递下去 def get_media_requests(self, item, info): print("------ 我拿到了下载任务!------") for image_url in item['image_urls']: # 把图片的原始 URL放在 meta 里传下去 yield Request(image_url, meta={'image_name': image_url.split('/')[-1]})
# 自定义图片保存的路径和文件名 def file_path(self, request, response=None, info=None, *, item=None): # 从 meta 中取出刚才传过来的名字 image_name = request.meta['image_name'] # 直接返回文件名,图片就会保存在 IMAGES_STORE 的 full 目录下 return f'full/{image_name}'定义完成后,我们需要再settings里面配置,同时要下载图片,你就得用到pip install Pillow,scrapy内部用了这个库,所以必须下载。
settings.pyITEM_PIPELINES = { 'tutorial.pipelines.MyImagesPipeline': 1,}配置我们的管道,让数据流向他。
接着在命令行里运行即可拿到图片。
scrapy crawl cos(这里是你定义在类里面的名称)五、坠机迫降
在这之后,我们先来聊聊redis😎
打开settings.py进行配置
# 启用Scrapy-Redis的调度器SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 启用Scrapy-Redis的去重过滤器DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 启用Redis的持久化SCHEDULER_PERSIST = True
# 配置Redis连接REDIS_HOST = '127.0.0.1'REDIS_PORT = 6379
# 配置Item PipelineITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 300,}这样我们就能利用redis做分布式了。
以下是简单案例
我们需要先连接redis客户端
redis文件夹内.\redis.exe打开另一个终端.\redis-cli.exe
存储我们的键值url127.0.0.1:6379> lpush quotes:start_urls https://quotes.toscrape.com/page/1/(integer) 1127.0.0.1:6379> lpush quotes:start_urls https://quotes.toscrape.com/page/2/(integer) 2以下代码是利用redis的版本,这个只有分布式时用到的
from scrapy_redis.spiders import RedisSpiderclass QuotesSpider(RedisSpider):#这里继承的是redisspider! name = "quotes" # start_urls = [ # "https://quotes.toscrape.com/page/1/", # "https://quotes.toscrape.com/page/2/", # ] redis_key = "quotes:start_urls"#格式是爬虫名:strat_urls好啦,你已经可以入门了😋
难点主要在配置那,多看看官方文档,自然就会了。
部分信息可能已经过时









