response对象是用来描述一个HTTP响应的,一般是和request成对出现,你用浏览器浏览网页的时候,给网站服务器一个request(请求),然后网站服务器根据你请求的内容给你一个response(响应)。
那 Scrapy中的response又是什么东西?
其实这个response和上边讲到的作用一样,不过在Scrapy中的response是一个基类,根据网站响应内容的不同,response还有三个子类 :
当页面下载完成之后,Scrapy中的下载器会根据HTML响应头部中的ContentType信息创建相应的子类对象。
ps:其实这三个子类相差不是很大,操作上也几乎相同。本作者觉得用的最多的应该是HtmlResponse这个子类了。
以最常用的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,这个时候用的到这个属性) |
# text属性来源
response.text=response.body.decode(response.encoding)
常用的属性应该是上表中的最后三个了即 xpath、css、urljoin。
表达式 | 描述 |
---|---|
/ | 选中文档的根(root) |
. | 选中当前节点 |
. . | 选中当前节点的父节点 |
element | 选中当前节点中所有的element节点,如h标签,a标签等 |
//element | 选中后代节点中所有的element节点 |
* | 选中所有元素节点 |
text() | 选中所有文本子节点 |
@ATTR | 选中名为ATTR的属性节点 |
@* | 选中所有属性节点 |
[谓语] | 用来查找某个特定的节点或者包含某个特定值的节点 |
举个栗子:
text='''
- Python 学习手册价格:99.00元
- Python 核心编程价格:88.00元
- Python 基础教程价格:80.00元
'''
selector=Selector(text=text)
print(selector.xpath('.//li/b/text()'))
[,
,
]
表达式 | 描述 |
---|---|
* | 选中所有元素 |
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()
话不多说,直接上代码
#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,然后爬取下一页面的内容了