返回介绍

3.1 Selector 对象

发布于 2024-02-05 21:13:20 字数 5664 浏览 0 评论 0 收藏 0

从页面中提取数据的核心技术是HTTP文本解析,在Python中常用以下模块处理此类问题:

BeautifulSoup

BeautifulSoup是非常流行的HTTP解析库,API简洁易用,但解析速度较慢。

lxml

lxml是一套由C语言编写的xml解析库(libxml2),解析速度更快,API相对复杂。

Scrapy综合上述两者优点实现了Selector类,它是基于lxml库构建的,并简化了API接口。在Scrapy中使用Selector对象提取页面中的数据,使用时先通过XPath或CSS选择器选中页面中要提取的数据,然后进行提取。

下面详细介绍Selector对象的使用。

3.1.1 创建对象

Selector类的实现位于scrapy.selector模块,创建Selector对象时,可将页面的HTML文档字符串传递给Selector构造器方法的text参数:

>>> from scrapy.selector import Selector
>>> text = '''
... <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>
... '''
...
>>> selector = Selector(text=text)
<Selector xpath=None data='<html>\n    <body>\n  <h1>He'>

也可以使用一个Response对象构造Selector对象,将其传递给Selector构造器方法的response参数:

>>> from scrapy.selector import 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')
>>> selector = Selector(response=response)
>>> selector
<Selector xpath=None data='<html>\n   <body>\n      <h1>He'>

3.1.2 选中数据

调用Selector对象的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语句迭代访问其中的每一个Selector对象:

>>> 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方法,并将所有结果收集到一个新的SelectorList对象返回给用户。请看下面的示例:

>>> selector_list.xpath('./text()')
[<Selector xpath='./text()' data='Hello World'>,
 <Selector xpath='./text()' data='Hello Scrapy'>]
>>> selector.xpath('.//ul').css('li').xpath('./text()')
[<Selector xpath='./text()' data='C++'>,
 <Selector xpath='./text()' data='Java'>,
 <Selector xpath='./text()' data='Python'>]

3.1.3 提取数据

调用Selector或SelectorLis对象的以下方法可将选中的内容提取:

extract()

re()

extract_first() (SelectorList专有)

re_first() (SelectorList专有)

首先来看extract方法,调用Selector对象的extract方法将返回选中内容的Unicode字符串:

>>> sl = selector.xpath('.//li')
>>> sl
[<Selector xpath='.//li' data='<li>C++</li>'>,
<Selector xpath='.//li' data='<li>Java</li>'>,
<Selector xpath='.//li' data='<li>Python</li>'>]
>>> sl[0].extract()
'<li>C++</li>'
>>> sl = selector.xpath('.//li/text()')
>>> sl
[<Selector xpath='.//li/text()' data='C++'>,
<Selector xpath='.//li/text()' data='Java'>,
<Selector xpath='.//li/text()' data='Python'>]
>>> sl[1].extract()
'Java'

与SelectorList对象的xpath和css方法类似,SelectorList对象的extract方法内部会调用其中每个Selector对象的extract方法,并把所有结果收集到一个列表返回给用户:

>>> sl = selector.xpath('.//li/text()')
>>> sl
[<Selector xpath='.//li/text()' data='C++'>,
 <Selector xpath='.//li/text()' data='Java'>,
 <Selector xpath='.//li/text()' data='Python'>]
>>> sl.extract()
['C++', 'Java', 'Python']

SelectorList对象还有一个extract_first方法,该方法返回其中第一个Selector对象调用extract方法的结果。通常,在SelectorList对象中只包含一个Selector对象时调用该方法,直接提取出Unicode字符串而不是列表:

>>> sl = selector.xpath('.//b')
>>> sl
[<Selector xpath='.//b' data='<b>Hello Python</b>'>]
>>> sl.extract()
['<b>Hello Python</b>']
>>> sl.extract_first()
'<b>Hello Python</b>'

有些时候,我们想使用正则表达式提取选中内容中的某部分,可以使用re方法(两个对象都有该方法):

>>> text = '''
... <ul>
...  <li>Python 学习手册 <b>价格: 99.00 元</b></li>
...  <li>Python 核心编程 <b>价格: 88.00 元</b></li>
...  <li>Python 基础教程 <b>价格: 80.00 元</b></li>
... </ul>
... '''
...
>>> selector = Selector(text=text)
>>> selector.xpath('.//li/b/text()')
[<Selector xpath='.//li/b/text()' data='价格: 99.00 元'>,
 <Selector xpath='.//li/b/text()' data='价格: 88.00 元'>,
 <Selector xpath='.//li/b/text()' data='价格: 80.00 元'>]
>>> selector.xpath('.//li/b/text()').extract()
['价格: 99.00 元', '价格: 88.00 元', '价格: 80.00 元']
>>> selector.xpath('.//li/b/text()').re('\d+\.\d+') #只提取价格的数字部分
['99.00', '88.00', '80.00']

SelectorList对象的re_first方法同样返回其中的第一个Selector对象调用re方法的结果:

>>> selector.xpath('.//li/b/text()').re_first('\d+\.\d+')
'99.00'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文