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)

系列文章:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271