Parsel --- 爬虫页面解析利器

Parsel — 爬虫页面解析利器


[声明] :本文并非原创,但是文章的来源地址未找到

parsel 是 scrapy 出品的,也是 scrapy 内置的选择器,包含 re、css、xpath 选择器,可从 HTML 和 XML 中提取和删除数据,使用该库能使代码简洁。

1 安装

pip install parsel or easy_install parsel

2 用法

2.1 用需要解析的 HTML 或 XML 创建 Selector

from parsel import Selector
text = """
<html>
    <body>
    	<h1>Hello, Parsel!</h1>
        <div>
          <ul>
             <li class="item-0">
             	<a href="link1.html">first item</a>
             </li>
             <li class="item-1">
             	<a href="link2.html">second item</a>
             </li>
             <li class="item-inactive">
             	<a href="link3.html">third item</a>
             </li>
             <li class="item-1">
             	<a href="link4.html">fourth item</a>
             </li>
             <li class="item-0">
             	<a href="link5.html">fifth item</a>
             </li>
          </ul>
 		</div>
    </body>
</html>
"""
selector = Selector(text=text) # python2 text must be a unicode string.

2.2 然后使用 CSS 或 Xpath 表达式提取需要的信息

selector.css('h1::text')
# [<Selector xpath='descendant-or-self::h1/text()' data='Hello, Parsel!'>]
selector.css('h1::text').get()
# 'Hello, Parsel!'
selector.xpath('//h1/text()').getall()
# ['Hello, Parsel!']
# 可结合正则
selector.xpath('//h1/text()').re_first(r'(H\w+)lo')
# Hel
selector.xpath('//h1/text()').re(r'H(\w+)lo, Par(\w+el)')
# ['el', 'sel']
# 支持 xpath 的 re EXSLT 扩展
selector.xpath(r'//li[re:test(@class, "item-\d$")]//@href').getall()
# selector.xpath('//li/a/@href').getall()
# ['link1.html', 'link2.html', 'link4.html', 'link5.html']

3 CSS 语法

3.1 通用选择器(Universal selector)

语法:*

说明:* 将匹配文档的所有元素。

