首页Python6.解析库——pyquer...

6.解析库——pyquery

1.pyquery概述:

PyQuery是一个类似于jQuery的解析网页工具,使用lxml操作xml和html文档,它的语法和jQuery很像。和XPATH,BeautifulSoup比起来,PyQuery更加灵活,提供增加节点的class信息,移除某个节点,提取文本信息等功能。

使用pip安装pyquery库。

pip install pyquery

一般采用如下方式引用:

from pyquery import PyQuery as pq

更多内容可以查看pyquery官方文档

2.初始化PyQuery对象:

pyqueryHTML文档的所有操作都需要PyQuery对象来完成,初始化PyQuery对象主要有三种方式,分别是通过网址、字符串和文件名创建。

2.1 URL初始化

首先引入PyQuery类,然后将要解析的URL网址当做参数传递给PyQuery类,这样就完成了初始化。再将初始化的对象传入CSS选择器。

from pyquery import PyQuery as pq

doc = pq(url='https://www.baidu.com' , encoding='utf-8')
print(type(doc))
print('---------')
print(doc)
print('---------')
print(doc('title'))

运行结果如下:

<class 'pyquery.pyquery.PyQuery'>
---------
<html> <head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><meta content="always" name="referrer"/><link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css"/><title>百度一下,你就知道</title></head> <body link="#0000cc"> <div id="wrapper"> <div id="head"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129"/> </div> <form id="form" name="f" action="//www.baidu.com/s" class="fm"> <input type="hidden" name="bdorz_come" value="1"/> <input type="hidden" name="ie" value="utf-8"/> <input type="hidden" name="f" value="8"/> <input type="hidden" name="rsv_bp" value="1"/> <input type="hidden" name="rsv_idx" value="1"/> <input type="hidden" name="tn" value="baidu"/><span class="bg s_ipt_wr"><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off" autofocus="autofocus"/></span><span class="bg s_btn_wr"><input type="submit" id="su" value="百度一下" class="bg s_btn" autofocus=""/></span> </form> </div> </div> <div id="u1"> <a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a> <a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a> <noscript> <a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');

                </script> <a href="//www.baidu.com/more/" name="tj_briicon" class="bri" style="display: block;">更多产品</a> </div> </div> </div> <div id="ftCon"> <div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a>  <a href="http://jianyi.baidu.com/" class="cp-feedback">意见反馈</a> 京ICP证030173号  <img src="//www.baidu.com/img/gs.gif"/> </p> </div> </div> </div> </body> </html>
---------
<title>百度一下,你就知道</title>

2.2 字符串初始化

直接将HTML内容当做初始化参数递给PyQuery类。

html_text = """
<div>
    <div>
        <a>
        The Dormouse's story
        <p>this is something</p>
        </a>
    </div>
</div>
"""

from pyquery import PyQuery as pq

doc = pq(html_text)
print(type(doc))
print('---------')
print(doc)
print('---------')
# 选择a节点
print(doc('a'))
print('---------')
# 选择p节点
print(doc('p'))

运行结果如下:

<class 'pyquery.pyquery.PyQuery'>
---------
<div>
    <div>
        <a>
        The Dormouse's story
        <p>this is something</p>
        </a>
    </div>
</div>
---------
<a>
        The Dormouse's story
        <p>this is something</p>
        </a>
    
---------
<p>this is something</p>

2.3 文件初始化

可以传递本地的文件,此时只需要使用参数filename指定本地文件。

from pyquery import PyQuery as pq

doc = pq(filename='index.html')
print(type(doc))
print('---------')
print(doc)
print('---------')
print(doc('a'))
print('---------')
print(doc('p'))

运行结果如下:

<class 'pyquery.pyquery.PyQuery'>
---------
<div>
    <div>
        <a>
        The Dormouse's story
        <p>this is something</p>
        </a>
    </div>
</div>
---------
<a>
        The Dormouse's story
        <p>this is something</p>
        </a>
    
---------
<p>this is something</p>

3.查找节点

以如下html为例:

html_text = """
<html>
    <head>
        <title>
        The Dormouse's story
        <p>this is something</p>
        </title>
    </head>
    <body>
        <div class="story" id="container">
            <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href='link1.html'><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href='link2.html'>BBB</a></li>
                <li class="item_3"><a href='link3.html'><span>CCC</span></a></li>
                <li class="item_4"><a href='link4.html'>DDD</a></li>
            </ul>
        </div>
    </body>
</html>
"""

3.1 子节点

  • children()方法

可以通过已经查找的节点,查找这个标签下的直接子节点,而不用从头开始查找。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul')

