pyquery 的使用

安装: pip install pyquery

字符串初始化

html = '''
<div>
    <ul>
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li'))

<li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>

这里首先引入 PyQuery 这个对象, 取别名为 pq 。 然后声明一个长 HTML 字符串,并将其当作参数传给 PyQuery 类, 这样就成功的完成了初始化。 接着将初始化的对象传给 CSS 选择器。 在这个 例子中 我们传入了 li  这样就选择了所有 li 节点。

URL 初始化

初始化的参数除了能以字符串形式传递, 还能以网页的URL , 此时只需要指定 PyQuery 对象的参数为 url 即可

from pyquery import PyQuery as pq
doc = pq(url='https://cuiqingcai.com')
print(doc('title'))

<title>静觅丨崔庆才的个人站点 - Python爬虫教程</title>

这样的话, PyQuery 对象会首先请求这个URL , 然后用的到的HTML 内容完成初始化, 其实就相当于把网页的源代码以字符串形式传递给PyQuery 类, 来完成初始化操作

类似于这段代码

from pyquery import PyQuery as pq
import requests
doc = pq(requests.get('https://cuiqingcai.com').text)
print(doc('li'))

文件初始化

除了上面两种还可以传递本地文件名, 此时将参数指定为 filename 即可

from pyquery import PyQuery as pq
doc = pq(filename='demo.htm'))
print(doc('li'))

当然, 这里你需要有一个 本地的HTML 文件, 其内容时待解析 HTML 字符串。 

基本CSS选择器

简单使用

html = '''
<div id="container">
    <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))

<li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     
<class 'pyquery.pyquery.PyQuery'>

这里我们初始化 PyQuery 对象之后, 传入了一个CSS 选择器 #container .list li,  它的意思时先选取 id 为 container 的节点, 在选取其内部 class 为 list 的节点内部的所有 li 系欸但, 然后打印输出。从运行结果可以看到, 我们成功获取了符合条件的节点

最后我们将符合条件的节点的类型打印输出, 可以看到依然时 PyQuery 类型

下面我们遍历获取的节点, 然后调用 tex 方法, 就可以直接获取节点的文本内容

for item in doc('#container .list li').items():
    print(item.text())

for item in doc('#container .list li').items():

print(item.text())

first item
second item
third item
fourth item
fifth item

查找节点

子节点

查找子节点时, 需要用到 find 方法, 其参数是CSS 选择器, 我们这里还是以上面的HTML为例

from pyquery import PyQuery as pq 
doc = pq(html)
items = doc('.list')
print(type(items))
print(items)
lis = items.find('li')
print(type(lis))
print(lis)

from pyquery import PyQuery as pq

doc = pq(html)

items = doc('.list')

print(type(items))

print(items)

lis = items.find('li')

print(type(lis))

print(lis)

<class 'pyquery.pyquery.PyQuery'>
<ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 
<class 'pyquery.pyquery.PyQuery'>
<li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>

这里我们通过 .list 来选取 class 为 list 的节点, 然后调用 find 方法, 并给其传入 CSS 选择器, 选取内部的 li 节点, 最后打印输出。 可以发现, find 将所有符合条件的节点选择出来, 结果为 PyQuery 类型

其实 find 方法是查找范围内所有符合条件的子孙节点, 如果只查找子节点可以用 children 方法:

lis = items.children()
print(lis)

<li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>

如果要筛选符合条件的子节点,可以传入相应的参数即可

lis = items.children('.active')
print(lis)

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>

父节点

可以用 parent 方法获取某个节点的父节点

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
container = items.parent()
print(type(container))
print(container)

<class 'pyquery.pyquery.PyQuery'>
<div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 

这里我们首先用 .list 选取 class 为 list 的节点, 然后调用parent 方法得到其父节点, 其类型依然是 PyQuery 

这里的父节点是直接父节点,也就是说 parent 方法不会继续查找父节点的父节点, 即祖先节点。如果想要获取某个祖先节点 可以用 parents 方法

from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
parents = items.parents()
print(type(parents))
print(parents) 

<class 'pyquery.pyquery.PyQuery'>
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div><div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>

