parsel 这个库可以对 HTML 和 XML 进行解析,并支持使用 XPath 和 CSS Selector 对内容进行提取和修改,同时它还融合了正则表达式提取的功能。
python3环境下输入:
html = '''
- first item
- second item
- third item
- fourth item
- fifth item
'''
from parsel import Selector
selector = Selector(text=html) # 将 HTML 字符串,赋值为 selector 变量
# print(selector)
# 提取 class 包含 item-0 的节点
# css方法
items = selector.css('.item-0')
print(len(items), type(items), items) # 结果是一个可迭代对象 SelectorList
# xpath方法
items2 = selector.xpath('//li[contains(@class, "item-0")]')
print(len(items2), type(items2), items2)
知识点:
- 将 HTML 字符串,赋值为 selector 变量:selector = Selector(text=html)。
- css方法提取 class 包含 item-0 的节点:selector.css(‘.item-0’)。
- xpath方法提取 class 包含 item-0 的节点:selector.xpath(‘//li[contains(@class, “item-0”)]’)。
- 两种方法返回的结果都是一个可迭代对象 SelectorList,长度都为3,具体结果看输出。
结果输出为:
3 <class 'parsel.selector.SelectorList'> [<Selector xpath="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='first item \n ...'>, <Selector xpath="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='> , <Selector xpath="descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' item-0 ')]" data='> ]
3 <class 'parsel.selector.SelectorList'> [<Selector xpath='//li[contains(@class, "item-0")]' data='first item \n ...'>, <Selector xpath='//li[contains(@class, "item-0")]' data='> , <Selector xpath='//li[contains(@class, "item-0")]' data='> ]
for item in items:
text = item.xpath('.//text()').get() # 仍是一个可迭代对象 SelectorList
print(text)
知识点:
遍历 items , 利用xpah 提取所有 li 节点的文本内容:text = item.xpath(‘.//text()’).get() ,结果如下。
结果输出为:
first item
third item
fifth item
# 提取 SelectorList 里面对应的结果,可以使用 get 或 getall 方法
# xpath 方法
result = selector.xpath('//li[contains(@class, "item-0")]//text()').get()
print(result)
result = selector.xpath('//li[contains(@class, "item-0")]//text()').getall()
print(result)
# css 方法
result = selector.css('.item-0 *::text').get() # *用来提取第一个子节点
print(result)
result = selector.css('.item-0 *::text').getall() # *用来提取所有子节点
print(result)
知识点:
get 和 getall 对于xpath和css都通用。
get() :用来提取第一个子节点
getall() :用来提取所有子节点
结果输出为:
first item
['first item', 'third item', 'fifth item']
first item
['first item', 'third item', 'fifth item']
# 提取属性########################################
result = selector.css('.item-0.active a::attr(href)').get()
print(result)
result = selector.xpath('//li[contains(@class, "item-0") and contains(@class, "active")]/a/@href').get()
print(result)
result = selector.css('.item-0').re('link.*')
# re 方法在这里遍历了所有提取到的 Selector 对象,然后根据传入的正则表达式查找出符合规则的节点源码并以列表的形式返回。
print(result)
result = selector.css('.item-0 *::text').re('.*item')
# 调用 css 方法时已经提取了进一步的结果,比如提取了节点文本值,那么 re 方法就只会针对节点文本值进行提取
print(result)
result = selector.css('.item-0').re_first('(.*?)') # 输出的结果就是小括号部分对应的结果
print(result)
结果输出为:
link3.html
link3.html
['link2.html">second item', 'link3.html">third item', 'link4.html">fourth item', 'link5.html">fifth item', 'link3.html">third item', 'link4.html">fourth item', 'link5.html">fifth item', 'link5.html">fifth item']
['first item', 'third item', 'fifth item']
third item