Python爬虫笔记(十二)——Scrapy官方文档阅读笔记——request与response

Request和Response对象用于爬取网站

Request对象

Request对象代表HTTP请求,通常由Spider生成,由Downloader执行发送,然后由Downloader生成返回Response对象

__init__:构造函数,常用参数:

  • url:请求的url
  • callback:用于处理response的函数,如果没有指定,scrapy默认使用parse函数
  • method:HTTP请求的方法,默认是GET
  • meta(dict类型):Request.meta属性的值,如果给定了meta,它的值将会浅复制到Request.meta中,用于规定元数据
  • body(str类型):请求的body部分
  • headers(dict类型):请求的头部
  • cookie(dict或是list类型):request的cookie,可以有两种组织形式:
  •       使用dict:                  
request_with_cookies = Request(url="http://www.example.com",
                               cookies={'currency': 'USD', 'country': 'UY'})
  •        使用list:
request_with_cookies = Request(url="http://www.example.com",
                               cookies=[{'name': 'currency',
                                        'value': 'USD',
                                        'domain': 'example.com',
                                        'path': '/currency'}])

当响应返回时,相应的cookie会合并到旧的cookie中,Scrapy通过CookiesMiddleware跟踪cookie,添加到现有的cookie中,在发送请求的时候附着上cookie,即Scrapy可以自动管理cookie

  • encoding:请求所使用的编码
  • priority(int):用来表示请求的优先级,值越大,优先级越大,越先处理,默认值为0
  • dont_filter(boolean):默认值为false,表示请求不应该被请求队列过滤,当我们对请求进行验证以排除重复的请求时,通过设置这个值就可以忽略过滤,要谨慎使用这个值,可能会造成循环
  • errback(callback):当异常发生时回调的函数
  • flags:可用于请求登陆或是类似的用途

copy()函数

  • 返回当前request的一个拷贝

replace([url,method,headers,body,cookies,meta,encoding,dont_filter,callback,errback])

  • 替换当前request某些区域的值并返回

属性:

url:Request对象的url,这个属性的url是经过url编码的,是只读的,如果想更改,请使用replace函数

method:HTTP请求的方法(GET、POST等)

headers:请求头部

body:请求body部分,只读,需要更改,请使用replace()

meta:请求的元数据,当使用copy()和replace()时,都是浅拷贝,下面会讲请求的特殊元数据有哪些

传递额外的参数给callback函数

有时候我们想把页面一的某些内容传递给处理页面二的callback函数,这个时候可以使用Request.meta:

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来捕获异常

当发生异常时,将会使用errbacks指定的函数

它会接收到一个Twisted 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
        "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)

Request.meta的特殊关键字

由于时间关系,这里就不总结了,在需要的时候在查看:

bindaddress:request请求发往的IP地址

download_timeout:dowmloader等待响应的最长时间,超过这个时间,将被视为超时,单位为秒

download_latency:只读,发送请求到接收到响应所花费的时间,这个属性只有在接收到响应以后才有效

max_retry_times:最大重试次数,这个值比RETRY_TIMES具有更高的优先级

Request的子类

Scrapy提供了一些request类的子类

1、FormRequest类:

用于处理HTML表单

 __init__函数的参数多了个formdata参数(dict类型),定义了HTML表单的键值对,会被编码并填充到request的boy部分

            form_response(response[, formname=Noneformid=Noneformnumber=0formdata=Noneformxpath=Noneformcss=Noneclickdata=Nonedont_click=False...])函数,返回一个新的FormRequest对象,这个对象包含表单需要填写区域的键值对,使用这个对象进行表单的提交处理有时会出现一些难以发现的bug,例如当表单的填充或是提交需要经过js处理时,使用这个对象就不太合适

参数:

  • response:为Response类型,response中包含有HTML表单,用于填充
  • formname(string):如果给定,表单的name属性值为formname指定值,将被选择填充
  • formid(string):如果给定,表单的id属性值为formid指定值,将被选择填充
  • formxpath(string):第一个满足xpath的表单将被使用
  • formcss(string):第一个满足css选择器的表单将被使用
  • formnumber(int):当response包含有多个表单时,选择哪一个表单进行填充,第一个表单的值是0
  • formdata(dict):需要填充到表单中的值,这个参数指定的表单的值才会被添加请求头
  • clickdata(dict):查找可点击的元素,如果没有指出,则scrapy会自动模拟点击第一个可点击元素
  • dont_click(boolean):如果为true,没有点击任何元素,表单会直接提交

FormRequest使用方式举例:

1、使用FormRequest发送HTTP的POST请求:

return [FormRequest(url="http://www.example.com/post/action",
                    formdata={'name': 'John Doe', 'age': '27'},
                    callback=self.after_post)]

2、使用FormRequest模拟用户登录:

import scrapy

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):
        # check login succeed before going on
        if "authentication failed" in response.body:
            self.logger.error("Login failed")
            return

Response对象

Response对象代表了HTTP响应

__init__函数:

  • url(string):响应对应的url请求
  • status(int):HTTP响应的状态码
  • headers(dict):reponse响应的header
  • body(bytes):响应的body部分,为了获得解码的文本,可以使用TextResponse的text属性
  • flags(list):包含Response.flags属性的初始值,使用的是浅拷贝,用于标识响应的信息,例如'cached'、'redirected'
  • request(Request对象):响应对应的Request对象

除了构造函数参数对用的属性以外,还有下列属性:

meta:与最初的Requets的meta属性的值一致,即使发生请求重发或是重定向,meta的值仍然与最初的Request的meta属性一致

常用函数:

copy():返回当前Response对象的拷贝

replace([url,status,headers,body,request,flags,cls]):用于更改当前reponse对象的部分属性的值

urljoin(url):用Response的url属性与提供的url参数构造绝对URL

follow(url,callback=None,method='GET',headers=None,body=None,cookies=None,meta=None,encoding='utf8'priority=0dont_filter=Falseerrback=None):返回一个request对象,可以将相对url变为绝对url,url参数可以相对url也可以是scrapy.link.Link对象(link extractor的结果),不仅仅是绝对url

Response的子类

这里主要介绍TextResponse

scrapy.http.TextResponse(url[, encoding[, ...]])

TextResponse主要用于处理二进制数据(例如图像)

TextResponse的构造函数多了一个参数:encoding(string):解码响应用到的编码,如果没有指定,默认使用响应头部或是body部分指定的编码

TextResponse支持下列属性:

  • text:解码后的响应body
  • encoding:解码响应body用的编码,解码用的编码方式按下列顺序依次进行:1、response指定的encoding,2、HTTP头部的Content-Type,3、response的body部分指定的编码方式,4、根据response的body推测编码方式
  • selector:选择器

TextResponse包含下列函数:

xpath(query):使用xpath进行选择

css(query):使用css选择器进行选择

follow(url,callback=None,method='GET',headers=None,body=None,cookies=None,meta=None,encoding='utf8'priority=0dont_filter=Falseerrback=None):返回一个request对象,可以将相对url变为绝对url,url参数可以相对url也可以是scrapy.link.Link对象(link extractor的结果),不仅仅是绝对url

body_as_unicode():与text属性一样,对body进行解码

猜你喜欢

转载自blog.csdn.net/dhaiuda/article/details/81556570