Agent = client.Agent

class ScrapyAgent(object):

    _Agent = Agent#为twisted的client.Agent类
_ProxyAgent = ProxyAgent
_TunnelingAgent = TunnelingAgent def __init__(self, contextFactory=None, connectTimeout=10, bindAddress=None, pool=None,
maxsize=0, warnsize=0, fail_on_dataloss=True):
self._contextFactory = contextFactory
self._connectTimeout = connectTimeout
self._bindAddress = bindAddress
self._pool = pool
self._maxsize = maxsize
self._warnsize = warnsize
self._fail_on_dataloss = fail_on_dataloss
self._txresponse = None def _get_agent(self, request, timeout):#获得代理
bindaddress = request.meta.get('bindaddress') or self._bindAddress
proxy = request.meta.get('proxy')
if proxy:
_, _, proxyHost, proxyPort, proxyParams = _parse(proxy)
scheme = _parse(request.url)[0]
proxyHost = to_unicode(proxyHost)
omitConnectTunnel = b'noconnect' in proxyParams
if scheme == b'https' and not omitConnectTunnel:
proxyConf = (proxyHost, proxyPort,
request.headers.get(b'Proxy-Authorization', None))
return self._TunnelingAgent(reactor, proxyConf,
contextFactory=self._contextFactory, connectTimeout=timeout,
bindAddress=bindaddress, pool=self._pool)
else:
endpoint = TCP4ClientEndpoint(reactor, proxyHost, proxyPort,
timeout=timeout, bindAddress=bindaddress)
return self._ProxyAgent(endpoint) return self._Agent(reactor, contextFactory=self._contextFactory,
connectTimeout=timeout, bindAddress=bindaddress, pool=self._pool) def download_request(self, request):
timeout = request.meta.get('download_timeout') or self._connectTimeout
agent = self._get_agent(request, timeout) # request details
url = urldefrag(request.url)[0]
method = to_bytes(request.method)
headers = TxHeaders(request.headers)
if isinstance(agent, self._TunnelingAgent):
headers.removeHeader(b'Proxy-Authorization')
if request.body:
bodyproducer = _RequestBodyProducer(request.body)
elif method == b'POST':
# Setting Content-Length: 0 even for POST requests is not a
# MUST per HTTP RFCs, but it's common behavior, and some
# servers require this, otherwise returning HTTP 411 Length required
#
# RFC 7230#section-3.3.2:
# "a Content-Length header field is normally sent in a POST
# request even when the value is 0 (indicating an empty payload body)."
#
# Twisted < 17 will not add "Content-Length: 0" by itself;
# Twisted >= 17 fixes this;
# Using a producer with an empty-string sends `0` as Content-Length
# for all versions of Twisted.
bodyproducer = _RequestBodyProducer(b'')
else:
bodyproducer = None
start_time = time()
d = agent.request(#调用代理的请求
method, to_bytes(url, encoding='ascii'), headers, bodyproducer)
# set download latency
d.addCallback(self._cb_latency, request, start_time)
# response body is ready to be consumed
d.addCallback(self._cb_bodyready, request)
d.addCallback(self._cb_bodydone, request, url)
# check download timeout
self._timeout_cl = reactor.callLater(timeout, d.cancel)
d.addBoth(self._cb_timeout, req
class Agent(_AgentBase):

    def __init__(self, reactor,
contextFactory=BrowserLikePolicyForHTTPS(),
connectTimeout=None, bindAddress=None,
pool=None): if not IPolicyForHTTPS.providedBy(contextFactory):
warnings.warn(
repr(contextFactory) +
" was passed as the HTTPS policy for an Agent, but it does "
"not provide IPolicyForHTTPS. Since Twisted 14.0, you must "
"pass a provider of IPolicyForHTTPS.",
stacklevel=2, category=DeprecationWarning
)
contextFactory = _DeprecatedToCurrentPolicyForHTTPS(contextFactory)
endpointFactory = _StandardEndpointFactory(
reactor, contextFactory, connectTimeout, bindAddress)
self._init(reactor, endpointFactory, pool) @classmethod
def usingEndpointFactory(cls, reactor, endpointFactory, pool=None):
"""
Create a new L{Agent} that will use the endpoint factory to figure
out how to connect to the server. """
agent = cls.__new__(cls)
agent._init(reactor, endpointFactory, pool)
return agent def _init(self, reactor, endpointFactory, pool): _AgentBase.__init__(self, reactor, pool)
self._endpointFactory = endpointFactory def _getEndpoint(self, uri): return self._endpointFactory.endpointForURI(uri) def request(self, method, uri, headers=None, bodyProducer=None):
"""
Issue a request to the server indicated by the given C{uri}. An existing connection from the connection pool may be used or a new
one may be created. I{HTTP} and I{HTTPS} schemes are supported in C{uri}. @see: L{twisted.web.iweb.IAgent.request}
"""
parsedURI = URI.fromBytes(uri)
try:
endpoint = self._getEndpoint(parsedURI)
except SchemeNotSupported:
return defer.fail(Failure())
key = (parsedURI.scheme, parsedURI.host, parsedURI.port)#key值的计算
return self._requestWithEndpoint(key, endpoint, method, parsedURI,
headers, bodyProducer,
parsedURI.originForm)
#从class HTTPConnectionPool(object)中取得一个连接
def getConnection(self, key, endpoint): # Try to get cached version:
connections = self._connections.get(key)
while connections:
connection = connections.pop(0)
# Cancel timeout:
self._timeouts[connection].cancel()
del self._timeouts[connection]
if connection.state == "QUIESCENT":#该连接为空闲状态
if self.retryAutomatically:
newConnection = lambda: self._newConnection(key, endpoint)
connection = _RetryingHTTP11ClientProtocol(
connection, newConnection)
return defer.succeed(connection)#成功 return self._newConnection(key, endpoint)

scrapy之downloader执行流程的更多相关文章

  1. Scrapy框架的执行流程解析

    这里主要介绍七个大类Command->CrawlerProcess->Crawler->ExecutionEngine->sceduler另外还有两个类:Request和Htt ...

  2. scrapy架构图与执行流程

    概览 本文描述了Scrapy的架构图.数据流动.以及个组件的相互作用 架构图与数据流 上图中各个数字与箭头代表数据的流动方向和流动顺序,具体执行流程如下: 0. Scrapy将会实例化一个Crawle ...

  3. 爬虫--Scrapy之Downloader Middleware

    下载器中间件(Downloader Middleware) 下载器中间件是介于Scrapy的request/response处理的钩子框架. 是用于全局修改Scrapy request和respons ...

  4. Scrapy五大核心组件工作流程

    一.Scrapy五大核心组件工作流程 1.核心组件 # 引擎(Scrapy) 对整个系统的数据流进行处理, 触发事务(框架核心). # 调度器(Scheduler) 用来接受引擎发过来的请求. 由过滤 ...

  5. 步步深入:MySQL架构总览->查询执行流程->SQL解析顺序

    前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来 ...

  6. 第二天 ci执行流程

    第二天 ci执行流程 welcome 页面 this this->load 单入口框架index.php 两个文件夹 system application定义 定义常亮路径 载入 codeign ...

  7. 轻量级前端MVVM框架avalon - 执行流程2

    接上一章 执行流程1 在这一大堆扫描绑定方法中应该会哪些实现? 首先我们看avalon能帮你做什么? 数据填充,比如表单的一些初始值,切换卡的各个面板的内容({{xxx}},{{xxx|html}}, ...

  8. [Java编程思想-学习笔记]第4章 控制执行流程

    4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: char test(int score) { if ...

  9. ThinkPHP2.2框架执行流程图,ThinkPHP控制器的执行流程

    ThinkPHP2.2框架执行原理.流程图在线手册 ThinkPHP控制器的执行流程 对用户的第一次URL访问 http://<serverIp>/My/index.php/Index/s ...

随机推荐

  1. JAVA开源B2C系统

    前言 最近有人想面向境外销售商品,但是又不想依托于亚马逊这些平台,于是找我来帮忙想弄个B2C系统.因为刚开始只是打算试试水,也就不打算投入多少成本了.所以这边就考虑使用开源的B2C系统来直接使用了. ...

  2. jquery zTree搜索高亮的例子

    思路: 搜索的时候发请求到后台,后台根据关键字找到匹配的节点,并将这些节点添加一个标志light: 后面就根据这个light为true就高亮,false就不高亮: 后台将这些节点返回到前台,前台展示: ...

  3. js堆和栈

    一.栈 栈:英文为“stack”: 定义:一种存放数据的内存区域: 特点: ①LIFO,后进先出: 可视化描述: ②调用栈,函数或者子例程像堆积木一样存放,以实现层层调用: 函数调用形成一个栈帧: f ...

  4. [转][html]设置IIS 默认页

    <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.we ...

  5. 关于Strategy和State设计模式

    之前,我在描述我所采用的设计模式时,一直在Strategy和State之间犹豫,略微有些拿捏不准,说哪种设计模式好.结果到最后,会根据自己所想,觉得是State就是State,觉得Strategy就是 ...

  6. 在docker宿主机上查找指定容器内运行的所有进程的PID

    转载 https://www.cnblogs.com/keithtt/p/7591097.html 找到指定容器的所有进程的PID可以更方便的对容器进程进行管理,特别是在某些容器卡住无法连接的场景. ...

  7. [UE4]地图缩放

    一.创建一个设置UI比例尺的函数 二.通过Get Cached Geometry获得当前UI实际显示的尺寸,Get Desired Size获得当前UI原始尺寸,计算得到UI缩放比例尺 三.地图比例尺 ...

  8. [UE4]创建游戏、加入游戏

    google搜: UE4 compile dedicated server,编译UE4专用服务器 UE4默认网络端口可以在引擎配置文件中修改: 一.创建文件.需要修改一下工程的配置文件DefaultE ...

  9. 2018年最新PHP面试题

    面试之前多看看公司的资料,可以看出面试的公司主要做什么,电商,数据库,php函数,sql的优化,接口,session和cookie等经常会问到,都是必问之题,这其中有一部分题目摘抄自网络,回答也不错 ...

  10. linux达人养成计划

    一.命令基本格式: ls -1 详细列表 (ll) -h 人性化显示文件大小 -a 显示所有文件,包括隐藏文件 -d 查看目录属性 -i 显示iNode 二.文件处理命令 mkdir -p [目录名] ...