对于规则的网页信息我们可以使用的解析库和选择器很多比如bs4,xpath 等,这里我们介绍一种css选择器功能非常强大的库--pyquery
安装
pip3 install pyquery
使用
环境python3
初始化
# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq
html='''
<div class="qrcodeCon">
<div id="qrcode">
<div class="qrcode-item qrcode-item-1">
<div class="qrcode-img"></div>
<div class="qrcode-text">
<p><b>百度</b></p>
</div>
</div>
</div>
</div>
'''
doc = pd(html) # 这里doc就是一个pyquery对象我们可以对其进行选择器操作,这就是初始化
print(doc('a')) # 这里就可以对节点下所有的子孙节点的查找a标签
# 此外还支持url初始化,以及文件初始化
doc = pd(url = 'https://www.baidu.com') # url初始化
print(doc('title'))
doc = pd(filename='test.html') # 文件初始化
print(doc('title'))
基本选择器
还是以上面的文本内容为例:
from pyquery import PyQuery as pq
html = '''
<div class="qrcodeCon">
<div id="qrcode">
<div class="qrcode-item qrcode-item-1">
<div class="qrcode-img"></div>
<div class="qrcode-text">
<p><b>百度</b></p>
<a>hello world</a>
</div>
</div>
</div>
</div>
'''
doc = pq(html)
print(doc('.qrcodeCon .qrcode-text').text())
从上面的例子中我们可以看到pyquery的css选择器的用法很简单,给pq对象传入一个查找参数就可以了, # 表示id, . 表示类 下一级就空格一下,这样就可以轻松的定位到我们需要的节点了.
查找节点
pyquery 查找子节点的时候可以使用上面我们说的方法也可以使用一下方法:
- 子节点
查找子节点的时候,需要用到find()方法,此时传入的参数是css选择器,同样的以上面的文档为例,
# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq
html = '''
<div class="qrcodeCon">
<div id="qrcode">
<div class="qrcode-item qrcode-item-1">
<div class="qrcode-img"></div>
<div class="qrcode-text">
<p><b>百度</b></p>
<a>hello world</a>
<a>hello world</a>
</div>
</div>
</div>
</div>
'''
doc = pq(html)
first = doc('.qrcodeCon')
second = doc.find('.qrcode-text a')
third = doc('.qrcode-text a')
print(second)
print(third)
两个结果是一样的
<a>hello world</a>
<a>hello world</a>
<a>hello world</a>
<a>hello world</a>
另外find()所选的css选择器选择的是所有的子孙节点,如果我们只想找子节点那么可以使用 children() 方法来查找,使用方法和find()方法是一样的,对pyquery对象传入css选择句就可以得到我们想要的结果了.
- 父节点
我们可以使用parent()的方法来获取某个节点的父节点,我们可以给其传入css查询语句来进行特定的查询.使用方法和children()方法一样,这里是该节点的直接父节点,不会再去查找该节点的祖先节点 - 祖先节点
和父节点一样,我们使用parents()来实现祖先借点的查找,同样的我们可以往里面传入css选择器参数查找我们需要的祖先节点 - 兄弟节点
使用siblings()方法来获取兄弟节点,同样的我们可以给它传入css选择参数来获取我们需要的节点
遍历
我们查到的对象不是想bs4那样返回一个列表,对于单个节点来说我们可以直接转成字符串使用str(doc('.li'))* 方法即可,对于多个节点,我们就需要使用遍历来获取内容了---.items() 方法
对于我们选择的多个内容我们可以:
doc = pq('html')
list_cont = doc('li').items() # 这里会得到一个生成器
for i in list_cont:
print(i)
获取信息
- 获取属性
直接调用.attr() 方法可以获取属性
doc.attr('href') # 类似这样的就可以获取他的herf属性了
我们也可以直接调用.attr属性来获取属性,例如
doc.attr.href
这两种方法获取到的内容是一样的
如果选中的是多个元素,我们调用attr()方法的时候就只会得到第一个节点的属性,这点可以自己去验证一下.当我们遇到这样的情况的时候就要使用遍历了也就是前面说的使用.items()来进行遍历操作.
- 获取文本
调用.text()方法可以获取选中节点里的所有文本的内容,它会忽略掉节点内部包含的所有HTML,值返回纯文字.
但是如果想获取节点内部的HTML文本就要使用html()方法了.
对于 html()方法返回的是第一个节点内部的HTML文本,而text()则返回了所有的节点内部的纯文本. 中间用一个空格隔开,也就是说结果返回的是一个字符串
这个地方需要注意的是,如果结果是多个节点,并且想要获取每个节点内部的HTMl文本呢,那么就需要遍历每个节点,或者是使用text()方法来直接组合成一个字符串来获取.
节点操作 - addClass 和 removeClass 对class属性进行增减,具体是选中节点pyquery对象,然后进行修改
doc.removeClass('example') # 我们给这个节点移除了example类属性
doc.addClass('example') # 这里我们给这个节点增加了exmaple属性.
- addr text 和 html
我们可以使用一下形式直接更改节点里面的内容:
html = '''
<ul class="list">
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
</ul>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.attr('name','link') # 这里可以直接给节点添加一个属性
print(li)
li.text('change the world') # 这里直接更改了节点的内容
print(li)
li.html("<span>change item</span>") # 这里修改了节点了的HTML内容
print(li)
输出结果如下:
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link">change the world</li>
<li class="item-0 active" name="link"><span>change item</span></li>
在我们调用了attr()方法之后,li节点多了一个name属性,值为link,然后使用text方法传入文本改变了内部的文本信息,最后调用了html()方法来改变了节点的html的值
所以,如果attr()方法只传入一个参数那么就是获取这个节点的属性值,如果传入第二个参数那么是可以修改这个参数的值的. 对于text()和html()方法,如果不传入参数就是获取内部的纯文本信息和HTML文本,如果传入参数就进行赋值修改
- remove
可以直接操作节点进行移除操作
伪类选择器
伪类选择器功能很强大具体参看w3School来查看更多的详情,这里我直接搬运过来了.
一个普通标题 | 一个普通标题 | 一个普通标题 | |
---|---|---|---|
选择器 | 例子 | 例子描述 | CSS |
.class | .intro | 选择 class="intro" 的所有元素。 | 1 |
#id | #firstname | 选择 id="firstname" 的所有元素。 | 1 |
* | * | 选择所有元素。 | 2 |
element | p | 选择所有 <p> 元素。 | 1 |
element,element | div,p | 选择所有 <div> 元素和所有 <p> 元素。 | 1 |
element element | div p | 选择 <div> 元素内部的所有 <p> 元素。 | 1 |
element>element | div>p | 选择父元素为 <div> 元素的所有 <p> 元素。 | 2 |
element+element | div+p | 选择紧接在 <div> 元素之后的所有 <p> 元素。 | 2 |
[attribute] | [target] | 选择带有 target 属性所有元素。 | 2 |
[attribute=value] | [target=_blank] | 选择 target="_blank" 的所有元素。 | 2 |
[attribute~=value] | [title~=flower] | 选择 title 属性包含单词 "flower" 的所有元素。 | 2 |
:link | a:link | 选择所有未被访问的链接。 | 1 |
:visited | a:visited | 选择所有已被访问的链接。 | 1 |
:active | a:active | 选择活动链接。 | 1 |
:hover | a:hover | 选择鼠标指针位于其上的链接。 | 1 |
:focus | input:focus | 选择获得焦点的 input 元素。 | 2 |
:first-letter | p:first-letter | 选择每个 <p> 元素的首字母。 | 1 |
:first-line | p:first-line | 选择每个 <p> 元素的首行。 | 1 |
:first-child | p:first-child | 选择属于父元素的第一个子元素的每个 <p> 元素。 | 2 |
:before | p:before | 在每个 <p> 元素的内容之前插入内容。 | 2 |
:after | p:after | 在每个 <p> 元素的内容之后插入内容。 | 2 |
:lang(language) | p:lang(it) | 选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。 | 2 |
element1~element2 | p~ul | 选择前面有 <p> 元素的每个 <ul> 元素。 | 3 |
[attribute^=value] | a[src^="https"] | 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 | 3 |
[attribute=value*] | a[src*="abc"] | 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 | 3 |
:first-of-type | p:first-of-type | 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 | 3 |
:last-of-type | p:last-of-type | 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 | 3 |
:only-of-type | p:only-of-type | 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 | 3 |
:only-child | p:only-child | 选择属于其父元素的唯一子元素的每个 <p> 元素。 | 3 |
:nth-child(n) | p:nth-child(2) | 选择属于其父元素的第二个子元素的每个 <p> 元素。 | 3 |
:nth-last-child(n) | p:nth-last-child(2) | 同上,从最后一个子元素开始计数。 | 3 |
:nth-of-type(n) | p:nth-of-type(2) | 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 | 3 |
:nth-last-of-type(n) | p:nth-last-of-type(2) | 同上,但是从最后一个子元素开始计数。 | 3 |
:last-child | p:last-child | 选择属于其父元素最后一个子元素每个 <p> 元素。 | 3 |
:root | :root | 选择文档的根元素。 | 3 |
:empty | p:empty | 选择没有子元素的每个 <p> 元素(包括文本节点)。 | 3 |
:target | #news:target | 选择当前活动的 #news 元素。 | 3 |
:enabled | input:enabled | 选择每个启用的 <input> 元素。 | 3 |
:disabled | input:disabled | 选择每个禁用的 <input> 元素 | 3 |
:checked | input:checked | 选择每个被选中的 <input> 元素。 | 3 |
:not(selector) | :not(p) | 选择非 <p> 元素的每个元素。 | 3 |
::selection | ::selection | 选择被用户选取的元素部分。 | 3 |
到这里就结束了,这里只是简单的介绍,更详细的需要查看官方文档,下一篇我们来做一个简单的爬取淘宝商品的小项目.
网友评论