PyQuery库详解

  强大又灵活的网页解析库,如果你觉得正则写起来太麻烦,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法,那么PyQuery将是你绝佳的选择。
安装PyQuery

pip3 install pyquery

  安装很简单,没什么可说的。

用法详解

初始化

字符串初始化

  我们先看看怎么做的。

# -*- coding: UTF-8 -*-
import pyquery

html = '''
<div class="nav-items">
  <ul>
    <li    ><a href="https://book.douban.com/cart/"
     >购书单</a>
    </li>
    <li    ><a href="https://read.douban.com/ebooks/?dcs=book-nav&dcm=douban"
            target="_blank"
     >电子图书</a>
    </li>
    <li    ><a href="https://market.douban.com/book?utm_campaign=book_nav_freyr&utm_source=douban&utm_medium=pc_web"
     >豆瓣书店</a>
    </li>
    <li    ><a href="https://book.douban.com/annual/2019?source=navigation"
            target="_blank"
     >2019年度榜单</a>
    </li>
    <li    ><a href="https://m.douban.com/standbyme/annual2019?source=navigation"
            target="_blank"
     >2019书影音报告</a>
    </li>
    <li          class=" book-cart"
    ><a href="https://market.douban.com/cart/?biz_type=book&utm_campaign=book_nav_cart&utm_source=douban&utm_medium=pc_web"
            target="_blank"
     >购物车</a>
    </li>
  </ul>
</div>
'''
from pyquery import PyQuery as pq

doc = pq(html)
print(doc('li'))

  用from引入PyQuery这个类,然后用pq来简写,在官方文档都是用pq这种简写的方法写的。申明一个PyQuery对象,pq然后html把第一个参数穿进来,这样这个doc就是第一个对象了,然后用选择元素,比如选择了li标签,看看打印结果:
H40F.png
  这里的选择器也就是css选择器,如果要选择id的话就加#号,如果要加class前面要加点,如果选择标签名,那就什么就不加,跟上一节说的css选择器是一样的道理。

url初始化

  可以直接传一个链接进来,然后选择要的参数。

import pyquery
from pyquery import PyQuery as pq

doc = pq(url='http://www.baidu.com')
print(doc('head'))

  直接传入了一个链接,然后把doc当作一个对象,要head信息就打印,要p标签就打印,很无敌的存在。
HKnJ.png

文件初始化

  很好理解,刚才传了我们手动写的html代码。还有我们打开的链接,那么这次就是一个html或者htm文本文件:

import pyquery
from pyquery import PyQuery as pq

doc = pq(filename='dome.htm')
print(doc('p'))

  需要注意的是这个文件名字必须正确,文件最好是在你的这个python程序的同级目录下,或者你写绝对路径也可以。然后用法基本跟刚才一样,我们看看打印结果:
HYgA.png

基本CSS选择器

  这个CSS选择器就是刚才说了的那种id用#号代替,然后class前面加个点,其他的就用其他的呗,看看代码:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i></span>
<!--                      <i class="fontello fontello-search" id="icon-search"></i>-->
<!--                      <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>-->
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
print(doc('#search_submit .feathericons i'))

  注意看我打印时是怎么写的,首先是id=search_submit我写成了#search_submit,然后是class=feathericons我写成了.feathericons,接着有个i标签,我就写了个i,这样的意思就是打印出是id=search_submit,class=feathericons,里面有i标签的那一段,套娃一样,注意的是这里是要有空格隔开的哟。用空格就是有个嵌套关系。

查找元素

子元素

  我们现在看一下怎么获取到一个标签里面的子元素:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i></span>
