强大又灵活的网页解析库,如果你觉得正则写起来太麻烦,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法,那么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标签,看看打印结果:
这里的选择器也就是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标签就打印,很无敌的存在。
文件初始化
很好理解,刚才传了我们手动写的html代码。还有我们打开的链接,那么这次就是一个html或者htm文本文件:
import pyquery
from pyquery import PyQuery as pq
doc = pq(filename='dome.htm')
print(doc('p'))
需要注意的是这个文件名字必须正确,文件最好是在你的这个python程序的同级目录下,或者你写绝对路径也可以。然后用法基本跟刚才一样,我们看看打印结果:
这个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的标签,同时也打印出它的类型和内容:
可以看到这个类型都是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,内容也和我们预想的一致:
另外还有一个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)
这个就厉害了,基本上把所以的内容都给你打印出来了:
这个类型也是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的才对:
兄弟元素
有了父节点和子节点,那么兄弟节点是必不可少的,我们可以看看下面的代码:
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方法,看看打印结果:
结果不出所料,两个兄弟标签都打印出来了。
然后这个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的兄弟,打印结果如图所示:
单个元素
如果我们查找了多个元素怎么遍历呢,先看看查找单个元素:
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)
看打印结果,单个元素很好操作,方便对其嵌套之类的。
多个元素的话我们需要用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()方法来提取里面的超链接。最后的打印方法两种都是一样的:
获取文本
我们这里不管文字被什么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())
获取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()方法而已。看看运行结果吧:
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加上:
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里面的内容:
其他的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去查看,用到的时候就可以直接用。
5 条评论
袁宝宝 鹏鹏 晚安
锤锤
瓜娃子
哈哈