可以看到输出结果由两个: 一个是 class 为 wrap 的节点, 一个是 id 为 container 的你节点,也就是说, parents 方法会返回所有祖先节点。

如果想要某个祖先节点, 可以向parents 方法传入CSS 选择器, 这样就会返回祖先节点中某个符合调节的节点

parents = items.parents('.wrap')
print(parents)

<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>

可以看到结果只保留了 一个 class 为 wrap 的节点

兄弟节点

siblings 方法, 以上面HTML文本为例

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings())

<li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0">first item</li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>

这里首先选择 class 为 list 的节点内部的 class 为 item-0 和 active 的节点, 也就是第三个 li 节点,那么很明显,其兄弟节点有 4 个, 分别是 第 一, 二, 四, 五个节点

如果要筛选某个节点,依然可以传入CSS选择器

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))

<li class="item-1 active"><a href="link4.html">fourth item</a></li>

遍历节点

可以看到 pyquery 库选择结果可能是单个节点,也可能是多个节点。

如果是单个节点,直接输出即可

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(str(li))

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>

如果是多个节点,就需要遍历

from pyquery import PyQuery as pq
doc = pq(html)
lis = doc('li').items()
print(type(lis))
for li in lis:
    print(li, type(li))

<class 'generator'>
<li class="item-0">first item</li>
              <class 'pyquery.pyquery.PyQuery'>
<li class="item-1"><a href="link2.html">second item</a></li>
              <class 'pyquery.pyquery.PyQuery'>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
              <class 'pyquery.pyquery.PyQuery'>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
              <class 'pyquery.pyquery.PyQuery'>
<li class="item-0"><a href="link5.html">fifth item</a></li>
          <class 'pyquery.pyquery.PyQuery'>

可以发现, 调用 items 方法后, 会得到一个生成器, 对其进行遍历, 就可以逐个得到 li 节点对象了, 它的类型也是 PyQuery 

获取属性

获取到某个节点 PyQuery 类型的节点后, 可以调用 attr 方法获取其属性

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a, type(a))
print(a.attr('href'))

<a href="link3.html"><span class="bold">third item</span></a> <class 'pyquery.pyquery.PyQuery'>
link3.html

这里首先选中 class 为 item-0 和 active 的 li 节点内的 a 节点, 其类型是 PyQuery 

然后调用 attr 方法, 在这个方法中传入属性名称, 就可得到相应的属性值了

此外也可以调用 attr 属性来获取属性值

print(a.attr.href)

link3.html

如果得到的是多个节点,然后调用 attr 方法

a = doc('a')
print(a, type(a))
print(a.attr('href'))
print(a.attr.href)

<a href="link2.html">second item</a><a href="link3.html"><span class="bold">third item</span></a><a href="link4.html">fourth item</a><a href="link5.html">fifth item</a> <class 'pyquery.pyquery.PyQuery'>
link2.html
link2.html

可以看出,我们得到了 4 个 a 节点, 调用 attr 方法之后,只得到了第一个节点的属性

如果想要得到所有 a 节点的属性,就需要遍历

from pyquery import PyQuery as pq
doc = pq(html)
a = doc('a')
for item in a.items():
    print(item.attr('href'))

link2.html
link3.html
link4.html
link5.html

可以看到,这里获取到了 4 个 a 节点里面的 href 属性值

获取文本

获取文本方法: text()

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active')
print(a)
print(a.text())

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             
third item

这里首先选中 a 节点, 然后调用 text 方法, 就可获取其内部的文本信息。 此时 text 方法会忽略节点内部包含的所有 HTML , 只返回纯文字内容

想要获取节点内部的 HTML 文本, 需要调用 html 方法

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(li.html())

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             
<a href="link3.html"><span class="bold">third item</span></a>

如果选中的是多个节点, text 和 html 方法返回的内容

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li')
print(li.html())
print(li.text())
print(type(li.text()))

<a href="link2.html">second item</a>
second item third item fourth item fifth item
<class 'str'>

结果有点不一样, html 方法返回的是第一个 li 节点内部的 HTML 文本, 而 text 返回了所有的 li 节点内部的纯文本, 各节点内容中间用一个空格分割开,即返回的结果是一个字符串

