Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >在Scrapy中如何使用aiohttp?

在Scrapy中如何使用aiohttp?

作者头像
青南
发布于 2020-07-16 06:18:39
发布于 2020-07-16 06:18:39
6.5K00
代码可运行
举报
文章被收录于专栏:未闻Code未闻Code
运行总次数:0
代码可运行

当我们从一些代理IP供应商购买代理IP时,他们可能是提供一个网址供我们查询当前可用的代理IP。我们周期性访问这个网址,拿到最新的IP,再分给爬虫使用。

最正确的做法,是单独有一个代理池程序,它负责请求这个网址,获取所有的代理IP,然后维护到一个池子里面。爬虫只需要从这个池子里面拿就可以了。

但有时候,因为某些原因,我们可能暂时无法或者暂时没有时间开发代理池程序,于是不得不直接让爬虫去请求代理IP供应商提供的网址获取代理IP。这个时候我们就面临了一个问题——爬虫应该怎么去请求代理网址?特别是当你使用的是Scrapy,那么这个问题变得尤为麻烦。

我们一般在Scrapy的下载器中间件里面设置爬虫的代理,但问题来了,在下载器中间件里面,你怎么发起网络请求?

于是很多人退而求其次,在下载器中间件里面,用requests来请求代理供应商的网址,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import requests
import json
import random


 class ProxyMiddleware:
     def process_request(self, request, spider):
         ip_info = requests.get('代理供应商的网址').json()
         ip_list = ip_info['proxy']
         ip = random.choice(ip_list)
         request.meta['proxy'] = ip

我们知道,Scrapy是一个异步爬虫框架,而requests是一个同步网络库。在Scrapy里面运行requests,会在requests等待请求的时候卡死整个Scrapy所有请求,从而拖慢整个爬虫的运行效率。

当然,你可以在Scrapy的爬虫里面,每次发起待爬请求前,先yield scrapy.Request('代理供应商网址'),请求一次代理供应商的网址,并在对应的回调函数里面拿到代理IP再发正常的请求。但这样的写法,会让爬虫代码变得很混乱。

为了避免这种混乱,在下载器中间件里面获取代理IP当然是最好的,但又不能用requests,应该如何是好呢?

实际上,我们可以在Scrapy里面,使用aiohttp,这样既能拿到代理IP,又能不阻塞整个爬虫。

Scrapy现在官方已经部分支持asyncio异步框架了,所以我们可以直接使用async def重新定义下载器中间件,并在里面使用aiohttp发起网络请求。

为了说明如何编写代码,我们用Scrapy创建一个示例爬虫。正常情况下,这个爬虫使用5个并发,每个请求延迟1秒访问http://exercise.kingname.info/exercise_middleware_ip/<page>并打印网站返回的结果,如下图所示。

请求频率和延迟如下图所示:

请求频率接近1秒钟一次。

现在,我们创建一个中间件,在这个中间件里面,使用requests请求一个需要延迟5秒钟才会返回的网址:

启动这个中间件,可以看到爬虫的速度明显变慢,几乎每5秒才能有一次返回,如下图所示:

从图中可以知道,requests卡住了整个Scrapy。在请求这个延迟5秒的网址时,Scrapy无法发起其他的请求。

现在,我们把requests替换为aiohttp,看看效果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import asyncio
import aiohttp


class TestAiohttp:
    async def get_ip(self):
        async with aiohttp.ClientSession() as client:
            resp = await client.get('http://httpbin.org/delay/5')
            result = await resp.json()
            print(result)

    async def process_request(self, request, spider):
        print('请求一个延迟5秒的网址开始')
        await asyncio.create_task(self.get_ip())

如下图所示:

现在,我们直接运行这个爬虫,理论上应该会遇到一个报错,如下图所示:

这是正常现象,要在Scrapy里面启用asyncio,需要额外在settings.py文件中,添加一行配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'

添加了这一行配置以后,再次运行爬虫,可以看到效果如下图所示:

刚刚启动的时候,爬虫会瞬间启动5个并发,所以会同时打印出请求一个延迟5秒的网址开始5次。然后稍稍停5秒,这5个请求几乎同时完成,于是同时打印出这个延迟网址的返回信息。接下来,后面的请求就是每秒一个。

这说明,Scrapy的异步机制成功启动了。首先第一个请求延迟网址发起以后,由于当前请求数还没有达到最大并发5,所以立刻就会利用这个等待时间发起第二个请求。由于现在请求数还不够5个,于是马上又会发起第三个请求,直到凑够5个并发请求为止。

当第一个请求延迟网站返回以后,Scrapy去请求正式的第一页。在等待第一页返回的过程中,第二个延迟请求完成并返回,于是Scrapy去请求正式网址的第二页……

