pyquery:轻松、灵活的处理html

介绍

pyquery是一个专门用来解析html的库,从名字很容易想到jQuery,没错,这完全是仿照jQuery的语法实现的。如果用过jQuery,俺么pyquery很容易实现

初始化html

pyquery可以接收一个网址,自动下载内容,也可以接收已经下载好的字符串格式的html,当然也可以传入一个本地html文件。但是我们一般都会使用requests下载html页面,然后再将html页面以字符串的格式传进去

from pyquery import PyQuery


html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>古明地觉</title>
</head>
<body>
    <p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <div>
        <p class="s1">古明地恋</p>
    </div>
    <table >
        <tbody>
            <tr>
                <td>姓名:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr class="tr">
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="提交"></td>
            </tr>
        </tbody>
    </table>
    <a href="http://www.baidu.com" target="_blank">百度</a>
    <a href="http://www.yahoo.com">雅虎</a>
</body>
</html>   
'''

p = PyQuery(html)  # 此时得到的是一个pyquery对象
print(type(p))  # <class 'pyquery.pyquery.PyQuery'>

# 如果打印p的话,会直接将我们传入的html打印出来,只不过p的类型是PyQuery

使用选择器

from pyquery import PyQuery


html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>古明地觉</title>
</head>
<body>
    <p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <div>
        <p class="s1">古明地恋</p>
    </div>
    <table >
        <tbody>
            <tr>
                <td>姓名:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr class="tr">
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="提交"></td>
            </tr>
        </tbody>
    </table>
    <a href="http://www.baidu.com" target="_blank">百度</a>
    <a href="http://www.yahoo.com">雅虎</a>
</body>
</html>   
'''

p = PyQuery(html)
# 标签选择器
# 打印出标签为head的内容
print(p("head"))
"""
<head>
    <meta charset="UTF-8"/>
    <title>古明地觉</title>
</head>
"""
# 但是需要注意的是,这个打印出来的依旧是一个PyQuery类型
# 意味着我们可以进一步过滤,但是如果我想要字符串的话呢?直接调用str方法即可
print(str(p("head")))
"""
<head>
    <meta charset="UTF-8"/>
    <title>古明地觉</title>
</head>
"""
# 或者调用html方法,但是此时获取到的不包括相应的标签名
# head标签本身没了,只保留里面的内容,此时也是一个字符串的类型
print(p("head").html())
"""

    <meta charset="UTF-8"/>
    <title>古明地觉</title>

"""
# 但如果有很多标签,比如p标签,在调用html方法的时候,只会打印第一个p标签里面的内容
print(p("p"))
"""
<p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <p class="s1">古明地恋</p>
"""
print(p("p").html())
"""
<a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a>
"""

# 获取文本
print(p("head").text())
"""
古明地觉
"""
# 可以看到只获取了纯文本,因为只能title标签里面有文本,而title在head里面

# css选择器
# 获取id=bili的标签
print(p("#bili"))
"""
<p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>

"""

# 获取class=s1的标签
print(p(".s1"))
"""
<p class="s1">my name is satori</p>
    <p class="s1">古明地恋</p>
"""

# 获取tbody下的class=tr的标签下的所有td标签
print(p("tbody .tr td"))
"""
<td>密码:</td>
                <td><input type="password" name="password"/></td>
            
"""
# 可以看到这和jQuery的语法基本上是一致的
# 如果我只想获取第一个的话,索引要是越界的话,也不会报错,会打印空行
print(p("tbody .tr td").eq(0))
"""
<td>密码:</td>
"""

# 常用方法:
'''
p(".color"):获取class=color的标签
p("#color"):获取id=color的标签
p("*"):获取所有的标签
p("p"):获取所有的p标签
p("div,p"):获取所有的div标签和p标签
p("div p"):获取所有div标签内部的p标签
p("[target]"):选择带有target属性的所有元素
p("[target=_blank]"):选择带有target=_blank的所有元素
'''

filter和find

from pyquery import PyQuery


html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>古明地觉</title>
</head>
<body>
    <p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <div>
        <p class="s1">古明地恋</p>
    </div>
    <table >
        <tbody>
            <tr>
                <td>姓名:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr class="tr">
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="提交"></td>
            </tr>
        </tbody>
    </table>
    <a href="http://www.baidu.com" target="_blank">百度</a>
    <a href="http://www.yahoo.com">雅虎</a>
</body>
</html>   
'''

p = PyQuery(html)

print(p("p"))  # 这是所有的p标签
"""
<p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <p class="s1">古明地恋</p>
    
"""

# 我只要class=s1的p标签,可以使用filter过滤
print(p("p").filter(".s1"))  # 表示在找到的p标签中,过滤出class=s1的p标签
"""
<p class="s1">my name is satori</p>
    <p class="s1">古明地恋</p>
    
"""

# 如果要按照文本过滤呢?比如我想找出文本内容等于'古明地恋'的p标签
print(p("p").filter(lambda _, this: PyQuery(this).text() == '古明地恋'))
"""
<p class="s1">古明地恋</p>
    
"""

# find
# 首先filter是过滤得到符合条件的标签
# 而find是在符合条件的标签里面找
# 举个例子
"""
p("p").filter(".fuck")表示的是有很多的p标签,我在选出的这么多p标签中,找到class=fuck的p标签
p("p").find(".fuck")表示的是有很多的p标签,我在选出的这么多p标签中,找到其内部满足class=fuck的其他标签
"""
print(p("div").filter(".s1"))
"""

"""
print(p("div").find(".s1"))
"""
<p class="s1">古明地恋</p>
    
"""
# 可以看到p("div").filter(".s1")是空的,因为这表示在选出来的div标签中,找出class=s1的div
# 而p("div").find(".s1")表示找到div里面满足class=s1的其他标签

# filter和find可以无限使用的,因为返回的都是一个PyQuery类型
# p("div p .cls li a") == p("div").find("p").find(".cls").find("li").find("a")

获取属性

from pyquery import PyQuery


html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>古明地觉</title>
</head>
<body>
    <p id="bili"><a href="http://www.bilibili.com">想进入基佬的大门吗?还等什么,快点击吧</a></p>
    <p class="s1">my name is satori</p>
    <div>
        <p class="s1">古明地恋</p>
    </div>
    <table >
        <tbody>
            <tr>
                <td>姓名:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr class="tr">
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="提交"></td>
            </tr>
        </tbody>
    </table>
    <a href="http://www.baidu.com" target="_blank">百度</a>
    <a href="http://www.yahoo.com">雅虎</a>
</body>
</html>   
'''

p = PyQuery(html)

a_tag = p("a")
print(a_tag.attr("href"))  # http://www.bilibili.com

"""
可以直接调用attr方法,传入要获取的属性值即可。
但是注意到即便满足条件的标签有多个,和html一样,调用attr获取的时候只会得到第一个
"""
# 因此可以使用eq
print(p("a").eq(0).attr("href"))  # http://www.bilibili.com
print(p("a").eq(1).attr("href"))  # http://www.baidu.com

# 但是还有一个问题,就是我们不知道获得了几个p标签
# 难道要一个一个的数吗?
# 当然不用,一种笨的方法,就是我不断的循环,如果没有内容了就break
# 但是PyQuery内部给我们提供了一个items方法,可以自动的迭代,如果迭代完毕自动退出。
for i in p("a").items():
    print(i.attr("href"))
"""
http://www.baidu.com
http://www.yahoo.com
"""
上一篇:使用pyquery


下一篇:Lambdify与Python一起使用,但是在Cython中引发异常