<!--                      <i class="fontello fontello-search" id="icon-search"></i>-->
<!--                      <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>-->
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
items = doc('#search_submit')
print(type(items))
print(items)
lis = items.find('.feathericons')
print(type(lis))
print(lis)

  上面代码里面可以看到我们先用doc声明了一个pyquery的对象,然后items这个变量去找doc里面id(因为是id所以代码中是#号)为search_submit的标签,然后打印出items的类型和内容,接着写了一个lis的变量,里面用了find的方法,去查找刚才那个items对象中class为feathericons的标签,同时也打印出它的类型和内容:
Hush.png
  可以看到这个类型都是PyQuery的类型,然后find方法也只是找到了属于items的内容。逻辑是很清晰的。因为都是PyQuery的类型那么就可以层层嵌套了。

父元素

  获取父元素也就是用parent方法:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i></span>
<!--                      <i class="fontello fontello-search" id="icon-search"></i>-->
<!--                      <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>-->
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
items = doc('#spin-search')
par = items.parent()
print(type(par))
print(par)

  父元素这里只是获取了一个父类,找到了id为spin-search的标签,然后用par这个变量声明了items的父类。然后打印出类型也是PyQuery,内容也和我们预想的一致:
HEwk.png
  另外还有一个parents方法,就是查找所有的祖先节点:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i></span>
<!--                      <i class="fontello fontello-search" id="icon-search"></i>-->
<!--                      <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>-->
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
items = doc('#spin-search')
par = items.parents()
print(type(par))
print(par)

  这个就厉害了,基本上把所以的内容都给你打印出来了:
Hclo.png
  这个类型也是PyQuery,这个也是可以在括号里面加css选择器去选择的:

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i></span>
<!--                      <i class="fontello fontello-search" id="icon-search"></i>-->
<!--                      <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>-->
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
items = doc('#spin-search')
par = items.parents("#search_submit")
print(type(par))
print(par)

  看下上面选择的是id为search_submit的标签,那么打印出来的应该也就是符合id为search_submit的才对:
Hfui.png

兄弟元素

  有了父节点和子节点,那么兄弟节点是必不可少的,我们可以看看下面的代码:

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search">666</i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
i = doc('#spin-search .fontello.fontello-search')
print(i.siblings())

  上面的代码里面,我选择的是span里面的i标签,注意我在做css选择器的时候.fontello后面没有空格,又跟了一个.fontello-search,这里就表示这个class里面的fontello和fontello-search是并列的关系。然后用siblings方法,看看打印结果:
HTZv.png
  结果不出所料,两个兄弟标签都打印出来了。
  然后这个siblings里面也是可以写css选择器的。跟刚才的父元素那的道理是一样的。

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search">666</i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
i = doc('#spin-search .fontello.fontello-search')
print(i.siblings('.animate-spin'))

  这里我只要了class是animate-spin的兄弟,打印结果如图所示:
HvFe.png

遍历

单个元素

  如果我们查找了多个元素怎么遍历呢,先看看查找单个元素:

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search">666</i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
i = doc('.animate-spin.fontello.fontello-spinner.hide')
print(i)

  看打印结果,单个元素很好操作,方便对其嵌套之类的。
HVSy.png
  多个元素的话我们需要用items()方法来遍历,还要用for循环把他们都列举出来:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search">666</i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
i = doc('i')
lis = doc(i).items()
print(type(lis))
for i in lis:
    print(i)

  上面操作的打印结果可以看到用了items()方法之后,这个类型就变成了generator,然后用for循环来将所有的i标签打印出来,这样就变成了PyQuery类的数据了。方便做嵌套之类的操作。

获取信息

获取属性

  先看看如何获取:


import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search"><a href="https://www.baidu.com">33</a></i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
a = doc('.fontello.fontello-search a')
print(a)
print(a.attr('href'))
print(a.attr.href)

  这里用的attr()方法来提取里面的超链接。最后的打印方法两种都是一样的:
HW0c.png

获取文本

  我们这里不管文字被什么p标签呀,br标签呀之类的包含,我们直接用text来获取:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search"><a href="https://www.baidu.com">33</a></i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
print(doc)
print(doc.text())

  看一下我们的源码里面就写了个33,然后看看打印结果吧:
HkBl.png

获取HTML

  先看看代码是怎么写的:

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search"><a href="https://www.baidu.com">33</a></i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
l = doc('.fontello.fontello-search')
print(l.html())

  可以看到这个写法跟刚才一样,就是用了个html()方法而已。看看运行结果吧:
H0jH.png

DOM操作

addClass、removeClass操作

  我们看几个常用的操作:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search"><a href="https://www.baidu.com">33</a></i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq

doc = pq(html)
i = doc(".fontello.fontello-search")
print(i)
i.removeClass('fontello-search')
print(i)
i.add_class('fontello-search')
print(i)

  首先我们先打印了一次原来两个都带class的标签,然后我们用removeclass把fontello-search删除掉,打印观察,然后又用add_class加上:
HCsY.png

attr、css

  现在看看怎么修改属性和css,先看看下面这段代码:

import pyquery

html = '''<span id="search_submit" class="transparent input-group-btn">
                  <button  type="submit" class="transparent btn btn-sm">
                      <span class="feathericons" id="icon-search"><i data-feather="search"></i></span>
                      <span class="feathericons animate-spin  hide" id="spin-search"><i
                                  data-feather="loader"></i>
                     <i class="fontello fontello-search" id="icon-search"><a href="https://www.baidu.com">33</a></i>
                     <i class="animate-spin  fontello fontello-spinner hide" id="spin-search"></i>
                     </span>
                  </button>
              </span>'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.fontello.fontello-search')
print(li)
li.attr('name','link')
print(li)
li.css('color','red')
print(li)

  首先是打印了class里面含有fontello和fontello-search的标签,然后attr是指添加了属性,name是link的属性,这个是添加属性,而css里面则是直接定义css里面的信息,例如颜色或者字体大小等等。

remove

  现在看看remove的方法,这个是用的比较常用的:

import pyquery

doc = '''<div class="warp">
        Hello world
        <p>hello nihao  world</p>
        </div>'''
from pyquery import PyQuery as pq

hhh = pq(doc)
warp = hhh('.warp')
print(warp.text())
warp.find('p').remove()
print(warp.text())

  可以看到这个代码里面有一个div标签,我们如果打印的话就会把div和p标签里面的内容都打印出来,我们这时候就要用到remove方法来把p标签删除掉,所以当我们把p标签删除掉之后,得到的就是只有div里面的内容:
HJyM.png

其他的DOM方法

伪类选择器

  看一下css3的选择器:

from pyquery import PyQuery as py

html = '''
<div class="div1">
<ul class="ul1">
<li class="li1">this is li1.</li>
<li class="li2">this is li2.</li>
<li class="li3">this is li3.</li>
<li class="li4">this is li4.</li>
<li class="li5">this is li5.</li>
</ul>
</div>
'''
doc = py(html) #以字符串形式初始化html

li = doc('li:first-child')
print('第一个')
print(li)

li = doc('li:last-child')
print('最后一个')
print(li)

li = doc('li:nth-child(2)')
print('第二个')
print(li)

li = doc('li:gt(3)')
print('第4个(不包括)之后')
print(li)

li = doc('li:nth-child(2n)')
print('偶数位')
print(li)

li = doc('li:contains(li4)')
print('文本内容包含li4')
print(li)

  更多的选择器点我查看w3cschool去查看,用到的时候就可以直接用。

最后修改:2020 年 05 月 11 日 03 : 51 PM
请俺喝杯咖啡呗