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. 黄聪:wordpress获取hook所有function

    list_hooked_functions('wp_footer'); function list_hooked_functions($tag=false) { global $wp_filter; ...

  2. jquery 中prop和 attr

    prop就是给html中元素固有的属性赋值 而attr是给元素定义新的属性值.

  3. 关于Nginx配置性能优化

    基本的 (优化过的)配置 将修改的唯一文件是nginx.conf,其中包含Nginx不同模块的所有设置.在服务器的/etc/nginx目录中找到nginx.conf. 首先,我们将谈论一些全局设置,然 ...

  4. java设计模式-Command模式

    1.背景: 站在MM的角度,想命令追求者Boy干什么就干什么,而且将来还可以扩展,怎么做?   2.代码: Command.java: package com.cy.dp.command; publi ...

  5. bundle adjustment原理(1)

    那些光束平差的工具,比如SBA.SSBA之类的虽然好,然而例子和教程都不够多且不够详细,让初学者难以上手. 要传入的参数虽然有解释,然而却也不是十分清楚其含义,具体要怎么生成,生成为什么形式. 我在折 ...

  6. 【转】十年你能做的能得到的有多少?一个工科IT男的工作回忆

    https://blog.csdn.net/b5w2p0/article/details/8798989

  7. Java中的局部变量、成员变量和静态变量

    直接看代码 public class Variable { // 静态变量,属于类的变量,且用关键字static声明,不属于实例,虽然可以通过实例来调用,但是不建议 private static in ...

  8. c#特性学习(1)

    C#中的特性我认为可以理解为Java中的注解,见名知意,就是描述这个类或是属性的一个信息,是一个语法糖.原理运用的是反射,下面我来演示一下它的原理.其中引用了软谋的代码. 举一个栗子.我们在做code ...

  9. CentOS之Shell基础

    Linux默认的shell版本是bash. 我们所敲的命令都是有记录的:被保存在.bash_history文件中.只有当用户正常突出shell时,命令才会保存至.bash_history中. !!:连 ...

  10. 用dlopen,dlsym加载动态链接库.so中函数

    代码如下 static void *findSymbol(const char *path, const char *symbol) { void *handle = dlopen(path, RTL ...