网页数据的解析提取(parsel库的使用)

        前面,我们已经介绍了Xpath库和Beautiful Soup库(支持css选择器)来提取页面信息。它们有各自的优缺点,那可不可以取长补短呢?当然可以,parsel库就是结合Xpath和css选择器两种方式来提取网页信息。同时,Python爬虫有一个最流行的Scrapy框架,parsel就是它的底层支持。了解了它,后面学习Scrapy选择器的用法就非常方便了!!!

目录

Parsel

1、准备工作

2、案例

3、提取文本 

(1)Xpath的提取方法

(2)css选择器提取方法

4、提取属性

5、正则提取


Parsel

1、准备工作

使用前要先安装parsel库,安装命令如下:

pip3 install parsel

2、案例

        为了让读者更加能清晰感受到parsel库,首先来看一下一个示例:

# html代码
html = '''
<div>
    <ul>
        <li class="item-0">firsst item</li>
        <li class="item-1"><a href="link2.html">secomd item</a> </li>
        <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span> </a> firsst item</li>
        <li class="item-1 active"><a href="link4.html">fourth item</a> </li>
        <li class="item-0"><a href="link5.html">fifth item</a> </li>
   </ul> 
</div>
'''
# 导包
from parsel import Selector
# 创建一个Selector对象,向其中传入text参数,传入的就是上面的html代码
selector = Selector(html)
# 有了Selector对象,我们就可以使用css和xpath方法
# 这里用css选择器选择class为item-0的节点
items = selector.css('.item-0')
# 打印该节点的长度 类型 信息
print(len(items),type(items),items)
# 分隔行
print()
# 这里我们用xpath的方式提取li节点提取class为item-0的节点
items2 = selector.xpath('//li[contains(@class, "item-0")]')
# 打印该节点的长度 类型 信息
print(len(items2),type(items2),items2)
# 这两种方式得到的结果是一样的

结果如下:

3 <class 'parsel.selector.SelectorList'> [<Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0">firsst item</li>'>, <Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0 active"><a href="li...'>, <Selector query="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='<li class="item-0"><a href="link5.htm...'>]

3 <class 'parsel.selector.SelectorList'> [<Selector query='//li[contains(@class, "item-0")]' data='<li class="item-0">firsst item</li>'>, <Selector query='//li[contains(@class, "item-0")]' data='<li class="item-0 active"><a href="li...'>, <Selector query='//li[contains(@class, "item-0")]' data='<li class="item-0"><a href="link5.htm...'>]

        可以看到两个结果都是SelectorList对象,这其实是一个可迭代对象。用len 方法获取了结果的长度,都是3。另外,提取结果代表的节点也是一样的,都是第1、3、5个li节点,每个节点还是以Selector 对象的形式返回, 其中每个 Selector 对象的 data属性里包含对应提取节点的 HTML 代码。

        这里大家可能会有个疑问,第一次不是用css方法提取的节点吗? 为什么结果中的 Selector对象输出的是xpath属性而不是css属性? 这是因为在css方法的背后,我们传入的 CSS 选择器首先是被转成了 XPath,真正用于节点提取的是XPath。其中CSS选择器转换为 XPath的过程是由底层的 cssselect 这个库实现的, 例如.item-0这个CSS 选择器转换为 XPath的结果就是 descendant-or-self::*[@class and contains(concat(' ' , normalize-space(@class), ' '), ' item-o ')], 因此输出的 Selector 对象就有了xpath属性。不过大家不用担心,这个对提取结果是没有影响的,仅仅是换了一个表示方法而已。

3、提取文本 

        提取文本只需采用xpath或者css选择器的方式去获取即可。由于Selector对象是一个可迭代对象,这里我们需要进行遍历然后再选择Xpath或css选择器的方式去提取。

(1)Xpath的提取方法

        首先演示一下用Xpath方式去获取文本,Xpath是用text()方法来提取节点的文本,但提取的只是Selector构成的可迭代对象SelectorList。SelectorList中有一个get方法,可以获取第一个Selector对象的文本内容;getall方法则获取所有Selector对象的文本内容。代码如下:

# html代码
html = '''
<div>
    <ul>
        <li class="item-0">first item</li>
        <li class="item-1"><a href="link2.html">secomd item</a> </li>
        <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span> </a> firsst item</li>
        <li class="item-1 active"><a href="link4.html">fourth item</a> </li>
        <li class="item-0"><a href="link5.html">fifth item</a> </li>
   </ul> 
</div>
'''
from parsel import Selector
selector = Selector(html)
#  采用css选择器选择目标节点
items = selector.css('.item-0')
# 因为Selector是一个可迭代的对象,它是有列表组成的。所以可以遍历提取所需要的信息
for item in items:
    # 采用Xpath方式提取文本信息,Selector中有一个get方法,它是用来提取所获取第一个节点的文本内容
    # text = item.xpath('.//text()').get()
    # print(text)
    # 采用Xpath方式提取文本信息,Selector中有一个getall方法,它是用来提取所获取所有的节点文本内容
    text2 = item.xpath('.//text()').getall()
    print(text2)

结果如下:

first item
['first item']
third item
['third item', ' ', ' firsst item']
fifth item
['fifth item', ' ']

(2)css选择器提取方法

        css选择器是通过::text来提取文本的,采用css选择器定位到所需要的节点,然后加上::text,但它返回的也是Selector对象构成的SelectorList对象,所以也是跟上面一样,加上get方法或getall方法。 

# html代码
html = '''
<div>
    <ul>
        <li class="item-0">first item</li>
        <li class="item-1"><a href="link2.html">secomd item</a> </li>
        <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span> </a> firsst item</li>
        <li class="item-1 active"><a href="link4.html">fourth item</a> </li>
        <li class="item-0"><a href="link5.html">fifth item</a> </li>
   </ul> 
</div>
'''
from parsel import Selector
selector = Selector(html)
#  采用css选择器选择目标节点
items = selector.css('.item-0')
# 因为Selector是一个可迭代的对象,它是有列表组成的。所以可以遍历提取所需要的信息
for item in items:
    # 采用Xpath方式提取文本信息,Selector中有一个get方法,它是用来提取所获取第一个节点的文本内容
    text = item.css('::text').get()
    print(text)
    # 采用Xpath方式提取文本信息,Selector中有一个getall方法,它是用来提取所获取所有的节点文本内容
    text2 = item.css('::text').getall()
    print(text2)

结果如下:

C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\python.exe C:\Users\Lenovo\Desktop\爬虫学习\Python知识\parsel库\提取文本2.py 
first item
['first item']
third item
['third item', ' ', ' firsst item']
fifth item
['fifth item', ' ']

进程已结束,退出代码为 0

4、提取属性

        提取属性的方式更上面类似,直接采用xpath提取属性的方法:选中节点后加上/@再加属性名称;css选择器提取属性的方法加::attr(),往里面传入对应的属性名称。示例如下:

# html代码
html = '''
<div>
    <ul>
        <li class="item-0">first item</li>
        <li class="item-1"><a href="link2.html">secomd item</a> </li>
        <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span> </a> firsst item</li>
        <li class="item-1 active"><a href="link4.html">fourth item</a> </li>
        <li class="item-0"><a href="link5.html">fifth item</a> </li>
   </ul> 
</div>
'''
from parsel import Selector
selector = Selector(text=html)
# css选择器提取属性的方式
result = selector.css('.item-0.active a::attr(href)').get()
print(result)
# xpath提取属性的方式
result = selector.xpath('//li[contains(@class, "item-0") and contains(@class, "active")]/a/@href').get()
print(result)

结果如下:

link3.html
link3.html

5、正则提取

        Selector对象还提供正则表达式的提取方法。可以先采用css选择器或xpath选择器选中所需要的目标节点,然后调用Selector对象的re方法输入正则表达式来匹配,其匹配选中节点所有符合正则表达式的内容;re_first方法输入正则表达式来匹配,其匹配选中节点第一个符合正则表达式的内容。示例如下:

# html代码
html = '''
<div>
    <ul>
        <li class="item-0">first item</li>
        <li class="item-1"><a href="link2.html">secomd item</a> </li>
        <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span> </a> firsst item</li>
        <li class="item-1 active"><a href="link4.html">fourth item</a> </li>
        <li class="item-0"><a href="link5.html">fifth item</a> </li>
   </ul> 
</div>
'''
from parsel import Selector
selector = Selector(text=html)
# 选用css选择器选中目标节点,再用re方法输入正则表达式来匹配,其匹配选中节点所有符合正则表达式的内容
result = selector.css('.item-0').re('link.*')
print(result)
# 选用css选择器选中目标节点,再用re_first方法输入正则表达式来匹配,其匹配选中节点第一个符合正则表达式的内容
result = selector.css('.item-0').re_first('<span class="bold">(.*?)</span>')
print(result)

结果如下:

['link3.html"><span class="bold">third item</span> </a> firsst item</li>', 'link5.html">fifth item</a> </li>']
third item
  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值