请求与响应
Scrapy 使用 Request 和 Response 对象来爬取网站。
通常,Request 对象在爬虫中生成,并在系统中传递,直到到达下载器,下载器执行请求并返回一个 Response 对象,该对象再返回给发出请求的爬虫。
Request 和 Response 类都有子类,它们添加了基类中不需要的功能。这些在 Request 子类 和 Response 子类 中有描述。
请求对象
- class scrapy.Request(*args: Any, **kwargs: Any)[source]
表示一个HTTP请求,它通常在 Spider 中生成并由 Downloader 执行,从而生成一个
Response。- 参数:
url (str) –
此请求的URL
如果URL无效,则会引发
ValueError异常。callback (Callable[Concatenate[Response, ...], Any] | None) – 设置
callback,默认为None。method (str) – 此请求的HTTP方法。默认为
'GET'。meta (dict) –
Request.meta属性的初始值。如果给定,此参数中传递的字典将进行浅复制。body (bytes or str) – 请求体。如果传入字符串,则使用传入的
encoding(默认为utf-8) 将其编码为字节。如果未给出body,则存储一个空字节对象。无论此参数的类型如何,最终存储的值都将是字节对象(绝不是字符串或None)。headers (dict) –
此请求的请求头。字典值可以是字符串(用于单值请求头)或列表(用于多值请求头)。如果传入
None作为值,则HTTP请求头将根本不发送。注意
通过
Cookie请求头设置的 Cookie 不会被 CookiesMiddleware 考虑。如果需要为请求设置 Cookie,请使用cookies参数。这是一个已知的当前限制,正在解决中。请求的Cookie。可以通过两种形式发送。
使用字典
request_with_cookies = Request( url="http://www.example.com", cookies={"currency": "USD", "country": "UY"}, )
使用字典列表
request_with_cookies = Request( url="https://www.example.com", cookies=[ { "name": "currency", "value": "USD", "domain": "example.com", "path": "/currency", "secure": True, }, ], )
后者允许自定义 Cookie 的
domain和path属性。这仅在 Cookie 保存供后续请求使用时才有用。当某些网站返回 Cookie (在响应中) 时,它们会存储在该域的 Cookie 中,并在未来的请求中再次发送。这是任何普通网络浏览器的典型行为。
请注意,在
request.meta中将dont_merge_cookies键设置为True会导致自定义 Cookie 被忽略。更多信息请参阅 CookiesMiddleware。
注意
通过
Cookie请求头设置的 Cookie 不会被 CookiesMiddleware 考虑。如果需要为请求设置 Cookie,请使用scrapy.Request.cookies参数。这是一个已知的当前限制,正在解决中。encoding (str) –
此请求的编码(默认为
'utf-8')。此编码将用于对URL进行百分比编码,并将请求体转换为字节(如果以字符串形式给出)。要禁用请求的URL百分比编码,请使用
verbatim_url请求元数据键。dont_filter (bool) – 设置
dont_filter,默认为False。errback (Callable[[Failure], Any] | None) – 设置
errback,默认为None。flags (list) – 发送到请求的标志,可用于日志记录或类似目的。
cb_kwargs (dict) – 一个包含任意数据的字典,这些数据将作为关键字参数传递给 Request 的回调函数。
- url
一个包含此请求URL的字符串。
请记住,此属性包含已转义的URL,因此它可能与
__init__()方法中传入的URL不同。如果
verbatim_url设置为True,则URL保持与传入__init__()时相同。此属性是只读的。要更改请求的URL,请使用
replace()。
- method
一个表示请求中HTTP方法的字符串。这保证是大写的。示例:
"GET"、"POST"、"PUT"等
- headers
一个类似字典的 (
scrapy.http.headers.Headers) 对象,其中包含请求头。
- callback: CallbackT | None
用于解析接收到此请求的
Response的Callable。可调用对象必须将其第一个参数作为响应,并支持通过
cb_kwargs设置的任何附加关键字参数。除了任意可调用对象外,还支持以下值:
None(默认值),表示必须使用爬虫的parse()方法。
如果在请求或响应处理期间引发未处理的异常,即由 爬虫中间件、下载器中间件 或下载处理程序 (
DOWNLOAD_HANDLERS) 引发,则会调用errback。提示
HttpErrorMiddleware默认会为非2xx响应引发异常,并将其发送到errback。另请参阅
- errback: Callable[[Failure], Any] | None
用于处理在请求或响应处理期间引发的异常的
Callable。可调用对象必须将其第一个参数作为
Failure。另请参阅
- cb_kwargs
一个字典,包含此请求的任意元数据。其内容将作为关键字参数传递给 Request 的回调函数。对于新的请求,它是空的,这意味着默认情况下回调函数只接收一个
Response对象作为参数。当使用
copy()或replace()方法克隆请求时,此字典会进行 浅复制,并且在您的爬虫中,也可以通过response.cb_kwargs属性访问它。如果处理请求失败,可以在请求的错误回调函数中通过
failure.request.cb_kwargs访问此字典。更多信息,请参阅 在错误回调函数中访问附加数据。
- meta = {}
请求的任意元数据的字典。
您可以根据需要扩展请求元数据。
请求元数据也可以通过响应的
meta属性访问。要将数据从一个爬虫回调函数传递到另一个,请考虑使用
cb_kwargs。然而,在某些情况下,请求元数据可能是正确的选择,例如在所有后续请求中维护一些调试数据(例如源URL)。请求元数据的一个常见用途是为 Scrapy 组件(扩展、中间件等)定义请求特定参数。例如,如果您将
dont_retry设置为True,即使请求失败,RetryMiddleware也绝不会重试该请求。请参阅 Request.meta 特殊键。您还可以在自定义 Scrapy 组件中使用请求元数据,例如,为了保留与您的组件相关的请求状态信息。例如,
RetryMiddleware使用retry_times元数据键来跟踪请求到目前为止已重试的次数。在爬虫回调函数中将先前请求的所有元数据复制到新的后续请求是一种不好的做法,因为请求元数据可能包含由 Scrapy 组件设置的元数据,这些元数据不应复制到其他请求中。例如,将
retry_times元数据键复制到后续请求中可能会降低这些后续请求允许的重试次数。只有当新请求旨在替换旧请求时,才应将所有请求元数据从一个请求复制到另一个请求,这通常发生在从 下载器中间件 方法返回请求时。
- dont_filter: bool
此请求是否可能被支持过滤请求的 组件 过滤掉(
False,默认),或者这些组件不应过滤掉此请求(True)。以下内置组件会检查此属性:
调度器 使用它来跳过重复请求过滤(请参阅
DUPEFILTER_CLASS)。当设置为True时,请求不会与重复过滤器进行检查,从而允许原本被视为重复的请求多次调度。OffsiteMiddleware使用它来允许请求访问不在allowed_domains中的域。要仅跳过站外过滤器而不影响其他组件,请考虑使用allow_offsite请求元数据键。
第三方组件也可能使用此属性来决定是否过滤请求。
当通过
start_urls定义爬虫的起始URL时,此属性默认启用。请参阅start()。
- attributes: tuple[str, ...] = ('url', 'headers', 'body', 'cookies', 'meta', 'encoding', 'flags', 'cb_kwargs', 'callback', 'dont_filter', 'errback', 'method', 'priority')
一个包含类所有公共属性名称的
str对象元组,这些属性也是__init__()方法的关键字参数。当前由
Request.replace()、Request.to_dict()和request_from_dict()使用。
- copy()[source]
返回一个新的 Request,它是此 Request 的副本。另请参阅:向回调函数传递附加数据。
- replace([url, method, headers, body, cookies, meta, flags, encoding, priority, dont_filter, callback, errback, cb_kwargs])[source]
返回一个具有相同成员的 Request 对象,但由指定的任何关键字参数赋予新值的成员除外。
cb_kwargs和meta属性默认进行浅复制(除非作为参数给出新值)。另请参阅 向回调函数传递附加数据。
- classmethod from_curl(curl_command: str, ignore_unknown_options: bool = True, **kwargs: Any) Self[source]
从包含 cURL 命令的字符串创建一个 Request 对象。它填充HTTP方法、URL、请求头、Cookie和请求体。它接受与
Request类相同的参数,优先并覆盖 cURL 命令中包含的相同参数的值。未识别的选项默认被忽略。要在找到未知选项时引发错误,请通过传入
ignore_unknown_options=False调用此方法。注意
使用
from_curl()从Request子类(如JsonRequest或XmlRpcRequest),以及启用 下载器中间件 和 爬虫中间件(如DefaultHeadersMiddleware、UserAgentMiddleware或HttpCompressionMiddleware),可能会修改Request对象。要将 cURL 命令转换为 Scrapy 请求,您可以使用 curl2scrapy。
创建提交HTML表单的请求
使用 form2request 从HTML <form> 元素构建请求数据并将其转换为 Request。
使用 pip 安装它
pip install form2request
使用CSS或XPath选择所需的表单,然后构建并转换请求数据
from form2request import form2request
def parse(self, response):
form = response.css("form#search")
request_data = form2request(form, data={"q": "scrapy"})
yield request_data.to_scrapy(callback=self.parse_results)
使用 data 覆盖字段值。要从结果请求中删除某个字段,请将其值设置为 None。
默认情况下,form2request 模拟点击第一个提交按钮。要在不点击任何按钮的情况下提交,请传入 click=False。要点击特定的提交按钮,请传入其元素
def parse(self, response):
form = response.css("form#checkout")
submit = form.css('button[name="pay"]')
request_data = form2request(form, click=submit)
使用 form2request 模拟用户登录
网站通常会通过 <input type="hidden"> 元素提供预填充的表单字段,例如会话相关数据或认证令牌(用于登录页面)。从表单构建请求,并仅覆盖凭据
import scrapy
from form2request import form2request
class LoginSpider(scrapy.Spider):
name = "example.com"
start_urls = ["http://www.example.com/users/login.php"]
def parse(self, response):
form = response.css("form")
request_data = form2request(
form,
data={"username": "john", "password": "secret"},
)
yield request_data.to_scrapy(callback=self.after_login)
def after_login(self, response): ...
向回调函数传递附加数据
请求的回调函数是一个在下载该请求的响应时将被调用的函数。回调函数将以下载的 Response 对象作为其第一个参数被调用。
示例:
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.cb_kwargs 属性来实现这一点:
def parse(self, response):
request = scrapy.Request(
"http://www.example.com/index.html",
callback=self.parse_page2,
cb_kwargs=dict(main_url=response.url),
)
request.cb_kwargs["foo"] = "bar" # add more arguments for the callback
yield request
def parse_page2(self, response, main_url, foo):
yield dict(
main_url=main_url,
other_url=response.url,
foo=foo,
)
注意
Request.cb_kwargs 在版本 1.7 中引入。在此之前,建议使用 Request.meta 在回调函数之间传递信息。在 1.7 之后,Request.cb_kwargs 成为处理用户信息,而 Request.meta 用于与中间件和扩展等组件进行通信的首选方式。
使用错误回调函数捕获请求处理中的异常
请求的错误回调函数是一个在处理请求时引发异常时将被调用的函数。
它将一个 Failure 作为第一个参数接收,可用于跟踪连接建立超时、DNS错误等。
这是一个爬虫示例,它记录所有错误并在需要时捕获某些特定错误:
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
"https://example.invalid/", # DNS error expected
]
async def start(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)
在错误回调函数中访问附加数据
如果处理请求失败,您可能希望访问回调函数的参数,以便在错误回调函数中根据这些参数进行进一步处理。以下示例展示了如何通过使用 Failure.request.cb_kwargs 来实现这一点:
def parse(self, response):
request = scrapy.Request(
"http://www.example.com/index.html",
callback=self.parse_page2,
errback=self.errback_page2,
cb_kwargs=dict(main_url=response.url),
)
yield request
def parse_page2(self, response, main_url):
pass
def errback_page2(self, failure):
yield dict(
main_url=failure.request.cb_kwargs["main_url"],
)
请求指纹
爬取的一些方面,例如过滤重复请求(请参阅 DUPEFILTER_CLASS)或缓存响应(请参阅 HTTPCACHE_POLICY),您需要能够从 Request 对象生成一个短而唯一的标识符:请求指纹。
您通常不需要担心请求指纹,默认的请求指纹生成器适用于大多数项目。
然而,没有通用的方法可以从请求生成唯一标识符,因为不同的情况需要以不同的方式比较请求。例如,有时您可能需要不区分大小写地比较URL,包含URL片段,排除某些URL查询参数,包含部分或所有请求头等。
要更改如何为您的请求构建请求指纹,请使用 REQUEST_FINGERPRINTER_CLASS 设置。
REQUEST_FINGERPRINTER_CLASS
默认值:scrapy.utils.request.RequestFingerprinter
一个 请求指纹生成器类 或其导入路径。
- class scrapy.utils.request.RequestFingerprinter(crawler: Crawler | None = None)[source]
默认指纹生成器。
它考虑了
request.url的规范版本 (w3lib.url.canonicalize_url()) 以及request.method和request.body的值,除非verbatim_url对该请求为真。然后它生成一个 SHA1 哈希值。
编写自己的请求指纹生成器
请求指纹生成器是一个 组件,它必须实现以下方法:
- fingerprint(self, request: scrapy.Request)
返回一个唯一标识 *请求* 的
bytes对象。另请参阅 请求指纹限制。
默认请求指纹生成器 scrapy.utils.request.RequestFingerprinter 的 fingerprint() 方法使用默认参数的 scrapy.utils.request.fingerprint()。对于一些常见的用例,您也可以在您的 fingerprint() 方法实现中使用 scrapy.utils.request.fingerprint():
- scrapy.utils.request.fingerprint(request: Request, *, include_headers: Iterable[bytes | str] | None = None, keep_fragments: bool = False) bytes[source]
返回请求指纹。
请求指纹是一个哈希值,它唯一标识请求指向的资源。例如,考虑以下两个URL:
http://www.example.com/query?id=111&cat=222,http://www.example.com/query?cat=222&id=111。尽管这是两个不同的URL,但它们都指向相同的资源并且是等效的(即它们应该返回相同的响应)。
另一个例子是用于存储会话ID的Cookie。假设以下页面仅对经过身份验证的用户可访问:
http://www.example.com/members/offers.html。许多网站使用Cookie来存储会话ID,这会为HTTP请求添加一个随机组件,因此在计算指纹时应忽略它。
出于这个原因,在计算指纹时默认会忽略请求头。如果要包含特定的请求头,请使用
include_headers参数,它是一个要包含的请求头列表。此外,服务器在处理请求时通常会忽略URL中的片段,因此在计算指纹时默认也会忽略它们。如果要包含它们,请将
keep_fragments参数设置为 True(例如在使用无头浏览器处理请求时)。
默认情况下,请求指纹化会规范化请求URL。如果 verbatim_url 设置为 True,则指纹化不会规范化URL,并且 keep_fragments 参数将被忽略(它实际上为 True)。
例如,要考虑名为 X-ID 的请求头的值:
# my_project/settings.py
REQUEST_FINGERPRINTER_CLASS = "my_project.utils.RequestFingerprinter"
# my_project/utils.py
from scrapy.utils.request import fingerprint
class RequestFingerprinter:
def fingerprint(self, request):
return fingerprint(request, include_headers=["X-ID"])
您也可以从头开始编写自己的指纹逻辑。
然而,如果您不使用 scrapy.utils.request.fingerprint(),请确保使用 WeakKeyDictionary 来缓存请求指纹:
缓存通过确保每个请求只计算一次指纹,而不是每个需要请求指纹的 Scrapy 组件都计算一次,从而节省了CPU。
使用
WeakKeyDictionary可以节省内存,因为它确保请求对象不会因为您的缓存字典中有它们的引用而永远停留在内存中。
例如,仅考虑请求的URL,而不进行任何先前的URL规范化或考虑请求方法或请求体:
from hashlib import sha1
from weakref import WeakKeyDictionary
from scrapy.utils.python import to_bytes
class RequestFingerprinter:
cache = WeakKeyDictionary()
def fingerprint(self, request):
if request not in self.cache:
fp = sha1()
fp.update(to_bytes(request.url))
self.cache[request] = fp.digest()
return self.cache[request]
如果您需要能够从爬虫回调函数中覆盖任意请求的请求指纹,您可以实现一个请求指纹生成器,它在可用时从 request.meta 中读取指纹,然后回退到 scrapy.utils.request.fingerprint()。例如:
from scrapy.utils.request import fingerprint
class RequestFingerprinter:
def fingerprint(self, request):
if "fingerprint" in request.meta:
return request.meta["fingerprint"]
return fingerprint(request)
如果您需要重现与 Scrapy 2.6 相同的指纹算法,请使用以下请求指纹生成器:
from hashlib import sha1
from weakref import WeakKeyDictionary
from scrapy.utils.python import to_bytes
from w3lib.url import canonicalize_url
class RequestFingerprinter:
cache = WeakKeyDictionary()
def fingerprint(self, request):
if request not in self.cache:
fp = sha1()
fp.update(to_bytes(request.method))
fp.update(to_bytes(canonicalize_url(request.url)))
fp.update(request.body or b"")
self.cache[request] = fp.digest()
return self.cache[request]
请求指纹限制
使用请求指纹的 Scrapy 组件可能会对您的 请求指纹生成器 生成的指纹格式施加额外限制。
以下内置 Scrapy 组件具有此类限制:
scrapy.extensions.httpcache.FilesystemCacheStorage(HTTPCACHE_STORAGE的默认值)请求指纹必须至少为 1 字节长。
HTTPCACHE_DIR文件系统的路径和文件名长度限制也适用。在HTTPCACHE_DIR内部,会创建以下目录结构:-
请求指纹的第一个字节(十六进制)
指纹(十六进制)
文件名最长16个字符
例如,如果请求指纹为20字节(默认),
HTTPCACHE_DIR为'/home/user/project/.scrapy/httpcache',并且您的爬虫名称为'my_spider',则您的文件系统必须支持类似以下的路径:/home/user/project/.scrapy/httpcache/my_spider/01/0123456789abcdef0123456789abcdef01234567/response_headers
-
scrapy.extensions.httpcache.DbmCacheStorage底层 DBM 实现必须支持长度为请求指纹字节数两倍加5的键。例如,如果请求指纹为20字节(默认),则必须支持45个字符长的键。
Request.meta 特殊键
Request.meta 属性可以包含任何任意数据,但 Scrapy 及其内置扩展会识别一些特殊键。
这些是:
ftp_password(更多信息请参阅FTP_PASSWORD)ftp_user(更多信息请参阅FTP_USER)
bindaddress
下载处理程序连接的默认本地出站地址。
此元数据值可以是:
字符串形式的主机地址(例如
"127.0.0.2"),在这种情况下,本地端口会自动选择,或者一个
(host, port)元组(例如("127.0.0.2", 50000)),用于绑定到特定的本地接口和特定的本地端口。
例如
Request(
"https://example.org",
meta={"bindaddress": "127.0.0.2"},
)
Request(
"https://example.org",
meta={"bindaddress": ("127.0.0.2", 50000)},
)
如果未设置,内置HTTP下载处理程序将使用 DOWNLOAD_BIND_ADDRESS 的值作为默认绑定地址。设置 bindaddress 请求元数据键以覆盖特定请求的绑定地址。
HttpxDownloadHandler 不支持此元数据键,但支持 DOWNLOAD_BIND_ADDRESS。
download_timeout
下载器在超时前将等待的时间量(秒)。另请参阅:DOWNLOAD_TIMEOUT。
download_latency
从请求开始(即HTTP消息通过网络发送)到获取响应所花费的时间量。此元数据键仅在响应下载完成后可用。虽然大多数其他元数据键用于控制 Scrapy 行为,但此键应为只读。
download_fail_on_dataloss
是否在响应损坏时失败。请参阅:DOWNLOAD_FAIL_ON_DATALOSS。
give_up_log_level
在 2.17.0 版本中添加。
当请求超出其重试次数时,用于记录消息的 日志级别。详情请参阅 RETRY_GIVE_UP_LOG_LEVEL。
http_auth_domain
在 2.17.0 版本中添加。
覆盖此请求的 HTTPAUTH_DOMAIN。
http_pass
在 2.17.0 版本中添加。
覆盖此请求的 HTTPAUTH_PASS。
http_user
在 2.17.0 版本中添加。
覆盖此请求的 HTTPAUTH_USER。
max_retry_times
此元数据键用于设置每个请求的重试次数。设置后,max_retry_times 元数据键优先于 RETRY_TIMES 设置。
verbatim_url
在 2.17.0 版本中添加。
将此键设置为 True 以保持请求URL与传递给 Request 时相同,而不进行URL百分比编码。
启用此键时,fingerprint() 不会规范化请求URL,因此URL仅在通常会被规范化的字符上不同的请求会获得不同的指纹。
在此模式下,keep_fragments 参数被忽略,并且实际上为 True。
停止下载响应
从 bytes_received 或 headers_received 信号的处理程序中引发 StopDownload 异常将停止给定响应的下载。请参见以下示例
import scrapy
class StopSpider(scrapy.Spider):
name = "stop"
start_urls = ["https://docs.scrapy.net.cn/en/latest/"]
@classmethod
def from_crawler(cls, crawler):
spider = super().from_crawler(crawler)
crawler.signals.connect(
spider.on_bytes_received, signal=scrapy.signals.bytes_received
)
return spider
def parse(self, response):
# 'last_chars' show that the full response was not downloaded
yield {"len": len(response.text), "last_chars": response.text[-40:]}
def on_bytes_received(self, data, request, spider):
raise scrapy.exceptions.StopDownload(fail=False)
它会产生以下输出
2020-05-19 17:26:12 [scrapy.core.engine] INFO: Spider opened
2020-05-19 17:26:12 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2020-05-19 17:26:13 [scrapy.core.downloader.handlers.http11] DEBUG: Download stopped for <GET https://docs.scrapy.org/en/latest/> from signal handler StopSpider.on_bytes_received
2020-05-19 17:26:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://docs.scrapy.org/en/latest/> (referer: None) ['download_stopped']
2020-05-19 17:26:13 [scrapy.core.scraper] DEBUG: Scraped from <200 https://docs.scrapy.org/en/latest/>
{'len': 279, 'last_chars': 'dth, initial-scale=1.0">\n \n <title>Scr'}
2020-05-19 17:26:13 [scrapy.core.engine] INFO: Closing spider (finished)
默认情况下,生成的响应由其相应的 errback 处理。要改为调用其 callback,如本例所示,请将 fail=False 传递给 StopDownload 异常。
Request 子类
以下是内置的 Request 子类列表。您也可以通过继承它来实现自己的自定义功能。
FormRequest
- class scrapy.FormRequest(*args: Any, **kwargs: Any)[source]
一个
Request子类,带有一个formdata参数,该参数将给定的数据进行 URL 编码并分配给请求,这使得通过 HTTP POST 或 GET 发送任意表单数据变得方便,而无需解析 HTML<form>元素。注意
要从响应中找到的 HTML
<form>元素构建请求,请改用 form2request。请参见 Creating requests that submit HTML forms。其余参数与
Request类相同,在此不赘述。- 参数:
formdata (dict or collections.abc.Iterable) – 一个字典(或 (key, value) 元组的可迭代对象),包含将进行 URL 编码的 HTML 表单数据。如果未给出
method且提供了formdata,则方法设置为"POST"并且数据分配给请求正文;如果方法是"GET",则数据将添加到 URL 查询字符串中。
要通过 HTTP POST 发送数据,模拟 HTML 表单提交,请从您的爬虫中返回一个
FormRequest对象return [ FormRequest( url="http://www.example.com/post/action", formdata={"name": "John Doe", "age": "27"}, callback=self.after_post, ) ]
要将数据发送到 URL 查询字符串中,请使用
GET方法return [ FormRequest( url="http://www.example.com/search", method="GET", formdata={"q": "keyword", "page": "1"}, callback=self.parse_results, ) ]
JsonRequest
JsonRequest 类通过处理 JSON 请求的功能扩展了基本的 Request 类。
- class scrapy.http.JsonRequest(url[, ... data, dumps_kwargs])[source]
JsonRequest类为__init__()方法添加了两个新的关键字参数。其余参数与Request类相同,在此不赘述。使用
JsonRequest将把Content-Type标头设置为application/json,并将Accept标头设置为application/json, text/javascript, */*; q=0.01- 参数:
- attributes: tuple[str, ...] = ('url', 'headers', 'body', 'cookies', 'meta', 'encoding', 'flags', 'cb_kwargs', 'callback', 'dont_filter', 'errback', 'method', 'priority', 'dumps_kwargs')
一个包含类所有公共属性名称的
str对象元组,这些属性也是__init__()方法的关键字参数。当前由
Request.replace()、Request.to_dict()和request_from_dict()使用。
JsonRequest 使用示例
发送带有 JSON 载荷的 JSON POST 请求
data = {
"name1": "value1",
"name2": "value2",
}
yield JsonRequest(url="http://www.example.com/post/action", data=data)
Response 对象
- class scrapy.http.Response(*args: Any, **kwargs: Any)[source]
一个表示 HTTP 响应的对象,通常由下载器 (Downloader) 下载并提供给爬虫 (Spiders) 进行处理。
- 参数:
url (str) – 此响应的 URL
status (int) – 响应的 HTTP 状态。默认为
200。headers (dict) – 此响应的标头。字典值可以是字符串(用于单值标头)或列表(用于多值标头)。
body (bytes) – 响应正文。要将解码后的文本作为字符串访问,请从支持编码的 Response 子类(例如
TextResponse)使用response.text。flags (list) – 一个列表,包含
Response.flags属性的初始值。如果给定,该列表将进行浅复制。request (scrapy.Request) –
Response.request属性的初始值。这表示生成此响应的Request。certificate (Any) – 表示服务器 SSL 证书的对象。
ip_address (
ipaddress.IPv4Addressoripaddress.IPv6Address) – 响应来源服务器的 IP 地址。protocol (
str) – 用于下载响应的协议。例如:“HTTP/1.0”、“HTTP/1.1”、“h2”
- status
表示响应 HTTP 状态的整数。示例:
200、404。
- headers
一个类似字典的 (
scrapy.http.headers.Headers) 对象,包含响应头。可以使用get()访问值以返回指定名称的最后一个头值,或使用getlist()返回指定名称的所有头值。例如,此调用将为您提供头中所有的 cookieresponse.headers.getlist('Set-Cookie')
- body
响应正文,以字节形式。
如果您想要将正文作为字符串,请使用
TextResponse.text(仅在TextResponse及其子类中可用)。此属性是只读的。要更改 Response 的正文,请使用
replace()。
- request
生成此响应的
Request对象。此属性在 Scrapy 引擎中,在响应和请求通过所有 Downloader Middlewares 后分配。具体而言,这意味着HTTP 重定向将从重定向前的请求创建一个新请求。它拥有大部分相同的元数据和原始请求属性,并分配给重定向的响应,而不是原始请求的传播。
Response.request.url并不总是等于Response.url此属性仅在爬虫代码和 Spider Middlewares 中可用,但在 Downloader Middlewares 中不可用(尽管您可以通过其他方式在那里访问 Request),以及
response_downloaded信号的处理程序中不可用。
- meta
指向
Response.request对象的meta属性的快捷方式(即self.request.meta)。与
Response.request属性不同,Response.meta属性在重定向和重试过程中会传播,因此您将获得从您的爬虫发送的原始Request.meta。另请参阅
Request.meta属性
- cb_kwargs
指向
Response.request对象的cb_kwargs属性的快捷方式(即self.request.cb_kwargs)。与
Response.request属性不同,Response.cb_kwargs属性在重定向和重试过程中会传播,因此您将获得从您的爬虫发送的原始Request.cb_kwargs。另请参阅
- flags
包含此响应标志的列表。标志是用于标记响应的标签。例如:
'cached'、'redirected’等。它们显示在 Response 的字符串表示 (__str__()方法) 中,引擎使用该方法进行日志记录。
- certificate
一个表示服务器 SSL 证书的对象。其类型和内容取决于生成响应的下载处理程序。
仅针对
https响应填充,否则为None。
- ip_address
响应来源服务器的 IP 地址。
此属性目前仅由 HTTP 1.1 下载处理程序(即
http(s)响应)填充。对于其他处理程序,ip_address始终为None。
- protocol
用于下载响应的协议。例如:“HTTP/1.0”、“HTTP/1.1”
此属性目前仅由 HTTP 下载处理程序(即
http(s)响应)填充。对于其他处理程序,protocol始终为None。
- attributes: tuple[str, ...] = ('url', 'headers', 'body', 'flags', 'status', 'request', 'certificate', 'ip_address', 'protocol')
一个包含类所有公共属性名称的
str对象元组,这些属性也是__init__()方法的关键字参数。目前由
Response.replace()使用。
- replace([url, status, headers, body, request, flags, cls])[source]
返回一个具有相同成员的 Response 对象,除了那些通过指定关键字参数给定新值的成员。属性
Response.meta默认情况下会被复制。
- urljoin(url)[source]
通过将 Response 的
url与可能的相对 URL 组合来构建一个绝对 URL。这是
urljoin()的一个封装,它仅仅是进行此调用的别名urllib.parse.urljoin(response.url, url)
- follow(url: str | Link, callback: CallbackT | None = None, method: str = 'GET', headers: Mapping[AnyStr, Any] | Iterable[tuple[AnyStr, Any]] | None = None, body: bytes | str | None = None, cookies: CookiesT | None = None, meta: dict[str, Any] | None = None, encoding: str | None = None, priority: int = 0, dont_filter: bool = False, errback: Callable[[Failure], Any] | None = None, cb_kwargs: dict[str, Any] | None = None, flags: list[str] | None = None) Request[source]
返回一个
Request实例以跟踪链接url。它接受与Request.__init__()方法相同的参数,但url可以是相对 URL 或Link对象,而不仅仅是绝对 URL。TextResponse提供了一个follow()方法,该方法除了支持绝对/相对 URL 和 Link 对象外,还支持选择器。
- follow_all(urls: Iterable[str | Link], callback: CallbackT | None = None, method: str = 'GET', headers: Mapping[AnyStr, Any] | Iterable[tuple[AnyStr, Any]] | None = None, body: bytes | str | None = None, cookies: CookiesT | None = None, meta: dict[str, Any] | None = None, encoding: str | None = None, priority: int = 0, dont_filter: bool = False, errback: Callable[[Failure], Any] | None = None, cb_kwargs: dict[str, Any] | None = None, flags: list[str] | None = None) Iterable[Request]
返回一个
Request实例的可迭代对象,以跟踪urls中的所有链接。它接受与Request.__init__()方法相同的参数,但urls的元素可以是相对 URL 或Link对象,而不仅仅是绝对 URL。TextResponse提供了一个follow_all()方法,该方法除了支持绝对/相对 URL 和 Link 对象外,还支持选择器。
Response 子类
以下是可用的内置 Response 子类列表。您也可以通过继承 Response 类来实现自己的功能。
TextResponse 对象
- class scrapy.http.TextResponse(url[, encoding[, ...]])[source]
TextResponse对象在基本Response类中添加了编码功能,该类仅用于二进制数据,例如图像、声音或任何媒体文件。TextResponse对象除了支持基本Response对象外,还支持一个新的__init__()方法参数。其余功能与Response类相同,在此不赘述。- 参数:
encoding (str) – 一个字符串,包含此响应要使用的编码。如果您使用字符串作为正文创建
TextResponse对象,它将使用此编码转换为字节。如果 *encoding* 为None(默认),则编码将在响应头和正文中查找。
TextResponse对象除了支持标准Response对象外,还支持以下属性- text
响应正文,作为字符串。
与
response.body.decode(response.encoding)相同,但在第一次调用后结果会被缓存,因此您可以多次访问response.text而无需额外开销。注意
str(response.body)不是将响应正文转换为字符串的正确方法>>> str(b"body") "b'body'"
- encoding
一个字符串,包含此响应的编码。编码通过以下机制按顺序解析
在
__init__()方法encoding参数中传递的编码Content-Type HTTP 标头中声明的编码。如果此编码无效(即未知),则会忽略它并尝试下一个解析机制。
响应正文中声明的编码。TextResponse 类不提供任何特殊功能。但是,
HtmlResponse和XmlResponse类提供。通过查看响应正文推断出的编码。这是更脆弱的方法,但也是最后尝试的方法。
- attributes: tuple[str, ...] = ('url', 'headers', 'body', 'flags', 'status', 'request', 'certificate', 'ip_address', 'protocol', 'encoding')
一个包含类所有公共属性名称的
str对象元组,这些属性也是__init__()方法的关键字参数。目前由
Response.replace()使用。
TextResponse对象除了支持标准Response对象外,还支持以下方法- jmespath(query)[source]
指向
TextResponse.selector.jmespath(query)的快捷方式response.jmespath('object.[*]')
- follow(url: str | Link | parsel.Selector, callback: CallbackT | None = None, method: str = 'GET', headers: Mapping[AnyStr, Any] | Iterable[tuple[AnyStr, Any]] | None = None, body: bytes | str | None = None, cookies: CookiesT | None = None, meta: dict[str, Any] | None = None, encoding: str | None = None, priority: int = 0, dont_filter: bool = False, errback: Callable[[Failure], Any] | None = None, cb_kwargs: dict[str, Any] | None = None, flags: list[str] | None = None) Request
返回一个
Request实例以跟踪链接url。它接受与Request.__init__()方法相同的参数,但url不仅可以是绝对 URL,还可以是以下任何一种相对 URL
一个
Selector对象,用于<link>或<a>元素,例如response.css('a.my_link')[0]一个属性
Selector(不是 SelectorList),例如response.css('a::attr(href)')[0]或response.xpath('//img/@src')[0]
有关用法示例,请参见 创建 Request 的快捷方式。
- follow_all(urls: Iterable[str | Link] | parsel.SelectorList[Any] | None = None, callback: CallbackT | None = None, method: str = 'GET', headers: Mapping[AnyStr, Any] | Iterable[tuple[AnyStr, Any]] | None = None, body: bytes | str | None = None, cookies: CookiesT | None = None, meta: dict[str, Any] | None = None, encoding: str | None = None, priority: int = 0, dont_filter: bool = False, errback: Callable[[Failure], Any] | None = None, cb_kwargs: dict[str, Any] | None = None, flags: list[str] | None = None, css: str | None = None, xpath: str | None = None) Iterable[Request]
一个生成器,生成
Request实例以跟踪urls中的所有链接。它接受与Request的__init__()方法相同的参数,只是每个urls元素无需是绝对 URL,它可以是以下任何一种相对 URL
一个
Selector对象,用于<link>或<a>元素,例如response.css('a.my_link')[0]一个属性
Selector(不是 SelectorList),例如response.css('a::attr(href)')[0]或response.xpath('//img/@src')[0]
此外,接受
css和xpath参数,以在follow_all()方法中执行链接提取(urls、css和xpath中只接受一个)。请注意,当将
SelectorList作为urls参数的参数传递,或使用css或xpath参数时,此方法不会为无法获取链接的选择器生成请求(例如,没有href属性的锚点标签)
- urljoin(url)[源码]
通过将 Response 的基础 URL 与一个可能的相对 URL 组合,构建一个绝对 URL。基础 URL 将从
<base>标签中提取,如果不存在该标签,则直接使用Response.url。
HtmlResponse 对象
- class scrapy.http.HtmlResponse(url[, ...])[源码]
HtmlResponse类是TextResponse的子类,它通过查看 HTML meta http-equiv 属性来添加编码自动发现支持。请参阅TextResponse.encoding。
XmlResponse 对象
- class scrapy.http.XmlResponse(url[, ...])[源码]
XmlResponse类是TextResponse的子类,它通过查看 XML 声明行来添加编码自动发现支持。请参阅TextResponse.encoding。
JsonResponse 对象
- class scrapy.http.JsonResponse(url[, ...])[源码]
JsonResponse类是TextResponse的子类,当响应在其 Content-Type 头中包含 JSON MIME 类型时使用。