爬虫:PyQuery的使用
Posted Felix Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了爬虫:PyQuery的使用相关的知识,希望对你有一定的参考价值。
一:简介
PyQuery库是jQuery的Python实现,可以用于解析html网页内容,是一个非常强大又灵活的网页解析库。
--》官方文档地址
--》jQuery参考文档
二:初始化
初始化的时候一般有三种传入方式:传入字符串,传入url,传入文件。
(1):字符串初始化
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写起来比较麻烦,所以我们导入的时候都会添加别名:
from pyquery import PyQuery as pq
这里我们可以知道上述代码中的doc其实就是一个pyquery对象,我们可以通过doc可以进行元素的选择,其实这里就是一个css选择器,所以CSS选择器的规则都可以用,直接doc(标签名)就可以获取所有的该标签的内容,如果想要获取class 则doc(\'.class_name\'),如果是id则doc(\'#id_name\')....
(2):url初始化
from pyquery import PyQuery as pq doc = pq(url=\'http://www.baidu.com\') print(doc(\'head\'))
(3):文件初始化
from pyquery import PyQuery as pq doc = pq(filename=\'demo.html\') print(doc(\'li\'))
注意:pq()这里可以传入url参数也可以传入文件参数,当然这里的文件通常是一个html文件,例如:pq(filename=\'index.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\'))
注意:
doc(\'#container .list li\'),这里的三者之间的并不是必须要挨着,只要是层级关系就可以,下面是常用的CSS选择器方法:
(1):查找元素
子元素:
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) 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> ##############################
从结果里我们也可以看出通过pyquery找到结果其实还是一个pyquery对象,可以继续查找,上述中的代码中的items.find(\'li\') 则表示查找ul里的所有的li标签
当然这里通过children可以实现同样的效果,并且通过.children方法得到的结果也是一个pyquery对象
li = items.children() print(type(li)) print(li) # 在children里也可以用CSS选择器 li2 = items.children(\'.active\') print(li2)
父元素:
通过.parent就可以找到父元素的内容:
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) items = doc(\'.list\') container = items.parent() print(type(container)) print(container)
通过.parents就可以找到祖先节点的内容:
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\') parents = items.parents() print(type(parents)) print(parents)
# 通过.parents查找的时候也可以添加css选择器来进行内容的筛选
兄弟元素:
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(\'.list .item-0.active\') print(li.siblings())
代码中doc(\'.list .item-0.active\') 中的.tem-0和.active是紧挨着的,所以表示是并的关系,这样满足条件的就剩下一个了:thired item的那个标签了
这样在通过.siblings就可以获取所有的兄弟标签,当然这里是不包括自己的
同样的在.siblings()里也是可以通过CSS选择器进行筛选
(2):遍历
单个元素:
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) lis = doc(\'li\').items() # 通过items()可以得到一个生成器,并且通过循环得到每个元素 print(type(lis)) for li in lis: print(type(li)) print(li)
三:获取信息
获取属性:
pyquery对象.attr(属性名)
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) print(a.attr(\'href\')) print(a.attr.href)
# 获得属性值的时候可以直接a.attr(属性名)或者a.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) print(a.text()) # 通过.text()就可以获取文本信息
获取html:
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) print(li.html()) # 通过.html()的方式可以获取当前标签所包含的html信息
四:DOM操作
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)
attr,css
同样的我们可以通过attr给标签添加和修改属性,
如果之前没有该属性则是添加,如果有则是修改
我们也可以通过css添加一些css属性,这个时候,标签的属性里会多一个style属性
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.attr(\'name\', \'link\') print(li) li.css(\'font-size\', \'14px\') print(li)
remove
有时候我们获取文本信息的时候可能并列的会有一些其他标签干扰,这个时候通过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())
五:官方api整理-->api
使用方法
from pyquery import PyQuery as pq
1.可加载一段HTML字符串,或一个HTML文件,或是一个url地址,
例:
d=pq("<html><title>hello</title></html>")
d=pq(filename=path_to_html_file)
d=pq(url=\'http://www.baidu.com\')注意:此处url似乎必须写全
2.html()和text() ——获取相应的HTML块或文本块,
例:
p=pq("<head><title>hello</title></head>")
p(\'head\').html()#返回<title>hello</title>
p(\'head\').text()#返回hello
3.根据HTML标签来获取元素,
例:
d=pq(\'<div><p>test 1</p><p>test 2</p></div>\')
d(\'p\')#返回[<p>,<p>]
print d(\'p\')#返回<p>test 1</p><p>test 2</p>
print d(\'p\').html()#返回test 1
注意:当获取到的元素不只一个时,html()、text()方法只返回首个元素的相应内容块
4.eq(index) ——根据给定的索引号得到指定元素
接上例,若想得到第二个p标签内的内容,则可以:
print d(\'p\').eq(1).html() #返回test 2
5.filter() ——根据类名、id名得到指定元素,例:
d=pq("<div><p id=\'1\'>test 1</p><p class=\'2\'>test 2</p></div>")
d(\'p\').filter(\'#1\') #返回[<p#1>]
d(\'p\').filter(\'.2\') #返回[<p.2>]
6.find() ——查找嵌套元素,例:
d=pq("<div><p id=\'1\'>test 1</p><p class=\'2\'>test 2</p></div>")
d(\'div\').find(\'p\')#返回[<p#1>, <p.2>]
d(\'div\').find(\'p\').eq(0)#返回[<p#1>]
7.直接根据类名、id名获取元素,例:
d=pq("<div><p id=\'1\'>test 1</p><p class=\'2\'>test 2</p></div>")
d(\'#1\').html()#返回test 1
d(\'.2\').html()#返回test 2
8.获取属性值,例:
d=pq("<p id=\'my_id\'><a href=\'http://hello.com\'>hello</a></p>")
d(\'a\').attr(\'href\')#返回http://hello.com
d(\'p\').attr(\'id\')#返回my_id
9.修改属性值,例:
d(\'a\').attr(\'href\', \'http://baidu.com\')把href属性修改为了baidu
10.addClass(value) ——为元素添加类,例:
d=pq(\'<div></div>\')
d.addClass(\'my_class\')#返回[<div.my_class>]
11.hasClass(name) #返回判断元素是否包含给定的类,例:
d=pq("<div class=\'my_class\'></div>")
d.hasClass(\'my_class\')#返回True
12.children(selector=None) ——获取子元素,例:
d=pq("<span><p id=\'1\'>hello</p><p id=\'2\'>world</p></span>")
d.children()#返回[<p#1>, <p#2>]
d.children(\'#2\')#返回[<p#2>]
13.parents(selector=None)——获取父元素,例:
d=pq("<span><p id=\'1\'>hello</p><p id=\'2\'>world</p></span>")
d(\'p\').parents()#返回[<span>]
d(\'#1\').parents(\'span\')#返回[<span>]
d(\'#1\').parents(\'p\')#返回[]
14.clone() ——返回一个节点的拷贝
15.empty() ——移除节点内容
16.nextAll(selector=None) ——返回后面全部的元素块,例:
d=pq("<p id=\'1\'>hello</p><p id=\'2\'>world</p><img scr=\'\' />")
d(\'p:first\').nextAll()#返回[<p#2>, <img>]
d(\'p:last\').nextAll()#返回[<img>]
17.not_(selector) ——返回不匹配选择器的元素,例:
d=pq("<p id=\'1\'>test 1</p><p id=\'2\'>test 2</p>")
d(\'p\').not_(\'#2\')#返回[<p#1>]
以上是关于爬虫:PyQuery的使用的主要内容,如果未能解决你的问题,请参考以下文章
Python爬虫编程思想(64): 在pyquery中使用CSS选择器
Python爬虫编程思想(64): 在pyquery中使用CSS选择器
Python爬虫编程思想(66): 使用pyquery获取节点信息