上QQ阅读APP看书,第一时间看更新
3.2 Response内置Selector
在实际开发中,几乎不需要手动创建Selector对象,在第一次访问一个Response对象的selector属性时,Response对象内部会以自身为参数自动创建Selector对象,并将该Selector对象缓存,以便下次使用。Scrapy源码中的相关实现如下:
class TextResponse(Response): def __init__(self, *args, **kwargs): ... self._cached_selector = None ... @property def selector(self): from scrapy.selector import Selector if self._cached_selector is None: self._cached_selector = Selector(self) return self._cached_selector ...
通常,我们直接使用Response对象内置的Selector对象即可:
>>> from scrapy.http import HtmlResponse >>> body = ''' ... <html> ... <body> ... <h1>Hello World</h1> ... <h1>Hello Scrapy</h1> ... <b>Hello python</b> ... <ul> ... <li>C++</li> ... <li>Java</li> ... <li>Python</li> ... </ul> ... </body> ... </html> ... ''' ... >>> response = HtmlResponse(url='http://www.example.com', body=body, encoding='utf8') >>> response.selector <Selector xpath=None data='<html>\n <body>\n <h1>He'>
为了方便用户使用,Response对象还提供了xpath和css方法,它们在内部分别调用内置Selector对象的xpath和css方法。Scrapy源码中的相关实现如下:
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() ['Hello World', 'Hello Scrapy'] >>> response.css('li::text').extract() ['C++', 'Java', 'Python']