所有这个地方值得注意, 如果得到的结果是多个节点,并且向获取所有节点的内部 HTML 文本,就需要遍历这些节点

节点操作

pyquery 库提供了一系列方法对节点进行动态修改, 例如为某个节点添加一个 class , 移除某个节点等, 节点的操作方法有很多,这里举例几个

addClass 和 removeClass

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.removeClass('active')
print(li)
li.addClass('active')
print(li)

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             
<li class="item-0"><a href="link3.html"><span class="bold">third item</span></a></li>
             
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>

这里输出了三次: 第一次是原来的 li 节点, 带有 active 这个class , 第二次我们移除了 active 

第三次 我们添加了 active 

attr  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('changed item')
print(li)
li.html('<span>changed</span>')
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">changed item</li>

<li class="item-0 active" name="link"><span>changed</span></li>

这里我们首先选中 li 节点, 然后调用 attr 方法修改其属性, 该方法的第一个参数我属性名, 第二个参数为属性值, 接着,调用 text 和 html 方法改变 li 节点内部的内容。

可以发现调用 attr 方法后, li 节点多了一个 name 属性, 其值为 link 。接着调用 text 方法,传入文本后,li 内部的文本全部被改为传入的字符串文本了, 最后调用 html 方法, li 内部又变成了传入的 HTML 文本

注意点 : 这里的 text 和 html 方法 添加文本,都是替换原来的内容,不是追加

remove

移除

html = '''
<div class="wrap">
    Hello, World
    <p>This is a paragraph.</p>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
print(wrap.text())
wrap.find('p').remove()
print(wrap.text())

Hello, World
This is a paragraph.
Hello, World

这里我们想要获取到 wrap 中的 Hello World 文本, 而通过 text() 方法则获取所有 wrap 的内容,包括 p 节点中的, 这里可以从获取到的字符串中进行截取, 当然也可以使用 remove 方法,直接选中 p 节点,然后移除,这样我们获取到的文本就只有 Hello World 了

伪类选择器

html = '''
<div class="wrap">
    <div id="container">
        <ul class="list">
             <li class="item-0">first item</li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         </ul>
     </div>
 </div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li:first-child')
print(li)
li = doc('li:last-child')
print(li)
li = doc('li:gt(2)')
print(li)
li = doc('li:nth-child(2n)')
print(li)
li = doc('li:contains(second)')
print(li)

<li class="item-0">first item</li>
             
<li class="item-0"><a href="link5.html">fifth item</a></li>
         
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
             <li class="item-0"><a href="link5.html">fifth item</a></li>
         
<li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-1 active"><a href="link4.html">fourth item</a></li>
             
<li class="item-1"><a href="link2.html">second item</a></li>

这里我们使用了伪类选择器,依次选择了文本中的第一个 li 节点, 最后一个 li 节点, 第二个 li 节点, 第三个 li 节点之后的 li 节点, 偶数位置的 li 节点, 包含 second 文本的 li 节点

相关推荐

  1. pyquery 使用

    2024-07-21 13:36:04       19 阅读
  2. Python爬虫之pyquery和parsel使用

    2024-07-21 13:36:04       32 阅读
  3. Python爬虫 pyquery库详解

    2024-07-21 13:36:04       42 阅读
  4. ThreadLocal使用以及使用场景

    2024-07-21 13:36:04       17 阅读
  5. git使用

    2024-07-21 13:36:04       64 阅读
  6. websoket 使用

    2024-07-21 13:36:04       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 13:36:04       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 13:36:04       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 13:36:04       45 阅读
  4. Python语言-面向对象

    2024-07-21 13:36:04       55 阅读

热门阅读

  1. 本周你可能错过的 AI 新闻

    2024-07-21 13:36:04       19 阅读
  2. Python如何优雅地在Terminal打印下标

    2024-07-21 13:36:04       21 阅读
  3. linux的shell的date命令的加号“+“的作用

    2024-07-21 13:36:04       20 阅读
  4. 【Python大写字符串中每一个单词的首字母】

    2024-07-21 13:36:04       17 阅读
  5. 主页目录导航

    2024-07-21 13:36:04       20 阅读
  6. Mechanize:自动化Web交互的利器

    2024-07-21 13:36:04       19 阅读