t## 使用Selector提取数据 ##
从页面中提取数据是SPider最重要的的工作之一
Selete对象
从页面中提取数据的核心技术是HTTP文本解析,常用的文本解析模块:
- BeautifulSoup API简单 但解析速度慢
- lxml 由C语言编写的xml解析库(libxm2),解析速度快 但是API复杂
- Scrapy 综合以上两者优势实现了Selector类,它是由lxml库构建的,并简化了API
使用时先通过XPath或者CSS选择器选中要提取的数据,然后进行提取
Select对象的使用
创建对象
Select类的实现位于scrapy.selector模块,创建selector对象时,可将页面的HTML文档字符串传递给Selector构造器方法的text参数:
from scrapy.selector import Selector
text = '''
<html>
<body>
<h1>Hello World</h1>
<h1>Hello Scrapy</h1>
<h1>Hello python</h1>
<ul>
<li>C++</li>
<li>java</li>
<li>python</li>
</ul>
</body>
</html>
'''
selectot = Selector(text=text)
<Selector xpath = None data'<html>\n <body>\n <h1>He'>
也可以使用一个response对象那个构造Selector对象,传递给Selector构造器方法的response参数
response = HtmlResponse(url='http://www.example.com'body = body,encoding ='utf-8')
selector = Selector(response=response)
Selector
<Selector xpath=None data'<html>\n <body\n> <h1>He'>
选取数据
调用Select对象的xpath、css方法(传入xpath 或css选择器表达式),可以选中文档中的某个或某些部分:
selector_list = selector.xpath('//h1')#选取文档中所有的h1
selector_list #其中包含两个<h1>对应的selector对象
<Selector xpath ='.//h1'data='<h1>Hello World</h1>'
<Selector xpath ='.//h1'data='<h1>Hello Scrapy</h1>'
XPath css返回一个SelectorList对象,包含每个被选中部分对应的Selector对象,SelectorList支持列表接口,for迭代访问
for sel in Selector_list:
print(sel.xpath('/text()'))
[<Selector xpath='./text()'data='Hello World'>]
[<Selector xpath='./text()'data='Hello Scrapy'>]
SelectorList对象也有xpath和css方法,调用他们的方法:以接收到的参数分别调用其中一个Selector对象的xpath css 将所有搜集到的一个新的SlectorList对象返回给用户
selector_list.xpath('./text()')
<selector.xpath = './text()'data = 'Hello World'>
<selector.xpath = './text()'data = 'Hello Scrapy'>
selector.xpath('.//path').css('li').xpath('./text()')
[<Selector xpath='.//text()'data='C++'>]
[<Selector xpath='.//text()'data='java'>]
[<Selector xpath='.//text()'data='python'>]
提取数据
调用Selector SelectorList对象的一下方法可以将选中的内容提取
- extract()
- re()
- extract_first()
re_first()
调用extract方法将返回选中内容的Unicode字符串
sl = selecor.xpath('.//li')
sl = selector.xpath('.//li/path()')
与SelectorList对象的XPath css方法类似 Selector对象的extract方法内部调用其中每个Selector对象的extract方法,并把所有的结果搜集到列表返回给用户
sl = selector.xpath('.//li/text')
extract_first方法返回第一个Selector对象调用extract方法的结果。 直接提取初来的是Unicode而不是列表
sl = selector.xpath('.//path')
re 正则表达式
re_first返回其中第一个Selector对象
Response内置Selector
在第一次访问一个response对象的Selector属性时,response对象内部会以自身为参数自动创建Selector对象,并将Selector对象缓存,以便下次使用。Scrapy源码:
calss TextResponse(Response):
def__init__(self,*arges,**kwargs):
'''
self._cached_selector = None
'''
def selector(self):
from scrapy.selector import Selector
if self._cached_sekector is None:
self._cached_sekector = Selector(self)
return self._cached_sekector
通常直接使用Response对象内置的Selector对象即可:
from scrapy.http import HtmlResponse
resopnse = HtmlResponse(url = 'http://www.example.com',body = body,enconding = 'utf-8')
response.selector
Response对象还提供了XPath和css
class TextResponse(Response):
def xpath(self,query,**kwargs):
return self.selector.xpath(query,**kwargs)
def css(self,query):
return self.selector.css(query)
快捷方式
response.xpath('.//h1/text()').extract()
response.css('li::text').extract()
XPath
XPath:XML路径语言(XML Path Language),确定xml文档中某系部分位置的语言。
xml文档(html属于xml)是由一系列节点构成的树
xml文档的节点有多种类型,常用:
- 根节点 整个文档的跟
- 元素节点 html body div p a
- 属性节点 href
- 文本节点 Click here
基础语法
- / 选中文档的跟(root)
- . 选中当前节点
- .. 父节点
- ELEMENT 选中子节点中所有ELEMENT元素节点
- //ELEMENT 选中后代节点中所有ELEMENT元素节点
- × 所有元素节点
- text() 文本子节点
- @attr 选中名字为attr的属性节点
@* 所有属性节点
CSS
CSS层叠样式表 语法比xpath简单 但是没有它强大。
用Selector调用css时,内部Python库cssSelect将CSS转化为xpath
基本语法- × 所有
- E 选中E元素
- E1,E2 选中E1,E2元素
- E1 E2 选取E1 后代元素中的E2元素
- E1>E2 选取E1子元素中的E2元素
- E1+E2 选取兄弟中的E2元素
- ,class 选取class属性包含的class的元素
- #id id属性为id的元素
- [attr] 包含attr的元素
- [attr=value] 包含attr属性且值为value的元素
- [attr~=value] 包含attr且包含value的元素
- E:nth-(last-)child(n) :选中E元素,且该元素必须是其父元素的第几个元素
- E:empty 选中没有子元素的E元素
- E::text 选中E元素的文本节点(text node)