# 获取ul节点下的所有直接子节点
print(type(item.children()))
print('---------')
print(item.children())
print('---------')
# 通过传入CSS选择器的方式,筛选子节点
print(item.children('.item_two'))

运行结果如下:

<class 'pyquery.pyquery.PyQuery'>
---------
<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<li class="item_2 item_two"><a href="link2.html">BBB</a></li>
  • find()方法
from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul')

print(item.find('*'))
print('---------')
print(item.find('li'))
print('---------')
print(item.find('a'))
print(item.find('a').text())

运行结果如下:

<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <a href="link1.html"><span class="blod">AAA</span></a>
                <span class="blod">AAA</span><li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <a href="link2.html">BBB</a><li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <a href="link3.html"><span>CCC</span></a><span>CCC</span><li class="item_4"><a href="link4.html">DDD</a></li>
            <a href="link4.html">DDD</a>
---------
<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<a href="link1.html"><span class="blod">AAA</span></a>
                <a href="link2.html">BBB</a><a href="link3.html"><span>CCC</span></a><a href="link4.html">DDD</a>
AAA BBB CCC DDD

3.2 父节点

使用parent()方法获取某个节点的父节点。
使用parents()方法获取某个节点的祖先节点。
也可以通过传入CSS选择器的方式,筛选节点。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_active a')
print('当前选择的节点为:\n' , item)
print('---------')
print('当前节点的父节点为:\n' , item.parent())
print('---------')
print('当前节点的祖先节点为:\n' , item.parents())
print('---------')
print('class属性为story的祖先节点为:\n' , item.parents('.story'))

运行结果如下:

当前选择的节点为:
 <a href="link1.html"><span class="blod">AAA</span></a>
                
---------
当前节点的父节点为:
 <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                
---------
当前节点的祖先节点为:
 <html>
    <head>
        <title>
        The Dormouse's story
        <p>this is something</p>
        </title>
    </head>
    <body>
        <div class="story" id="container">
            <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        </div>
    </body>
</html><body>
        <div class="story" id="container">
            <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        </div>
    </body>
<div class="story" id="container">
            <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        </div>
    <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                
---------
class属性为story的祖先节点为:
 <div class="story" id="container">
            <ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        </div>
    

3.3 兄弟节点

使用siblings()方法获取某个节点的兄弟节点。
也可以通过传入CSS选择器的方式,筛选节点。

from pyquery import PyQuery as pq

# ------兄弟节点

doc = pq(html_text)
item = doc('ul .item_active')
print(item)
print('---------')
print(item.siblings())

运行结果如下:

<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                
---------
<li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>

4.获取信息:

选择到节点后,需要获取该节点所包含的信息,主要为节点属性、节点内部文本。

4.1 获取节点属性

  • 调用attr()方法获取节点属性
from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul')
print(item)
print('---------')
# 获取节点的name属性值
print(item.attr('name'))
print('---------')
# 获取节点的class属性值
print(item.attr('class'))
print('---------')
# 获取节点的id属性值
print(item.attr('id'))

运行结果如下:

<ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        
---------
elements
---------
list_elements ul_first
---------
list_eng
  • 调用attr属性获取节点属性

需要注意的是class在Python中是关键字,因此在获取节点class属性时需使用class_

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul')
print(item)
# 获取节点的name属性值
print(item.attr.name)
print('---------')
# 获取节点的class属性值
print(item.attr.class_)
print('---------')
# 获取节点的id属性值
print(item.attr.id)

运行结果如下:

<ul class="list_elements ul_first" id="list_eng" name="elements">
                <li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            </ul>
        
elements
---------
list_elements ul_first
---------
list_eng
  • 获取多个节点的属性

当返回结果包含多个节点时,调用attr方法,只返回第一个节点的属性值。如果要获取多个节点的属性值,需要使用遍历的方式获取。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('a')
print(item)
print('---------')
# 当返回结果包含多个节点时,调用attr方法,只返回第一个节点的属性值。
print(item.attr('href'))
print('---------')
# 如果要获取多个节点的属性值,需要使用遍历的方式获取。
for i in item.items():
    print(i.attr('href'))

运行结果如下:

<a href="link1.html"><span class="blod">AAA</span></a>
                <a href="link2.html">BBB</a><a href="link3.html"><span>CCC</span></a><a href="link4.html">DDD</a>
---------
link1.html
---------
link1.html
link2.html
link3.html
link4.html

4.2 获取节点内部文本

  • 获取节点内部文本

调用text()方法获取节点内部文本,调用html()方法获取节点内部html文本。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_active')
print(item)
print('---------')
print(item.text())
print('---------')
print(item.html())

运行结果如下:

<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                
---------
AAA
---------

                    <a href="link1.html"><span class="blod">AAA</span></a>
  • 获取多个节点的文本

