class scrapy.selector.Selector(response = None,text = None,type = None)
selector 是对 response 的封装,用来对选取其中的特定内容。css
下面是 Selector 的主要成员变量:html
response 一个HtmlResponse或者XmlResponse对象git
text 一个unicode字符串或者utf-8文本,当response为空的时候才有效。同时使用text和response是未定义行为github
type 定义selector的类型,能够是html、xml或None(default)正则表达式
- xpath() 寻找匹配xpath query 的节点,并返回 SelectorList 的一个实例结果,单一化其全部元素。返回的列表元素也实现了 Selector 的接口。query 是包含XPATH查询请求的字符串。 - css() 应用给定的CSS选择器,返回 SelectorList 的一个实例。在后台,经过 cssselect 库和运行 .xpath() 方法,CSS查询会被转换为XPath查询。 - extract() 串行化并将匹配到的节点返回一个unicode字符串列表。 结尾是编码内容的百分比 - reg(regex) 应用给定的regex,并返回匹配到的unicode字符串列表。regex 能够是一个已编译的正则表达式,也能够是一个将被 re.compile(regex) 编译为正则表达式的字符串。 - register_namespaces(prefix, uri) 注册给定的命名空间,其将在 Selector 中使用。 不注册命名空间,你将没法从非标准命名空间中选择或提取数据。 - remove_namespaces() 移除全部的命名空间,容许使用少许的命名空间xpaths遍历文档 - __nonzero__() 若是选择了任意的真实文档,将返回 True ,不然返回 False 。 也就是说, Selector 的布尔值是经过它选择的内容肯定的。
class scrapy.selector.SelectorList
SelectorList 类是内建 list 类的子类,提供了一些额外的方法。shell
- xpath(query) 对列表中的每一个元素调用 .xpath() 方法,返回结果为另外一个单一化的 SelectorList - css(query) 对列表中的各个元素调用 .css() 方法,返回结果为另外一个单一化的 SelectorList - extract() 对列表中的各个元素调用 .extract() 方法,返回结果为单一化的unicode字符串列表 - re() 对列表中的各个元素调用 .re() 方法,返回结果为单一化的unicode字符串列表 - __nonzero__() 列表非空则返回True,不然返回False
假设已经有一个经过 XmlResponse 对象实例化的 Selector ,以下:scrapy
sel = Selector(xml_response)
选择全部的 元素,返回SelectorList :函数
sel.xpath(“//product”)
从 Google Base XML feed 中提取全部的价钱,这须要注册一个命名空间:性能
sel.register_namespace("g", "http://base.google.com/ns/1.0") sel.xpath("//g:price").extract()
在处理爬虫项目时,能够彻底去掉命名空间而仅仅处理元素名字,这样在写更多简单/实用的XPath会方便不少。为此能够使用Selector.remove_namespaces()方法。google
以Github博客的atom订阅来解释这个状况。
首先,咱们使用想爬取的url来打开shell:
scrapy shell https://github.com/blog.atom
一旦进入shell,咱们能够尝试选择全部的 <link> 对象,能够看到没有结果(由于Atom XML命名空间混淆了这些节点):
>>> response.xpath("//link") []
但一旦咱们调用 **Selector.remove_namespaces() **方法,全部的节点均可以直接经过他们的名字来访问:
>>> response.selector.remove_namespaces() >>> response.xpath("//link") [<Selector xpath='//link' data=u'<link xmlns="http://www.w3.org/2005/Atom'>, <Selector xpath='//link' data=u'<link xmlns="http://www.w3.org/2005/Atom'>, ...
若是你对为何命名空间移除操做并不老是被调用,而须要手动调用有疑惑。这是由于存在以下两个缘由,按照相关顺序以下: 1. 移除命名空间须要迭代并修改文件的全部节点,而这对于Scrapy爬取的全部文档操做须要必定的性能消耗 2. 会存在这样的状况,确实须要使用命名空间,但有些元素的名字与命名空间冲突。尽管这些状况很是少见。
若是XPath没有指定命名空间的话,那么它的命名空间为空。若是待解析XML文件含有默认命名空间的话,那么你必须添加那个命名空间的前缀,而且把命名空间的URI添加到XmlNamespaceManager中,不然,你得不到任何查询结果。
对于scrapy,这里提供了register_namespaces(prefix, uri) 和 remove_namespaces()两个函数来解决这个问题。