总之,从Scrapy打印出的信息可以看出,现在Scrapy与aiohttp协同工作,异步机制正常运转。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
爬虫框架scrapy之中间件
中间件是Scrapy里面的一个核心概念。使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。
菲宇
2019/06/13
1.6K0
爬虫框架scrapy之中间件
彻底搞懂Scrapy的中间件(二)
在上一篇文章中介绍了下载器中间件的一些简单应用,现在再来通过案例说说如何使用下载器中间件集成Selenium、重试和处理请求异常。
青南
2019/01/09
1.5K0
为 aiohttp 爬虫注入灵魂
听说过异步爬虫的同学,应该或多或少听说过aiohttp这个库。它通过 Python 自带的async/await实现了异步爬虫。
青南
2019/12/25
1K0
为 aiohttp 爬虫注入灵魂
彻底搞懂Scrapy的中间件(一)
中间件是Scrapy里面的一个核心概念。使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫。
青南
2019/01/09
2.2K0
剖析灵魂,为什么aiohttp默认的写法那么慢?
在上一篇文章中,我们提到了 aiohttp 官方文档中的默认写法速度与 requests 单线程请求没有什么区别,需要通过使用asyncio.wait来加速 aiohttp 的请求。今天我们来探讨一下这背后的原因。
青南
2019/12/25
1.8K0
剖析灵魂,为什么aiohttp默认的写法那么慢?
爬虫框架scrapy
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中。 其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
菲宇
2019/06/12
1.8K0
爬虫框架scrapy
Scrapy源码解读
Scrapy一个比较完整的爬虫框架,包含了爬取任务的调度、多个线程同时爬取(异步多线程,不用等一个请求完成后才开始另一个请求)、自动过滤重复的链接等功能。使用者通过定义比较简单的爬虫类(例如目标网址、爬取的具体页面元素、存储的格式字段、数据清理逻辑),剩余的就可以交给scrapy完成爬取工作。
大数据技术架构
2023/03/08
8330
Scrapy源码解读
Scrapy 和 Pyppeteer 更优雅的对接方案
现在越来越多的网页都已经演变为 SPA 页面,而且越来越多的网站采用了各种 JavaScript 混淆和加密技术,这使得 JavaScript 逆向难度变得很大,Ajax 接口模拟爬取也变得越发困难,因此模拟浏览器爬取不失为一个不错的爬取方案。
崔庆才
2020/07/21
3.1K1
强大的异步爬虫 with aiohttp
看到现在网络上大多讲的都是requests、scrapy,却没有说到爬虫中的神器:aiohttp
小歪
2018/07/25
1.1K0
Python爬虫从入门到放弃(十七)之 Scrapy框架中Download Middleware用法
coders
2018/01/04
1.2K0
Python爬虫从入门到放弃(十七)之 Scrapy框架中Download Middleware用法
Python自动化开发学习-Scrapy
讲师博客:https://www.cnblogs.com/wupeiqi/p/6229292.html 中文资料(有示例参考):http://www.scrapyd.cn/doc/
py3study
2020/01/08
1.5K0
一篇文章理解Python异步编程的基本原理
未闻 Code 已经发布过很多篇关于异步爬虫与异步编程的文章,最近有读者希望我能深入介绍一下 asyncio 是如何通过单线程单进程实现并发效果的。以及异步代码是不是能在所有方面都代替同步代码。
青南
2020/02/19
1.1K1
一篇文章理解Python异步编程的基本原理
回调函数Callback —从同步思维切换到异步思维
这是一种非常常见的直线性思维,我先请求网站拿到 html,然后我再把 html 传给负责处理的函数。在整个过程中,“我“担任着调度的角色。
王图思睿
2021/06/16
7970
Python爬虫:使用Scrapy框架进行高效爬取
Python爬虫可使用的架构有很多,对于我而言,经常使用Scrapy异步处理框架Twisted,其实意思很明确,Scrapy可以实现多并发处理任务,同一时间将可以处理多个请求并且大大提高工作效率。
华科云商小徐
2023/12/04
3030
Scrapy的架构一、Scrapy的Twisted引擎模型二、Scrapy的性能模型三、Scrapy架构组件数据流(Data flow)四、Scrapy架构
Scrapy的架构太重要了,单用一篇文章再总结整合下。前两张图来自《Learning Scrapy》,第三张图来自Scrapy 1.0中文官方文档(该中文文档只到1.0版),第四张图来自Scrapy
SeanCheney
2018/04/24
2.2K0
Scrapy的架构一、Scrapy的Twisted引擎模型二、Scrapy的性能模型三、Scrapy架构组件数据流(Data flow)四、Scrapy架构
爬虫之scrapy框架(二)
当我们启动spider.py文件时,会执行我们设置好的start_urls,但是源码真正是如何处理的呢?我们进入scrapy.Spider查看源码,Spider类下有如下代码:
GH
2020/03/19
9570
5分钟快速掌握 scrapy 爬虫框架
scrapy是基于事件驱动的Twisted框架下用纯python写的爬虫框架。很早之前就开始用scrapy来爬取网络上的图片和文本信息,一直没有把细节记录下来。这段时间,因为工作需要又重拾scrapy爬虫,本文和大家分享下,包你一用就会, 欢迎交流。
Python知识大全
2020/12/15
7390
爬虫之scrapy框架
  何为框架,就相当于一个封装了很多功能的结构体,它帮我们把主要的结构给搭建好了,我们只需往骨架里添加内容就行。scrapy框架是一个为了爬取网站数据,提取数据的框架,我们熟知爬虫总共有四大部分,请求、响应、解析、存储,scrapy框架都已经搭建好了。scrapy是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架,scrapy使用了一种非阻塞的代码实现并发的,结构如下:
py3study
2020/01/17
1.3K0
Python | Python学习之常用项目代码(一)
本篇是咸鱼日常撸视频的时候记录的一些代码实例,可以直接运用到项目中但是有些代码的可用性没有那么好,旨在分享思路,不喜勿喷~
咸鱼学Python
2019/10/09
7550
浅度测评:requests、aiohttp、httpx 我应该用哪一个?
作者 l kingname 来源 l 未闻 Code(ID:itskingname)
andrew_a
2020/02/18
2.2K0
浅度测评:requests、aiohttp、httpx 我应该用哪一个?
相关推荐
爬虫框架scrapy之中间件
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文