ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 请求和响应 > 译者:[OSGeo 中国](https://www.osgeo.cn/) 零星用途 [`Request`](#scrapy.http.Request "scrapy.http.Request") 和 [`Response`](#scrapy.http.Response "scrapy.http.Response") 用于对网站进行爬网的对象。 通常, [`Request`](#scrapy.http.Request "scrapy.http.Request") 对象在spider中生成并在系统中传递,直到它们到达下载程序,下载程序执行请求并返回 [`Response`](#scrapy.http.Response "scrapy.http.Response") 返回发出请求的spider的对象。 两个 [`Request`](#scrapy.http.Request "scrapy.http.Request") 和 [`Response`](#scrapy.http.Response "scrapy.http.Response") 类具有子类,这些子类添加了基类中不需要的功能。这些在下面的 [请求子类](#topics-request-response-ref-request-subclasses) 和 [响应子类](#topics-request-response-ref-response-subclasses) . ## 请求对象 ```py class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback, flags]) ``` A [`Request`](#scrapy.http.Request "scrapy.http.Request") 对象表示一个HTTP请求,通常由spider生成并由下载程序执行,从而生成一个 [`Response`](#scrapy.http.Response "scrapy.http.Response") . | 参数: | * **url** (_string_) -- 此请求的URL * **callback** (_callable_) -- 将以此请求的响应(一旦下载)作为第一个参数调用的函数。有关详细信息,请参阅 [向回调函数传递附加数据](#topics-request-response-ref-request-callback-arguments) 下面。如果请求未指定回调,则蜘蛛 [`parse()`](spiders.html#scrapy.spiders.Spider.parse "scrapy.spiders.Spider.parse") 将使用方法。请注意,如果在处理过程中引发异常,则改为调用errback。 * **method** (_string_) -- 此请求的HTTP方法。默认为 `'GET'` . * **meta** (_dict_) -- 的初始值 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 属性。如果给定,则将浅复制传入此参数的dict。 * **body** (_str_ _or_ _unicode_) -- 请求主体。如果A `unicode` 传递,然后将其编码为 `str` 使用 `encoding` 通过(默认为 `utf-8` )如果 `body` 如果未给定,则存储空字符串。无论此参数的类型如何,存储的最终值都将是 `str` (永远) `unicode` 或 `None` ) * **headers** (_dict_) -- 此请求的头。dict值可以是字符串(对于单值头)或列表(对于多值头)。如果 `None` 作为值传递,HTTP头将不会被发送。 * **cookies** (_dict_ _or_ _list_) -- 请求cookies。这些可以用两种形式发送。1。使用dict::request_with_cookies=request(url=“[http://www.example.com](http://www.example.com)”,cookies=货币“:'usd”,country“:'uy”)2。使用dicts::request_with_cookies=request(url=“[http://www.example.com](http://www.example.com)”,cookies)列表= [{{'name': 'currency', 'value': 'USD', 'domain': 'example.com', 'path': '/currency'}}] )后一个表单允许自定义 `domain` 和 `path` cookie的属性。只有在为以后的请求保存cookie时,这才有用。…reqmeta::当某些站点返回cookie(响应中)时,不要合并cookie。这些cookie存储在该域的cookie中,并将在将来的请求中再次发送。这是任何常规Web浏览器的典型行为。但是,如果出于某种原因,您希望避免与现有cookie合并,您可以通过设置 `dont_merge_cookies` 中的“真”键 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") . 不合并cookies的请求示例::request_with_cookies=request(url=“[http://www.example.com](http://www.example.com)”,cookies=currency':'usd','country':'uy',meta=不合并_cookies':true)有关详细信息,请参阅 [CookiesMiddleware](downloader-middleware.html#cookies-mw) . * **encoding** (_string_) -- 此请求的编码(默认为 `'utf-8'` )此编码将用于对URL进行百分比编码并将正文转换为 `str` (如果给予 `unicode` ) * **priority** (_int_) -- 此请求的优先级(默认为 `0` )调度程序使用优先级定义用于处理请求的顺序。优先级值较高的请求将更早执行。允许负值以表示相对较低的优先级。 * **dont_filter** (_boolean_) -- 指示调度程序不应筛选此请求。当您希望多次执行相同的请求时,可以使用此选项忽略重复的筛选器。小心使用,否则会进入爬行循环。默认为 `False` . * **errback** (_callable_) -- 如果在处理请求时引发任何异常,则将调用的函数。这包括404 HTTP错误等失败的页面。它收到一个 [Twisted Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) 实例作为第一个参数。有关详细信息,请参阅 [使用errbacks捕获请求处理中的异常](#topics-request-response-ref-errbacks) 下面。 * **flags** (_list_) -- 发送到请求的标志可用于日志记录或类似用途。 | | --- | --- | ```py url ``` 包含此请求的URL的字符串。请记住,此属性包含转义的URL,因此它可以不同于构造函数中传递的URL。 此属性是只读的。要更改请求的URL,请使用 [`replace()`](#scrapy.http.Request.replace "scrapy.http.Request.replace") . ```py method ``` 表示请求中HTTP方法的字符串。这保证是大写的。例子: `"GET"` , `"POST"` , `"PUT"` 等 ```py headers ``` 包含请求头的类似字典的对象。 ```py body ``` 包含请求主体的str。 此属性是只读的。要更改请求正文,请使用 [`replace()`](#scrapy.http.Request.replace "scrapy.http.Request.replace") . ```py meta ``` 包含此请求的任意元数据的dict。对于新请求,此dict是空的,通常由不同的零碎组件(扩展、中间产品等)填充。所以这个dict中包含的数据取决于您启用的扩展名。 见 [请求.meta特殊键](#topics-request-meta) 获取scrapy识别的特殊元键列表。 这个字典是 [shallow copied](https://docs.python.org/2/library/copy.html) 当使用 `copy()` 或 `replace()` 方法,也可以通过 `response.meta` 属性。 ```py copy() ``` 返回一个新请求,它是此请求的副本。参见: [向回调函数传递附加数据](#topics-request-response-ref-request-callback-arguments) . ```py replace([url, method, headers, body, cookies, meta, encoding, dont_filter, callback, errback]) ``` 返回具有相同成员的请求对象,除了那些通过指定的关键字参数赋予新值的成员。属性 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 默认情况下复制(除非在 `meta` 争论)。也见 [向回调函数传递附加数据](#topics-request-response-ref-request-callback-arguments) . ### 向回调函数传递附加数据 请求的回调是一个函数,在下载请求的响应时将调用该函数。将使用下载的 [`Response`](#scrapy.http.Response "scrapy.http.Response") 对象作为其第一个参数。 例子:: ```py def parse_page1(self, response): return scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2) def parse_page2(self, response): # this would log http://www.example.com/some_page.html self.logger.info("Visited %s", response.url) ``` 在某些情况下,您可能对向这些回调函数传递参数感兴趣,以便稍后在第二个回调中接收这些参数。你可以使用 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 属性。 下面是一个示例,说明如何使用此机制传递一个项,以填充来自不同页面的不同字段: ```py def parse_page1(self, response): item = MyItem() item['main_url'] = response.url request = scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2) request.meta['item'] = item yield request def parse_page2(self, response): item = response.meta['item'] item['other_url'] = response.url yield item ``` ### 使用errbacks捕获请求处理中的异常 请求的errback是一个函数,在处理异常时将调用该函数。 它收到一个 [Twisted Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) 实例作为第一个参数,可用于跟踪连接建立超时、DNS错误等。 下面是一个spider示例,记录所有错误,并在需要时捕获一些特定错误: ```py import scrapy from scrapy.spidermiddlewares.httperror import HttpError from twisted.internet.error import DNSLookupError from twisted.internet.error import TimeoutError, TCPTimedOutError class ErrbackSpider(scrapy.Spider): name = "errback_example" start_urls = [ "http://www.httpbin.org/", # HTTP 200 expected "http://www.httpbin.org/status/404", # Not found error "http://www.httpbin.org/status/500", # server issue "http://www.httpbin.org:12345/", # non-responding host, timeout expected "http://www.httphttpbinbin.org/", # DNS error expected ] def start_requests(self): for u in self.start_urls: yield scrapy.Request(u, callback=self.parse_httpbin, errback=self.errback_httpbin, dont_filter=True) def parse_httpbin(self, response): self.logger.info('Got successful response from {}'.format(response.url)) # do something useful here... def errback_httpbin(self, failure): # log all failures self.logger.error(repr(failure)) # in case you want to do something special for some errors, # you may need the failure's type: if failure.check(HttpError): # these exceptions come from HttpError spider middleware # you can get the non-200 response response = failure.value.response self.logger.error('HttpError on %s', response.url) elif failure.check(DNSLookupError): # this is the original request request = failure.request self.logger.error('DNSLookupError on %s', request.url) elif failure.check(TimeoutError, TCPTimedOutError): request = failure.request self.logger.error('TimeoutError on %s', request.url) ``` ## 请求.meta特殊键 这个 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 属性可以包含任意数据,但有一些特殊的键可以被scrapy及其内置扩展识别。 那些是: * [`dont_redirect`](downloader-middleware.html#std:reqmeta-dont_redirect) * [`dont_retry`](downloader-middleware.html#std:reqmeta-dont_retry) * [`handle_httpstatus_list`](spider-middleware.html#std:reqmeta-handle_httpstatus_list) * [`handle_httpstatus_all`](spider-middleware.html#std:reqmeta-handle_httpstatus_all) * [`dont_merge_cookies`](#std:reqmeta-dont_merge_cookies) * [`cookiejar`](downloader-middleware.html#std:reqmeta-cookiejar) * [`dont_cache`](downloader-middleware.html#std:reqmeta-dont_cache) * [`redirect_reasons`](downloader-middleware.html#std:reqmeta-redirect_reasons) * [`redirect_urls`](downloader-middleware.html#std:reqmeta-redirect_urls) * [`bindaddress`](#std:reqmeta-bindaddress) * [`dont_obey_robotstxt`](downloader-middleware.html#std:reqmeta-dont_obey_robotstxt) * [`download_timeout`](#std:reqmeta-download_timeout) * [`download_maxsize`](settings.html#std:reqmeta-download_maxsize) * [`download_latency`](#std:reqmeta-download_latency) * [`download_fail_on_dataloss`](#std:reqmeta-download_fail_on_dataloss) * [`proxy`](downloader-middleware.html#std:reqmeta-proxy) * `ftp_user` (见 [`FTP_USER`](settings.html#std:setting-FTP_USER) 更多信息) * `ftp_password` (见 [`FTP_PASSWORD`](settings.html#std:setting-FTP_PASSWORD) 更多信息) * [`referrer_policy`](spider-middleware.html#std:reqmeta-referrer_policy) * [`max_retry_times`](#std:reqmeta-max_retry_times) ### 绑定地址 用于执行请求的传出IP地址的IP。 ### download_timeout 下载程序在超时前等待的时间(以秒计)。参见: [`DOWNLOAD_TIMEOUT`](settings.html#std:setting-DOWNLOAD_TIMEOUT) . ### download_latency 自请求启动以来,获取响应所花费的时间,即通过网络发送的HTTP消息。只有在下载响应后,此元键才可用。虽然大多数其他的元键用于控制零碎的行为,但这个元键应该是只读的。 ### download_fail_on_dataloss 是否在错误的响应上失败。见: [`DOWNLOAD_FAIL_ON_DATALOSS`](settings.html#std:setting-DOWNLOAD_FAIL_ON_DATALOSS) . ### max_retry_times 使用meta key设置每个请求的重试次数。初始化时, [`max_retry_times`](#std:reqmeta-max_retry_times) 元键优先于 [`RETRY_TIMES`](downloader-middleware.html#std:setting-RETRY_TIMES) 设置。 ## 请求子类 这是内置的列表 [`Request`](#scrapy.http.Request "scrapy.http.Request") 子类。您还可以将其子类化,以实现您自己的自定义功能。 ### FormRequest对象 FormRequest类扩展了基 [`Request`](#scrapy.http.Request "scrapy.http.Request") 具有处理HTML表单的功能。它使用 [lxml.html forms](http://lxml.de/lxmlhtml.html#forms) 使用表单数据预填充表单域的步骤 [`Response`](#scrapy.http.Response "scrapy.http.Response") 物体。 ```py class scrapy.http.FormRequest(url[, formdata, ...]) ``` 这个 [`FormRequest`](#scrapy.http.FormRequest "scrapy.http.FormRequest") 类向构造函数添加新参数。其余参数与 [`Request`](#scrapy.http.Request "scrapy.http.Request") 在这里没有记录。 | 参数: | **formdata** (_dict_ _or_ _iterable of tuples_) -- 是包含HTML表单数据的字典(或可为(键、值)元组),这些数据将被URL编码并分配给请求主体。 | | --- | --- | 这个 [`FormRequest`](#scrapy.http.FormRequest "scrapy.http.FormRequest") 除了标准之外,对象还支持以下类方法 [`Request`](#scrapy.http.Request "scrapy.http.Request") 方法: ```py classmethod from_response(response[, formname=None, formid=None, formnumber=0, formdata=None, formxpath=None, formcss=None, clickdata=None, dont_click=False, ...]) ``` 返回新的 [`FormRequest`](#scrapy.http.FormRequest "scrapy.http.FormRequest") 对象,其表单字段值预填充在HTML中 `<form>` 包含在给定响应中的元素。有关示例,请参见 [使用formRequest.from_response()模拟用户登录](#topics-request-response-ref-request-userlogin) . 默认情况下,策略是在任何看起来可单击的窗体控件上自动模拟单击,如 `<input type="submit">` . 尽管这非常方便,而且常常是所需的行为,但有时它可能会导致难以调试的问题。例如,当处理使用javascript填充和/或提交的表单时,默认 [`from_response()`](#scrapy.http.FormRequest.from_response "scrapy.http.FormRequest.from_response") 行为可能不是最合适的。要禁用此行为,可以设置 `dont_click` 参数 `True` . 此外,如果要更改单击的控件(而不是禁用它),还可以使用 `clickdata` 争论。 警告 对于选项值中有前导空格或尾随空格的select元素,使用此方法将不起作用,因为 [bug in lxml](https://bugs.launchpad.net/lxml/+bug/1665241) ,应在LXML 3.8及更高版本中修复。 | 参数: | * **response** ([`Response`](#scrapy.http.Response "scrapy.http.Response") object) -- 包含用于预填充表单字段的HTML表单的响应 * **formname** (_string_) -- 如果给定,将使用名称属性设置为该值的表单。 * **formid** (_string_) -- 如果给定,将使用ID属性设置为该值的表单。 * **formxpath** (_string_) -- 如果给定,将使用与xpath匹配的第一个表单。 * **formcss** (_string_) -- 如果给定,将使用与CSS选择器匹配的第一个表单。 * **formnumber** (_integer_) -- 当响应包含多个表单时要使用的表单数。第一个(也是默认值)是 `0` . * **formdata** (_dict_) -- 要在表单数据中重写的字段。如果响应中已存在字段 `<form>` 元素,其值将被此参数中传递的值重写。如果此参数中传递的值是 `None` ,即使响应中存在该字段,该字段也不会包含在请求中。 `<form>` 元素。 * **clickdata** (_dict_) -- 用于查找单击的控件的属性。如果没有给出,将提交表单数据,模拟单击第一个可单击元素。除了HTML属性之外,控件还可以通过其相对于表单内其他可提交输入的基于零的索引进行标识,方法是 `nr` 属性。 * **dont_click** (_boolean_) -- 如果为真,则表单数据将在不单击任何元素的情况下提交。 | | --- | --- | 该类方法的其他参数直接传递给 [`FormRequest`](#scrapy.http.FormRequest "scrapy.http.FormRequest") 建造师。 0.10.3 新版功能: 这个 `formname` 参数。 0.17 新版功能: 这个 `formxpath` 参数。 1.1.0 新版功能: 这个 `formcss` 参数。 1.1.0 新版功能: 这个 `formid` 参数。 ### 请求使用示例 #### 使用FormRequest通过HTTP Post发送数据 如果您想在spider中模拟HTML表单发布并发送几个键值字段,可以返回 [`FormRequest`](#scrapy.http.FormRequest "scrapy.http.FormRequest") 像这样的物体: ```py return [FormRequest(url="http://www.example.com/post/action", formdata={'name': 'John Doe', 'age': '27'}, callback=self.after_post)] ``` #### 使用formRequest.from_response()模拟用户登录 网站通常通过 `<input type="hidden">` 元素,例如与会话相关的数据或身份验证令牌(用于登录页)。当进行抓取时,您将希望这些字段自动预填充,并且只覆盖其中的几个字段,例如用户名和密码。你可以使用 [`FormRequest.from_response()`](#scrapy.http.FormRequest.from_response "scrapy.http.FormRequest.from_response") 此作业的方法。下面是一个蜘蛛的例子,它使用它: ```py import scrapy def authentication_failed(response): # TODO: Check the contents of the response and return True if it failed # or False if it succeeded. pass class LoginSpider(scrapy.Spider): name = 'example.com' start_urls = ['http://www.example.com/users/login.php'] def parse(self, response): return scrapy.FormRequest.from_response( response, formdata={'username': 'john', 'password': 'secret'}, callback=self.after_login ) def after_login(self, response): if authentication_failed(response): self.logger.error("Login failed") return # continue scraping with authenticated session... ``` ### JSONRequest jsonRequest类扩展了基 [`Request`](#scrapy.http.Request "scrapy.http.Request") 类,具有处理JSON请求的功能。 ```py class scrapy.http.JSONRequest(url[, ... data, dumps_kwargs]) ``` 这个 [`JSONRequest`](#scrapy.http.JSONRequest "scrapy.http.JSONRequest") 类向构造函数添加两个新参数。其余参数与 [`Request`](#scrapy.http.Request "scrapy.http.Request") 在这里没有记录。 使用 [`JSONRequest`](#scrapy.http.JSONRequest "scrapy.http.JSONRequest") 将设置 `Content-Type` 报头到 `application/json` 和 `Accept` 报头到 `application/json, text/javascript, */*; q=0.01` | 参数: | * **data** (_JSON serializable object_) -- 是需要对JSON编码并分配给主体的任何JSON可序列化对象。如果 [`Request.body`](#scrapy.http.Request.body "scrapy.http.Request.body") 提供了参数。此参数将被忽略。如果 [`Request.body`](#scrapy.http.Request.body "scrapy.http.Request.body") 未提供参数,并且提供了数据参数 [`Request.method`](#scrapy.http.Request.method "scrapy.http.Request.method") 将被设置为 `'POST'` 自动地。 * **dumps_kwargs** (_dict_) -- 将传递给基础的参数 [json.dumps](https://docs.python.org/3/library/json.html#json.dumps) 方法,用于将数据序列化为JSON格式。 | | --- | --- | ### json请求使用示例 使用JSON负载发送JSON POST请求: ```py data = { 'name1': 'value1', 'name2': 'value2', } yield JSONRequest(url='http://www.example.com/post/action', data=data) ``` ## 响应对象 ```py class scrapy.http.Response(url[, status=200, headers=None, body=b'', flags=None, request=None]) ``` A [`Response`](#scrapy.http.Response "scrapy.http.Response") 对象表示一个HTTP响应,它通常被下载(由下载程序)并送入spider进行处理。 | 参数: | * **url** (_string_) -- 此响应的URL * **status** (_integer_) -- 响应的HTTP状态。默认为 `200` . * **headers** (_dict_) -- 此响应的头。dict值可以是字符串(对于单值头)或列表(对于多值头)。 * **body** (_bytes_) -- 响应主体。要以str(python 2中的unicode)形式访问解码后的文本,可以使用 `response.text` 从编码感知 [Response subclass](#topics-request-response-ref-response-subclasses) ,如 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") . * **flags** (_list_) -- 是一个列表,其中包含 [`Response.flags`](#scrapy.http.Response.flags "scrapy.http.Response.flags") 属性。如果给定,则将浅复制列表。 * **request** ([`Request`](#scrapy.http.Request "scrapy.http.Request") object) -- 的初始值 [`Response.request`](#scrapy.http.Response.request "scrapy.http.Response.request") 属性。这代表 [`Request`](#scrapy.http.Request "scrapy.http.Request") 产生了这个响应。 | | --- | --- | ```py url ``` 包含响应的URL的字符串。 此属性是只读的。要更改响应的URL,请使用 [`replace()`](#scrapy.http.Response.replace "scrapy.http.Response.replace") . ```py status ``` 表示响应的HTTP状态的整数。例子: `200` , `404` . ```py headers ``` 包含响应头的类似字典的对象。可以使用访问值 `get()` 返回具有指定名称的第一个头值,或 `getlist()` 返回具有指定名称的所有头值。例如,此调用将为您提供标题中的所有cookie:: ```py response.headers.getlist('Set-Cookie') ``` ```py body ``` 这个反应的主体。记住response.body始终是一个bytes对象。如果要使用Unicode版本,请使用 [`TextResponse.text`](#scrapy.http.TextResponse.text "scrapy.http.TextResponse.text") (仅在 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 和子类)。 此属性是只读的。要更改响应主体,请使用 [`replace()`](#scrapy.http.Response.replace "scrapy.http.Response.replace") . ```py request ``` 这个 [`Request`](#scrapy.http.Request "scrapy.http.Request") 生成此响应的对象。在响应和请求通过所有 [Downloader Middlewares](downloader-middleware.html#topics-downloader-middleware) . 特别是,这意味着: * HTTP重定向将导致将原始请求(重定向前的URL)分配给重定向响应(重定向后的最终URL)。 * response.request.url并不总是等于response.url * 此属性仅在spider代码和 [Spider Middlewares](spider-middleware.html#topics-spider-middleware) ,但在下载器中间软件(尽管您通过其他方式有可用的请求)和 [`response_downloaded`](signals.html#std:signal-response_downloaded) 信号。 ```py meta ``` 到的快捷方式 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 的属性 [`Response.request`](#scrapy.http.Response.request "scrapy.http.Response.request") 对象(I. `self.request.meta` ) 不像 [`Response.request`](#scrapy.http.Response.request "scrapy.http.Response.request") 属性 [`Response.meta`](#scrapy.http.Response.meta "scrapy.http.Response.meta") 属性是沿着重定向和重试传播的,因此您将获得原始的 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 从你的蜘蛛那里送来的。 参见 [`Request.meta`](#scrapy.http.Request.meta "scrapy.http.Request.meta") 属性 ```py flags ``` 包含此响应标志的列表。标记是用于标记响应的标签。例如: `'cached'` , `'redirected` '等,它们显示在响应的字符串表示形式上 (<cite>__str__</cite> 方法)由引擎用于日志记录。 ```py copy() ``` 返回此响应的副本的新响应。 ```py replace([url, status, headers, body, request, flags, cls]) ``` 返回具有相同成员的响应对象,除了那些通过指定的关键字参数赋予新值的成员。属性 [`Response.meta`](#scrapy.http.Response.meta "scrapy.http.Response.meta") 默认情况下是复制的。 ```py urljoin(url) ``` 通过组合响应的 [`url`](#scrapy.http.Response.url "scrapy.http.Response.url") 有一个可能的相对URL。 这是包装纸 [urlparse.urljoin](https://docs.python.org/2/library/urlparse.html#urlparse.urljoin) ,这仅仅是进行此呼叫的别名: ```py urlparse.urljoin(response.url, url) ``` ```py follow(url, callback=None, method='GET', headers=None, body=None, cookies=None, meta=None, encoding='utf-8', priority=0, dont_filter=False, errback=None) ``` 返回A [`Request`](#scrapy.http.Request "scrapy.http.Request") 要跟踪链接的实例 `url` . 它接受与 `Request.__init__` 方法,但 `url` 可以是相对URL或 `scrapy.link.Link` 对象,而不仅仅是绝对URL。 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 提供了一个 [`follow()`](#scrapy.http.TextResponse.follow "scrapy.http.TextResponse.follow") 方法,它除了支持绝对/相对URL和链接对象之外还支持选择器。 ## 响应子类 下面是可用的内置响应子类的列表。您还可以对响应类进行子类化,以实现您自己的功能。 ### 文本响应对象 ```py class scrapy.http.TextResponse(url[, encoding[, ...]]) ``` [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 对象将编码功能添加到基 [`Response`](#scrapy.http.Response "scrapy.http.Response") 类,它只用于二进制数据,如图像、声音或任何媒体文件。 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 对象除了支持基参数外,还支持新的构造函数参数 [`Response`](#scrapy.http.Response "scrapy.http.Response") 物体。其余功能与 [`Response`](#scrapy.http.Response "scrapy.http.Response") 类,此处未记录。 | 参数: | **encoding** (_string_) -- 包含用于此响应的编码的字符串。如果创建一个 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 对象具有Unicode主体,将使用此编码对其进行编码(记住主体属性始终是字符串)。如果 `encoding` 是 `None` (默认值),将在响应头和正文中查找编码。 | | --- | --- | [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 除了标准之外,对象还支持以下属性 [`Response`](#scrapy.http.Response "scrapy.http.Response") 一: ```py text ``` 响应主体,作为Unicode。 一样 `response.body.decode(response.encoding)` ,但结果在第一次调用后缓存,因此您可以访问 `response.text` 多次无额外开销。 注解 `unicode(response.body)` 不是将响应正文转换为Unicode的正确方法:您将使用系统默认编码(通常 `ascii` )而不是响应编码。 ```py encoding ``` 带有此响应编码的字符串。按顺序尝试以下机制来解决编码问题: 1. 在构造函数中传递的编码 `encoding` 论点 2. 内容类型HTTP头中声明的编码。如果此编码无效(即未知),则忽略此编码,并尝试下一个解决机制。 3. 响应正文中声明的编码。TextResponse类不为此提供任何特殊功能。然而, [`HtmlResponse`](#scrapy.http.HtmlResponse "scrapy.http.HtmlResponse") 和 [`XmlResponse`](#scrapy.http.XmlResponse "scrapy.http.XmlResponse") 上课。 4. 通过查看响应主体推断出的编码。这是更脆弱的方法,也是最后一个尝试的方法。 ```py selector ``` A [`Selector`](selectors.html#scrapy.selector.Selector "scrapy.selector.Selector") 使用响应作为目标的实例。选择器在第一次访问时被惰性地实例化。 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 对象除了支持标准之外还支持以下方法 [`Response`](#scrapy.http.Response "scrapy.http.Response") 一: ```py xpath(query) ``` 捷径 `TextResponse.selector.xpath(query)` :: ```py response.xpath('//p') ``` ```py css(query) ``` 捷径 `TextResponse.selector.css(query)` :: ```py response.css('p') ``` ```py follow(url, callback=None, method='GET', headers=None, body=None, cookies=None, meta=None, encoding=None, priority=0, dont_filter=False, errback=None) ``` 返回A [`Request`](#scrapy.http.Request "scrapy.http.Request") 要跟踪链接的实例 `url` . 它接受与 `Request.__init__` 方法,但 `url` 不仅可以是绝对URL,而且可以是 * 相对URL; * scrappy.link.link对象(例如链接提取程序结果); * 属性选择器(非选择器列表)-例如 `response.css('a::attr(href)')[0]` 或 `response.xpath('//img/@src')[0]` . * 选择器 `<a>` 或 `<link>` 元素,例如 `response.css('a.my_link')[0]` . 见 [创建请求的快捷方式](../intro/tutorial.html#response-follow-example) 用于示例。 ```py body_as_unicode() ``` 一样 [`text`](#scrapy.http.TextResponse.text "scrapy.http.TextResponse.text") ,但作为一种方法提供。此方法是为了向后兼容而保留的;请首选 `response.text` . ### HTMLResponse对象 ```py class scrapy.http.HtmlResponse(url[, ...]) ``` 这个 [`HtmlResponse`](#scrapy.http.HtmlResponse "scrapy.http.HtmlResponse") 类是的子类 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 它通过查看HTML添加了编码自动发现支持 [meta http-equiv](https://www.w3schools.com/TAGS/att_meta_http_equiv.asp) 属性。见 [`TextResponse.encoding`](#scrapy.http.TextResponse.encoding "scrapy.http.TextResponse.encoding") . ### XmlResponse对象 ```py class scrapy.http.XmlResponse(url[, ...]) ``` 这个 [`XmlResponse`](#scrapy.http.XmlResponse "scrapy.http.XmlResponse") 类是的子类 [`TextResponse`](#scrapy.http.TextResponse "scrapy.http.TextResponse") 它通过查看XML声明行添加了编码自动发现支持。见 [`TextResponse.encoding`](#scrapy.http.TextResponse.encoding "scrapy.http.TextResponse.encoding") .