Scrapy-3.Selector和Request

本文地址:https://www.jianshu.com/p/df7e56f2024c

数据提取(Selector)

Scrapy中,封装了我们常用的提取数据的方式,有正则、Xpath、CSS选择器等。而且Selector是基于lxml构建的,这就意味着性能上不会有太大问题。

Xpath和CSS选择器

由于使用Xpath和CSS选择器来提取数据非常普遍,所以Scrapy在response中设置了两个快捷接口,可以很方便的在response中使用Xpath和CSS选择器。

>>> response.xpath('//title/text()')
[<Selector (text) xpath=//title/text()>]
>>> response.css('title::text')
[<Selector (text) xpath=//title/text()>]

可以看到,使用Selector获取的是一个Selector对象的列表,所以可以嵌套和混合Xpath和CSS选择器使用:

>>> response.css('img').xpath('@src').extract()
[u'image1_thumb.jpg',
 u'image2_thumb.jpg',
 u'image3_thumb.jpg',
 u'image4_thumb.jpg',
 u'image5_thumb.jpg']

同时,由于获得的是一个Selector对象,所以,如果需要实际的提取出文本数据,那么就要使用一个特殊的方法.extract(),这个方法提取出的会是一个列表,包含的是所有符合条件的内容。

>>> response.xpath('//title/text()').extract()
[u'Example website']

如果只需要提取一个数据,那么可以使用.extract_first(),这个方法会默认的提取出第一个结果。

>>> response.xpath('//div[@id="images"]/a/text()').extract_first()
u'Name: My image 1 '

这个方法如果没有提取到任何数据,那么将会返回一个None,当然,你也可以自行设定没有找到结果返回的内容。

>>> response.xpath('//div[@id="not-exists"]/text()').extract_first() is None
True
>>> response.xpath('//div[@id="not-exists"]/text()').extract_first(default='not-found')
'not-found'

正则表达式

Selector同样也提供了一个.re()方法,可以快捷的使用正则提供数据,但是由于正则提取出的结果都是字符串,所以正则提取的结果不再能够像.xpath()一样嵌套使用了。

>>> response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
[u'My image 1',
 u'My image 2',
 u'My image 3',
 u'My image 4',
 u'My image 5']

同时,对正则也提供了一个与.extract_first()相对应地.re_first()方法,可以只提取出第一个匹配的字符串。

>>> response.xpath('//a[contains(@href, "image")]/text()').re_first(r'Name:\s*(.*)')
u'My image 1'

Request

Scrapy中,请求和响应都被封装成了一个个RequestResponse对象,方便传递和进行处理。

Spider的解析方法中,如果我们获得了接下来要访问的url,那么我们就需要使用yield Request()的方式生成一个Request对象,并返回出去。

这是目前大规模爬取基本都会使用的一个模式。

class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback, flags])

参数

  • url (string) – 访问的URL,这是唯一一个必备参数。

  • callback (callable) – 回调函数,网页请求完毕之后,将使用这个函数来解析获得的响应。如果没有指定这个参数,那么Scrapy将会默认调用Spiderparse()来处理。

    需要注意的是,如果在处理的过程中触发了异常,则会调用errback。

  • method (string) – 请求方法,默认为'GET'

  • meta (dict) – 通过这个参数,可以将一些数据传递到接下来的callback中,传递数据使用的是浅拷贝的方式。

  • body (str or unicode) – 请求体数据。

  • headers (dict) – 请求报头。字典的值可以为列表(多个值的报头)。如果值为None,那么不会发送任何报头。

  • cookies (dict or list) – cookies可以有字典和列表两种格式。

    1. 使用字典则可以正常的传递cookies

      request_with_cookies = Request(url="http://www.example.com",
                                     cookies={'currency': 'USD', 'country': 'UY'})
      
    2. 如果使用的是包含着字典的列表,那么可以在字典中附带上cookies的domain和path等参数

      request_with_cookies = Request(url="http://www.example.com",
                                     cookies=[{'name': 'currency',
                                              'value': 'USD',
                                              'domain': 'example.com',
                                              'path': '/currency'}])
      
  • encoding (string) – 编码格式,默认为utf-8。

  • priority (int) – 优先级。Scheduler会使用这个参数来决定Request的处理顺序,优先级的值越高,则排的位置越前,越早被处理。允许使用负值来指定较低的优先级。

  • dont_filter (boolean) – 如果这个值设定为True,那么这个请求将不会被Scheduler筛选,常常被用来发起一些重复的请求。谨慎使用这个参数,因为容易使爬取陷入死循环中,默认为False。

  • errback (callable) – 在处理request时触发异常时调用的异常处理函数。

Request属性与方法

Request这个对象里也有一些属性和方法,可以在后续的处理中进行使用。

  • url

    请求的url。

  • method

    请求的方法。

  • headers

    请求的headers。

  • body

    请求的body。

  • meta

    请求的元数据。

  • copy()

    复制出一个新的Request对象。

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

    可以使用此方法将Request对象中的指定内容进行替换。

Request.meta中的特殊key

在构造Request对象的时候,可以使用Request.meta属性来传递一些数据到回调函数中。但是meta这个属性不止有这个作用,其中还有一些特殊的key有特殊的作用。

它们分别是:

  • dont_redirect – 禁止重定向
  • dont_retry – 禁止重试
  • handle_httpstatus_list
  • handle_httpstatus_all
  • dont_merge_cookies
  • cookiejar
  • dont_cache – 禁止缓存
  • redirect_urls
  • bindaddress
  • dont_obey_robotstxt – 不遵守robots.txt
  • download_timeout – 下载超时时间
  • download_maxsize – 最大下载大小
  • download_latency
  • download_fail_on_dataloss
  • proxy – 设置代理
  • ftp_user (See FTP_USER for more info)
  • ftp_password (See FTP_PASSWORD for more info)
  • referrer_policy
  • max_retry_times – 最大重试次数

FormRequest

FormRequestRequest的子类,主要是扩展了处理HTML表单的功能。

class scrapy.http.FormRequest(url[, formdata, ...])

FormRequest添加了一个formdata参数,其余的参数都与Request相同。

  • formdata(dict对象或者可迭代的一系列tuple) – 这个属性包含了HTML的表单数据,并且会被url编码并分配给请求的请求体。

这个子类最大的作用是在发送POST请求时,能够使用字典发送POST提交的表单数据。

例子:

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

系列文章:

    原文作者:王南北丶
    原文地址: https://www.jianshu.com/p/df7e56f2024c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