示例:div/* 将匹配<div>节点内的所有子节点元素。

from parsel import Selector
text = """
<div class="table">
  <plate />
  <plate />
</div>
"""
selector = Selector(text=text)
selector.css('div/*').getall()
# ['<div class="table">\n  <plate></plate>\n  <plate></plate>\n</div>']

3.2 类型选择器(Type selector)

语法:elementname

示例:plate 匹配所有 <plate> 元素。

from parsel import Selector
text = """
<div class="table">
  <plate />
  <bento />
  <plate />
</div>
"""
selector = Selector(text=text)
selector.css('plate').getall()
# ['<plate></plate>', '<plate></plate>']

3.3 类选择器(Class selector)

语法.classname

示例.small 匹配任何 class 属性中含有 “small” 类的元素。

from parsel import Selector
text = """
<div class="table">
  <apple />
	<apple class="small" />
	<plate>
		<apple class="small" />
	</plate>
<plate />

</div>
"""
selector = Selector(text=text)
selector.css('.small').getall()
# ['<apple class="small"></apple>', '<apple class="small"></apple>']

3.4 ID 选择器(ID selector)

语法:#idname

示例:#fancy 匹配 id 为 “fancy” 的元素。

from parsel import Selector
text = """
<div class="table">
  <plate id="fancy" />
  <plate />
  <bento />
</div>
"""
selector = Selector(text=text)
selector.css('#fancy').getall()
# ['<plate id="fancy"></plate>']

3.5 属性选择器(Attribute selector)

语法:[attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]

示例效果
p[attr]选择带有 attr 属性所有 p 元素。
p[attr=value]选择带有 attr 属性为 “value” 的所有 p 元素。
p[attr~=value]选择 attr 属性包含单词 “value” 的所有 p 元素。
p[attr^=value]选择其 attr 属性值以 “value” 开头的每个 p 元素。
p[attr$=value]选择其 attr 属性值以 “value” 结尾的每个 p 元素。
p[attr*=value]选择其 attr 属性中包含 “value” 子串的每个 p 元素。
from parsel import Selector
text = """
<div class="table">
  <apple class="small" />
  <bento for="Hayato">
  	<pickle />
  </bento>
  <apple for="Ryota" />
  <plate for="Minato">
  	<orange />
  </plate>
  <pickle class="small" />
</div>
"""
selector = Selector(text=text)
selector.css('[for$="o"]').getall()
# ['<bento for="Hayato">\n  \t<pickle></pickle>\n  </bento>', '<plate for="Minato">\n  \t<orange></orange>\n  </plate>']

3.6 选择器列表(Selector list)

说明, 是将不同的选择器组合在一起的方法,它选择所有能被列表中的任意一个选择器选中的节点。

语法element1,element2

示例plate,bento 会同时匹配 <plate><bento> 元素。

from parsel import Selector
text = """
<div class="table">
  <pickle class="small" />
  <pickle />
  <plate>
 		<pickle />
  </plate>
  <bento>
  	<pickle />
  </bento>
  <plate>
  	<pickle />
  </plate>
  <pickle />
  <pickle class="small" />
</div>
"""
selector = Selector(text=text)
selector.css('plate,bento').getall()
# ['<plate>\n \t\t<pickle></pickle>\n  </plate>', '<bento>\n  \t<pickle></pickle>\n  </bento>', '<plate>\n  \t<pickle></pickle>\n  </plate>']

3.7 后代组合器(Descendant combinator)

语法:element1 element2

说明(空格) 是组合器选择前一个元素的后代节点,匹配所有位于任意 element1 元素之内的 element2 元素 。

from parsel import Selector
text = """
<div class="table">
  <bento />
  <plate>
  	<apple />
  </plate>
  <apple />
</div>
"""
selector = Selector(text=text)
selector.css('plate apple').getall()
# ['<apple></apple>']

3.8 直接子代组合器(Child combinator)

语法element1>element2

说明> 是组合器选择前一个元素的直接后代节点,匹配直接镶嵌在 element1 元素之内的所有 element2 元素 。

from parsel import Selector
text = """
<div class="table">
  <plate>
		<bento>
			<apple />
		</bento>
	</plate>
	<plate>
		<apple />
	</plate>
	<plate />
	<apple />
	<apple class="small" />
</div>
"""
selector = Selector(text=text)
selector.css('plate>apple').getall()
# ['<apple></apple>']

3.9 一般兄弟组合器(General sibling combinator)

语法element1~element2

说明~ 后一个节点在前一个节点后面的任意位置,并且共享同一个父节点。element1~element2 匹配同一父元素下,element1 元素后的所有 element2 元素。

from parsel import Selector
text = """
<div class="table">
    <pickle />
    <bento>
    	<orange class="small" />
    </bento>
    <pickle class="small" />
    <pickle />
    <plate>
    	<pickle />
    </plate>
    <plate>
    	<pickle class="small" />
    </plate>
</div>
"""
selector = Selector(text=text)
selector.css('pickle~pickle').getall()
# ['<pickle class="small"></pickle>', '<pickle></pickle>']

3.10 紧邻兄弟组合器(Adjacent sibling combinator)

语法:element1+element2

说明+ 后一个元素紧跟在前一个之后,并且共享同一个父节点。element1+element2 匹配所有紧邻在 element1 元素后的 element2 元素。

from parsel import Selector
text = """
<div class="table">
    <bento>
    	<apple class="small" />
    </bento>
    <plate />
    <apple class="small" />
    <plate />
    <apple />
    <apple class="small" />
    <apple class="small" />
</div>
"""
selector = Selector(text=text)
selector.css('plate+apple').getall()
# ['<apple class="small"></apple>', '<apple></apple>']

3.11 伪选择器(Pseudo)

a 伪类
: 伪选择器支持按照未被包含在文档树中的状态信息来选择元素。
语法::first-child
示例p:first-child 选择属于父元素的第一个子元素的每个

元素。

语法::nth-child(n)
示例p:nth-child(2) 选择属于其父元素的第二个子元素的每个

元素。

语法::nth-of-type(n)
示例p:nth-of-type(2) 选择属于其父元素第二个

元素的每个

元素。

语法::not(selector)
示例:not(p) 选择非

元素的每个元素。

b 伪元素
:: 伪选择器用于表示无法用 HTML 语义表达的实体。

示例:p::first-line 匹配所有 <p> 元素的第一行。

3.12 趣味练习

![截屏2020-07-07 10.33.05.png](https://img-blog.csdnimg.cn/img_convert/bb2205fc525ea28b76954c97078ae2e0.png#align=left&display=inline&height=493&margin=[object Object]&name=截屏2020-07-07 10.33.05.png&originHeight=1446&originWidth=1970&size=298670&status=done&style=none&width=672)
http://flukeout.github.io/

4 Xpath 语法

XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

<?xml version="1.0" encoding="UTF-8"?>
 
<bookstore>
 
<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>
 
<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>
 
</bookstore>

4.1 选择节点

表达式描述
/从根节点选取
//任意节点
.选取当前节点
选取当前节点的父节点
.//匹配某节点下的所有
@选取属性
nodename选取此节点的所有子节点
路径表达式效果
/bookstore选取根元素 bookstore
//book选取所有 book 子元素
bookstore选取 bookstore 元素的所有子节点
bookstore/book选取属于 bookstore 的子元素的所有 book 元素
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
//@href选取名为 href 的所有属性值

4.2 谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点,谓语被嵌在方括号中。

路径表达式效果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()❤️]选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素
//title[@lang=‘eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
/bookstore/book[price>35.00]//title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00

4.3 多路径选取

通过在路径表达式中使用 | 运算符,您可以选取若干个路径。

路径表达式效果
//book/title | //book/price选取 book 元素的所有 title 和 price 元素
//title | //price选取文档中的所有 title 和 price 元素
/bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素

4.4 其他

路径表达式效果
//input[@type=‘text’ or @name=‘wd’]选取文档中所有 input 元素且其的属性 type 值为 text 或属性 name 值为 wd 的元素
//*[contains(@class, ‘ip’)]匹配文档中所有 class 属性值含有关键字 ip 的元素
//*[starts-with(@id, ‘xx’)]匹配文档中所有 id 属性值开始位置是关键字 xx 的元素
string(.)提取当前节点的所有子节点中的文本

参考资料:
1 [https://parsel.readthedocs.io/en/latest/index.html](https://parsel.readthedocs.io/en/latest/index.html)
2 [https://www.w3school.com.cn/cssref/css_selectors.asp](https://www.w3school.com.cn/cssref/css_selectors.asp)
2 [https://www.runoob.com/xpath/xpath-syntax.html](https://www.runoob.com/xpath/xpath-syntax.html)

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值