当返回结果包含多个节点时,text()方法返回的是内部所有节点的内部纯文本,各个节点文本内容由空格分隔。
html()方法返回的是第一个节点内部的html文本,如若获取所有节点的html文本,就需要遍历所以节点。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul li')
print(item)
print('---------')
print(item.text())
print('---------')
print(item.html())
print('---------')
for i in item.items():
    print(i.html())
    print('---------')

运行结果如下:

<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
AAA BBB CCC DDD
---------

                    <a href="link1.html"><span class="blod">AAA</span></a>
                
---------

                    <a href="link1.html"><span class="blod">AAA</span></a>
                
---------
<a href="link2.html">BBB</a>
---------
<a href="link3.html"><span>CCC</span></a>
---------
<a href="link4.html">DDD</a>
---------

5.节点操作:

5.1 增加删除节点class属性

调用remove_class()方法,删除节点的class属性。
调用add_class()方法,增加节点的class属性。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_2')
print(item)
print('---------')
item.remove_class('item_two')
print(item)
print('---------')
item.add_class('item_two')
print(item)

运行结果如下:

<li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                
---------
<li class="item_2"><a href="link2.html">BBB</a></li>
                
---------
<li class="item_2 item_two"><a href="link2.html">BBB</a></li>

5.2 修改节点属性

调用atrr()方法对节点属性进行操作。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_3')
print(item)
print('---------')
item.attr('name' , 'list_ccc')
print(item)
print('---------')
item.attr('id' , 'list_3')
print(item)

运行结果如下:

<li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                
---------
<li class="item_3" name="list_ccc"><a href="link3.html"><span>CCC</span></a></li>
                
---------
<li class="item_3" name="list_ccc" id="list_3"><a href="link3.html"><span>CCC</span></a></li>

5.3 修改节点文本

调用text()方法修改节点内部纯文本内容。
调用html()方法修改节点内部html文本内容。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_3')
print(item)
print('---------')
item.text('GGG')
print(item)
print('---------')
item.html('<p>GGG</p>')
print(item)

运行结果如下:

<li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                
---------
<li class="item_3">GGG</li>
                
---------
<li class="item_3"><p>GGG</p></li>

5.4 修改节点css

调用css()方法修改节点css内容。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('ul .item_3')
print(item)
print('---------')
item.css('font-size' , '24px')
print(item)

运行结果如下:

<li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                
---------
<li class="item_3" style="font-size: 24px"><a href="link3.html"><span>CCC</span></a></li>

5.4 删除节点

调用remove()方法删除节点。

from pyquery import PyQuery as pq

doc = pq(html_text)
item = doc('title')
print(item)
print('---------')
print(item.text())
print('---------')
item.find('p').remove()
print(item)
print('---------')
print(item.text())

运行结果如下:

<title>
        The Dormouse's story
        <p>this is something</p>
        </title>
    
---------
The Dormouse's story
this is something
---------
<title>
        The Dormouse's story
         
        </title>
    
---------
The Dormouse's story

6.伪类选择器:

CSS选择器之所以功能强大,是因为其包含了多种伪类选择器。

方法说明
:first-child获取第一个节点
:last-child获取最后一个节点
:nth-child(N)获取第N个节点,N=1,2,…
:nth-child(2n)获取偶数位置的全部节点
:nth-child(2n-1)获取奇数位置的全部节点
:gt(N)获取索引大于N的节点,N=0,1,…
:contains('str')获取文本包含”str”的节点
from pyquery import PyQuery as pq

doc = pq(html_text)
# 获取所有li节点
print(doc('li'))
print('---------')
# 获取第一个li节点
print(doc('li:first-child'))
print('---------')
# 获取最后一个li节点
print(doc('li:last-child'))
print('---------')
# 获取第二个li节点
print(doc('li:nth-child(2)'))
print('---------')
# 获取偶数位置上的li节点
print(doc('li:nth-child(2n)'))
print('---------')
# 获取奇数位置上的li节点
print(doc('li:nth-child(2n-1)'))
print('---------')
# 获取第二个li节点
print(doc('li:gt(1)'))
print('---------')
# 获取包含CCC文本的li节点
print(doc('li:contains(CCC)'))
print('---------')

运行结果如下:

<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                
---------
<li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                
---------
<li class="item_2 item_two"><a href="link2.html">BBB</a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<li class="item_1 item_active">
                    <a href="link1.html"><span class="blod">AAA</span></a>
                </li>
                <li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                
---------
<li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                <li class="item_4"><a href="link4.html">DDD</a></li>
            
---------
<li class="item_3"><a href="link3.html"><span>CCC</span></a></li>
                
---------
RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments