Pyquery库并非python标准库,所以需要下载:pip install pyquery Pyquery是一个类似jquery(一个js库)的库,使用 lxml 进行快速 xml 和 html 操作。 利用它,我们可以直接解析 DOM 节点的结构,并通过 DOM 节点的一些属性快速进行内容提取。
1. 初始化Pyquery对象
初始化pyquery对象的方法有三种:文件名(filename)、网址(url)、字符串(text)
1.1 通过网址(url)初始化Pyquery对象
即,解析网址。在发起请求时注明编码集 如:encoding=“utf-8” 注意:一定要把协议补全了,这里的url就跟你在浏览器的网址栏里看到的一样。
from pyquery import PyQuery as pq
data = pq(url='https://www.baidu.com',encoding='utf-8')
print(data)
print(type(data))
print(data('title'))<title>百度一下,你就知道</title>
1.2 通过字符串(text)初始化Pyquery对象
from pyquery import PyQuery as pq
text = '''
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
'''
data = pq(text)
print(data)
print(data('span'))
1.3 通过文件名(filename)初始化Pyquery对象 第一步,先创建一个html文件 : 练习.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
</body>
</html>
第二步,解析
from pyquery import PyQuery as pq
data = pq(filename='练习.html',encoding='UTF-8')
print(data)
报错了不要急,原因是gbk解码错误。两种解决方式: 1)将html中的中文字符全部删除,再读取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="cont">
<ul class="slist">
<li class="item-0">web</li>
<li class="item-1"><a href="link2.html"></a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold"></span></a></li>
<li class="item-1 active"><a href="link4.html"></a></li>
<li class="item-0"><a href="link5.html"></a></li>
</ul>
</div>
</body>
</html>
from pyquery import PyQuery as pq
data = pq(filename='练习.html',encoding='UTF-8')
print(data)
print(data('title'))
2)先读取文件,并重新编码,再用字符串方式初始化 最终效果与1)是一样的。不过会占用内存,html文件太大时不太适合。 f
rom pyquery import PyQuery as pq
with open('练习.html','r+',encoding='utf-8') as f:
text = f.read()
data = pq(text)
print(data)
print(data('title'))
2. 查找节点
补充资料:https://www.icode9.com/content-1-621561.html 2.1 标签选择器
语法:pyquery对象('标签名')
就是前面范例中的:
print(data('title'))
如果要查某一个子标签,则:
语法:pyquery对象('标签a a的子标签b b的子标签c ...)
from pyquery import PyQuery as pq
data = pq(url='http://www.baidu.com',encoding='utf-8')
print(data('div div div div div div'))
2.2 CSS选择器 2.2.1 class选择器
语法:pyquery对象('.class属性值')
表示选择该pq对象中所有class='class属性值’的内容
语法:pyquery对象('标签1.class属性值')
表示选择 pq对象中class='class属性值’的标签1 内容
from pyquery import PyQuery as pq
with open('练习.html','r+',encoding='utf-8') as f:
text = f.read()
data = pq(text)
print(data('.item-0'))
print(data('.item-0.active'))
print(data('li.item-1'))
2.2.2 id选择器
语法:pyquery对象('#ID属性值')
表示选择该pq对象中所有id='ID属性值’的内容
语法:pyquery对象('标签1#ID属性值')
表示选择 pq对象中id='ID属性值’的标签1 内容。
这样写是可以,不过id不同于class,一个id对应一个css元素,一个css元素对应一个id,不存在id值相同的两个不同标签。所以没必要这样写
from pyquery import PyQuery as pq
data = pq(url='http://www.baidu.com',encoding='utf-8')
print(data('#lg'))
print(data('div#lg'))
2.2.4 其他
2.3 伪类选择器
html = '''
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li:first-child')
print(li)
li1 = doc('li:last-child')
print(li1)
li2 = doc('li:nth-child(2)')
print(li2)
li3 = doc('li:gt(2)')
print(li3)
li4 = doc('li:nth-child(2n)')
print(li4)
li5 = doc('li:contains(深度)')
print(li5)
2.4 父级节点查找
语法:pyquery对象.parent()
直接父级节点查找
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li')
print(type(li))
print(li.parent())
输出结果:
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
语法:pyquery对象.parents('条件1')
符合条件1的(父)祖级节点查找。如果不加条件限制,会返回所有的 父级 祖级。
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li')
print(li.parents('div'))
输出:
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
2.5 子级节点查找
语法1:pyquery对象.children('条件1')
符合条件1的直接子级节点查找,如果过不加条件限制,会返会所有直接子级。
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li')
print(type(li))
ch = li.children()
print(type(ch),ch)
语法2:pyquery对象('父节点 子节点')
注意:这个子节点并不需要是直接子关系,可以是孙子关系或者更下层的层级关系。
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0 span')
print(li)
两个节点之间加空格,表示后者是前者的下级;
不加空格表示同时满足条件1和条件2(例如doc(’.item-1.active’)),不适用于标签选择器(因为不加.或者[]之类符号限制的话,系统会将两个相连的标签识别为一个标签名,会报错例如:divp)。
print(doc('.item-1.active'))
语法3:pyquery对象('标签1>标签2')
适用于标签选择器。查找标签1下的多有标签2。标签1和标签2必须成直接父子关系,否则查找不到。
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('ul>li')
print(li)
2.6 同级(兄弟)节点查找
语法:pyquery对象.sibling('条件1')
查找符合条件1的兄弟节点。不加条件,则返回所有兄弟节点。
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li.active')
print(data)
print(data.siblings())
print(data.siblings('.item-1'))
2.7 同时查找多个节点
语法:pyquery对象('节点a,节点b')
from pyquery import PyQuery as pq
data = pq(url='http://www.baidu.com',encoding='utf-8')
for i in data('a,span').items():
print(i)
输出结果:
<span class="bg s_ipt_wr"><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off" autofocus=""/></span>
<span class="bg s_btn_wr"><input type="submit" id="su" value="百度一下" class="bg s_btn"/></span>
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a>
<a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a>
<a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a>
<a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a>
<a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a>
<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">登录</a>
<a href="//www.baidu.com/more/" name="tj_briicon" class="bri" style="display: block;">更多产品</a>
<a href="http://home.baidu.com">关于百度</a>
<a href="http://ir.baidu.com">About Baidu</a>
<a href="http://www.baidu.com/duty/">使用百度前必读</a>
<a href="http://jianyi.baidu.com/" class="cp-feedback">意见反馈</a> 京ICP证030173号
3. 遍历pyquery对象
pyquery对象.items() 转换为生成器对象(迭代器的一种),再for循环遍历
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li').items()
print(type(data))
for i in data:
print(i)
输出结果:
<class 'generator'>
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
4. 获取信息
4.1 获取属性值——attr()
语法1:pyquery对象.attr('属性名')
attr()只传递一个参数:属性名,表示查找属性值; 如果传递第二个参数,则表示修改属性值。 修改时,若第一个参数,这个属性不存在,则创建。
语法2:pyquery对象.attr.属性名
from pyquery import PyQuery as pq
doc = pq(html)
print(doc.attr('id'))
print(doc.attr.id)
doc.attr('name', 'alink')
print(doc.attr('name'))
attr方法是在pyquery对象的第一个标签里查找属性,如果没找到就返回None。
print(doc.attr('href'))
print(doc.attr.href)
所以我们需要先把一个pyquery对象用items()方法转换成一个迭代器对象,再迭代这个迭代器对象,再使用attr()方法取找每一个标签里的属性。
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li').items()
for i in data:
print(i)
print(i.attr('class'))
输出结果:
<li class="item-0">web开发</li>
item-0
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
item-1
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
item-0 active
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
item-1 active
<li class="item-0"><a href="link5.html">机器学习</a></li>
item-0
4.2 获取文本——text()
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('span')
print(data)
print(data.text())
text()中也可以传递参数,表示修改文本。
data.text('金融分析')
print(data.text())
4.3 获取节点内部的HTML文本——html() 获取或设置子节点的html表示,不传参表示查询,传参表示修改。
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li').items()
for d in data:
print(d.html())
d.html('<span>修改文档</span>')
print(d.html())
运行结果:
web开发
<span>修改文档</span>
<a href="link2.html">爬虫开发</a>
<span>修改文档</span>
<a href="link3.html"><span class="bold">数据分析</span></a>
<span>修改文档</span>
<a href="link4.html">深度学习</a>
<span>修改文档</span>
<a href="link5.html">机器学习</a>
<span>修改文档</span>
5. 节点操作
为了提取方便,我们可以修改我们已经获取的html的节点,如在指定位置添加class,移除不需要的某个(些)节点等
5.1 移除指定节点——remove()
先查找到要移除的结点,然后.remove()即可
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li')
data.remove()
print(doc)
运行结果:
<div id="cont">
<ul class="slist">
</ul>
</div>
5.2 移除class属性——removeClass()
removeClass('要移除的属性值')
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li.active')
data.remove_class('item-0')
print(data)
运行结果:
<li class="active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
5.3 增加class属性——addClass()
addClass('要增加的属性值')
from pyquery import PyQuery as pq
doc = pq(html)
data = doc('li.item-0.active')
data.add_class('春天来了')
print(data)
6. 注意事项
pyquery库直接请求url的话,没有办法设置请求头和请求方式,也不能上传数据。 所以只能用来爬取一些简单的网址。 不过用来做数据解析和提取时挺好用的,一般也确实是这样用的。 获取网页的工作用别的库,如requests库来完成。
|