在parse方法中,我们经常要用到xpath、CSS、re来提取数据。在Scrapy中就为我们封装了这些方法于Selector,而且Selector
是基于lxml
构建的,这就意味着性能上不会有太大问题。在这里,我就不再重复记录什么是xpath、css、re,在以前博客中,这些都以记载过。下面简单演示下:
由于使用Xpath和CSS选择器来提取数据非常普遍,所以Scrapy
在response中设置了两个快捷接口,可以很方便的在response中使用Xpath和CSS选择器。
>>> response.xpath('//title/text()')
[]
>>> response.css('title::text')
[]
这个选择器有两种方法可以将selector对象以具体数据的方式呈现出来。extract方法显示多个数据,是列表类型,extract_first方法只显示第一条数据。
>>> 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']
>>> response.css('img').xpath('@src').extract_first()
u'image1_thumb.jpg',
extract_first方法若没有提取到数据,将返回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对象可以嵌套多次使用xpath和CSS方法,因为这两种提取方法返回的还是selector对象。
>>> 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
同样也提供了一个.re()
方法,可以快捷的使用正则提供数据,但是由于正则提取出的结果都是字符串,所以正则提取的结果不再能够像xpath()和css()
一样嵌套使用了。
>>> 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'
在Scrapy
中,请求和响应都被封装成了一个个Request
和Response
对象,方便传递和进行处理。在Spider
的解析方法中,如果我们获得了接下来要访问的url,那么我们就需要使用yield Request()
的方式生成一个Request
对象,并返回出去。下面介绍下scrapy下的Request对象。
from scrapy.http import Request
def __init__(self, url, callback=None, method='GET', headers=None, body=None,
cookies=None, meta=None, encoding='utf-8', priority=0,
dont_filter=False, errback=None, flags=None):
Scrapy
将会默认调用Spider
的parse()
来处理。需要注意的是,如果在处理的过程中触发了异常,则会调用errback。'GET'
。callback
中,传递数据使用的是浅拷贝的方式。body(str或unicode)
- 请求体。如果unicode传递了a,那么它被编码为 str使用传递的编码(默认为utf-8)。如果 body没有给出,则存储一个空字符串。不管这个参数的类型,存储的最终值将是一个str(不会是unicode或None)。1.使用dict:
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'}])
```
Scheduler
会使用这个参数来决定Request
的处理顺序,优先级的值越高,则排的位置越前,越早被处理。允许使用负值来指定较低的优先级。Scheduler
筛选,常常被用来发起一些重复的请求。谨慎使用这个参数,因为容易使爬取陷入死循环中,默认为False。包含此请求的网址的字符串。请记住,此属性包含转义的网址,因此它可能与构造函数中传递的网址不同。
表示请求中的HTTP方法的字符串。这保证是大写的。例如:"GET","POST","PUT"
等
包含请求标头的类似字典的对象。
包含请求正文的str,此属性为只读。更改请求使用的正文 replace()
。
包含此请求的任意元数据的字典。此dict对于新请求为空,通常由不同的Scrapy组件(扩展程序,中间件等)填充。因此,此dict中包含的数据取决于您启用的扩展。
copy()
返回一个新的请求,它是这个请求的副本。
可以使用此方法将Request
对象中的指定内容进行替换。
meta这个属性的作用很大,他可以直接在response对象中获取到,即可以使用Request.meta
属性来传递一些数据到回调函数中。但是meta
这个属性不止有这个作用,其中还有一些特殊的key有特殊的作用。
dont_redirect
- 禁止重定向dont_retry
- 禁止重试dont_cache
- 禁止缓存dont_obey_robotstxt
- 不遵守robots.txtdownload_timeout
- 下载超时时间download_maxsize
- 最大下载大小proxy
- 设置代理max_retry_times
- 最大重试次数
这个是Request的子类,主要是扩展了处理HTML表单的功能。在Request类中新增加了一个下面这些参数。
from scrapy.http import FormRequest
这个属性包含了HTML的表单数据,并且会被url编码并分配给请求的请求体。这个子类最大的作用是在发送POST请求时,能够使用字典发送POST提交的表单数据。
from_response(cls, response, formname=None, formid=None, formnumber=0, formdata=None, clickdata=None, dont_click=False, formxpath=None, formcss=None, **kwargs):
我们常用这个方法来模拟登陆,这也是用来构造Requet对象。下面是这个方法的参数:
from scrapy.http import Response
一个Response对象表示的HTTP响应,这通常是下载(由下载),并供给到爬虫进行处理。
def __init__(self, url, status=200, headers=None, body=b'', flags=None, request=None):
TextResponse
。Response.flags
列表。如果给定,列表将被浅复制。Response.request
。这代表Request生成此响应。url
包含响应的URL的字符串。此属性为只读。更改响应使用的URL replace()。
表示响应的HTTP状态的整数。示例:200, 404。
包含响应标题的类字典对象。可以使用get()返回具有指定名称的第一个标头值或getlist()返回具有指定名称的所有标头值来访问值。
本回复的正文。记住Response.body总是一个字节对象。如果你想unicode版本使用 TextResponse.text(只在TextResponse 和子类中可用)。此属性为只读。更改响应使用的主体 replace()。
Request生成此响应的对象
Request.meta的属性(即self.request.meta)。
包含此响应的标志的列表。标志是用于标记响应的标签。例如:'cached','redirected '等等。它们显示在Response(__ str__ 方法)的字符串表示上,它被引擎用于日志记录。
返回一个新的响应,它是此响应的副本
返回具有相同成员的Response对象,但通过指定的任何关键字参数赋予新值的成员除外。该属性Response.meta是默认复制。
通过将响应url与可能的相对URL 组合构造绝对url。
TextResponse对象向基Response类添加编码能力 ,这意味着仅用于二进制数据,例如图像,声音或任何媒体文件。
是一个字符串,包含用于此响应的编码。如果你创建一个TextResponse具有unicode主体的对象,它将使用这个编码进行编码(记住body属性总是一个字符串)。如果encoding是None(默认值),则将在响应标头和正文中查找编码。
响应体,如unicode。
包含此响应的编码的字符串。编码通过尝试以下机制按顺序解决:
用于提取数据
除了这个子类,还有HtmlResponse对象、XmlResponse对象等。