Response对象简述

    response对象是用来描述一个HTTP响应的,一般是和request成对出现,你用浏览器浏览网页的时候,给网站服务器一个request(请求),然后网站服务器根据你请求的内容给你一个response(响应)。

    那 Scrapy中的response又是什么东西?
    其实这个response和上边讲到的作用一样,不过在Scrapy中的response是一个基类,根据网站响应内容的不同,response还有三个子类 :

    • TextResponse
    • HtmlResponse
    • XmlResponse
      当页面下载完成之后,Scrapy中的下载器会根据HTML响应头部中的ContentType信息创建相应的子类对象。

    ps:其实这三个子类相差不是很大,操作上也几乎相同。本作者觉得用的最多的应该是HtmlResponse这个子类了。




    Response对象属性



    以最常用的HtmlResponse对象为例

    属性名 作用
    url HTTP相应的 URL地址,str类型的
    status HTTP响应状态码,int类型的(在pycharm的控制台中你可以看到,例如200,404)
    body HTTP响应正文,bytes类型
    text 文本形式的HTTP响应正文,str类型,由response.body使用response.encoding解码得到(代码见表格下方)
    encoding HTTP响应正文的编码(有时候会出现烦人的乱码问题,那你得注意是不是这个属性出问题了)
    request 产生该HTTP响应的Requset对象
    meta response.request.meta 在构造request对象的时候,可以将要传递个响应处理函数的信息通过meta参数传入;响应处理函数处理响应时候,通过response.meta将信息取出
    selector (这个比较重要了)选择器对象用来提取response中的数据
    xpath(query) 即xml路径语言,用来确定xml文档中某部分位置的语言(html属性xml)。这个家伙厉害了,从下载的页面中提取数据,少了它可不行
    css(query) 也是一种选择器,用来提取页面内中的数据,但是不如xpath强大。(CSS即层叠样式表,css选择器比xpath要简单一点,但是底层还是会调用xpath)
    urljoin(url) 用来构造绝对url,(爬取页面的时候跳转到第二页的时候需要重新构造request,这个时候用的到这个属性)
    1. # text属性来源
    2. response.text=response.body.decode(response.encoding)


    Response对象常用的属性

    常用的属性应该是上表中的最后三个了即 xpath、css、urljoin。


    xpath()语法

    表达式 描述
    / 选中文档的根(root)
    . 选中当前节点
    . . 选中当前节点的父节点
    element 选中当前节点中所有的element节点,如h标签,a标签等
    //element 选中后代节点中所有的element节点
    * 选中所有元素节点
    text() 选中所有文本子节点
    @ATTR 选中名为ATTR的属性节点
    @* 选中所有属性节点

    举个栗子:

    1. text='''
    2. <ul>
    3. <li>Python 学习手册<b>价格:99.00元</b></li>
    4. <li>Python 核心编程<b>价格:88.00元</b></li>
    5. <li>Python 基础教程<b>价格:80.00元</b></li>
    6. </ul>
    7. '''
    8. selector=Selector(text=text)
    9. print(selector.xpath('.//li/b/text()'))
     [<Selector xpath='.//li/b/text()' data='价格:99.00元'>, 
     <Selector xpath='.//li/b/text()' data='价格:88.00元'>, 
     <Selector xpath='.//li/b/text()' data='价格:80.00元'>]
    

    css()语法

    表达式 描述
    * 选中所有元素
    E 选中E元素
    E1,E2 选中E1和E2元素
    E1 E2 选中E1后代元素中所有的E2元素
    E1>E2 选中E1子元素中的所有E2元素
    E1+E2 选中所有E1元素的兄弟元素
    .CLASS 选中CLASS属性包含CLASS的元素
    #ID 选中id舒心为ID的元素
    [ATTR] 选中包含ATTR属性的元素
    [ATTR=VALUE] 选中包含ATTR属性且值=VALUE的元素
    [ATTR~=VALUE] 选中包含ATTR属性且值包含VALUE的元素
    E:nth-child(n) E:nth-last-child(n) 选中E元素,且该元素必须是其父元素的(倒数)第n个节点
    E:first-child E:last-child 选中E元素,且这个元素必须是父元素的第一个或最后一个节点
    E:empty 选中没有元素的节点
    E::text 选中E元素的文本节点(ps:我没写错,就是双冒号)
    #取网页中类名为pager的ul节点中的类名为next的子节点li 中的a标签的href的值(构造下一页面的url)
    next_url=response.css('ul.pager li.next a::attr(href)').extract_first()
    

    urljoin(url)

    话不多说,直接上代码

    #response.css返回的对象是SelectList。所以要用extract_first()
    next_url=response.css('ul.pager li.next a::attr(href)').extract_first() 
    if next_url:
        #如果找到下一页的url,得到绝对路径构造新的Request
        next_url=response.urljoin(next_url)
    重新构造request方法,然后调用页面解析函数(递归?),不断爬取页面中的内容
        yield scrapy.Request(url=next_url,callback=self.parse_book)
    
    • urljoin(url) 用于构造绝对url ,当传入的url参数是一个相对地址的时候,这个伙计会根据response.url计算出相应的绝对地址。举个栗子:

      response.url=‘https://mp.csdn.net’,

      url=‘mdeditor/85640067’。


      response.joinurl(url) 的值为 ‘https://mp.csdn.net/mdeditor/85640067’ 然后就可以根据这个构造出来的新的url,重新构造request,然后爬取下一页面的内容了


    更多相关内容请参考 文档 https://zhuanlan.zhihu.com/p/40332579