什么是PyQuery

PyQuery是一个类似于jQuery的解析网页工具,使用lxml操作xml和html文档,它的语法和jQuery很像。和XPATH,Beautiful Soup比起来,PyQuery更加灵活,提供增加节点的class信息,移除某个节点,提取文本信息等功能。

初始化PyQuery对象

html文档的所有操作都需要PyQuery对象来完成,初始化PyQuery对象主要有三种方式,分别是通过网址、字符串和文件名创建。

方式一:通过网址初始化PyQyery对象

先看一段代码:

from pyquery import PyQuery as pq

s = '<html><title>PyQuery用法总结<title></html>'
doc = pq(s)
print(doc('title'))

运行结果:

<title>PyQuery用法总结</title>

首先要import PyQuery类,然后将字符串传递给PyQuery类,这样就生成了一个PyQuery对象,通过该对象就可以访问字符串中的title节点。

PyQuery还会将残缺的html文档补全。看下面的代码:

from pyquery import PyQuery as pq

s = '<html><title>PyQuery用法总结</title>'
doc = pq(s)
print(doc('html'))

运行的结果:

<html><head><title>PyQuery用法总结</title></head></html>

可以我们的字符串的html节点是没有闭合的,并且缺少head节点。初始化PyQuery对象之后,会把html文档补全,并且自动加上head节点。

方式二:URL网址初始化PyQyery对象

将要解析的URL网址当做参数传递给PyQuery类:

from pyquery import PyQuery as pq

url = 'http://www.bigdata17.com'
doc = pq(url=url,encoding='utf-8')
print(doc('title'))

运行结果:

<title>Home - Summer哥的自留地</title>

方式三:通过文件初始化PyQyery对象

这个方式也比较常用,很多时候我们会将网站爬取下来然后保存在本地磁盘:

from pyquery import PyQuery as pq

doc = pq(filename='test_pyquery.html',encoding='utf-8')
print(doc('title'))

访问节点属性:

使用attr()方法访问节点的属性:

from pyquery import PyQuery as pq
li = pq('<li id="test1" class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.attr("id"))

运行结果:

test1

上面的代码中有两个id不同的li节点,但是attr()方法只取第一个li节点的id属性值,而不取第二个,我们把上面的代码修改下,把第一个li节点的id属性去掉,attr方法是否只取第一个复合条件节点的属性值:

from pyquery import PyQuery as pq
li = pq('<li class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.attr("id"))

运行结果:

None

第一个li节点没有id属性,因此返回结果为None,所以可见,attr()方法返回的是第一个节点的属性值。

那要取多个li节点的属性值,要怎么做呢?这就要结合items()方法来实现。items()方法是返回的节点的生成器generator object PyQuery.items

from pyquery import PyQuery as pq
li = pq('<li id="test1" class="test1"></li><li id="test2" class="test2"></li>')('li')
print(li.items())
for item in li.items():
print(item.attr("id"))

运行结果:

<generator object PyQuery.items at 0x0000027F26082728>
test1
test2

动态添加节点属性

PyQuery有很多方法动态添加节点的属性,我们挑选几个比较常用的方法介绍个大伙。

addClass(),动态添加节点class属性:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.addClass("addClass")
print(li)

运行结果:

<li id="test1" class="test1 addClass"/>

可见li节点的calss属性值有test1变为test1 addclass。

addClass()方法只能动态添加节点class属性的值,能不能动态添加其他属性呢?答案是当然可以,attr()方法就可以实现:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.attr("name","li name")
print(li)
li.attr("type","li")
print(li)
print(li.attr("type"))

运行结果:

<li id="test1" class="test1" name="li name"/>
<li id="test1" class="test1" name="li name" type="li"/>
li

上面的代码一共执行了3次attr()方法,执行第一次attr()方法时,有两个参数,分别是name和li name。这是给li节点添加name属性及属性值。执行第二次attr()方法也有两个参数,分别是type和li,这是给li几点添加type属性及type属性值。执行第三次方法attr()方法只有一个type参数,根据前面介绍的attr()方法的用法可知,是获取li节点type属性的值。

小结: attr()方法只有一个参数时,是获取节点的属性值,有两个参数时,是给节点添加属性及属性值,第一个参数时属性,第二个参数时属性值。

removeClass(),动态移除节点的class属性:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.removeClass("test1")
print(li)

运行结果:

<li id="test1" class=""/>

将class节点的属性值有test1变为“”。

动态添加/修改文本值

PyQuery支持动态给节点添加文本值:

from pyquery import PyQuery as pq
html = '<li id="test1" class="test1"></li>'
li = pq(html)('li')
li.html("use html() dynamic add text")
print(li)
li.text("use text() dynamic add text")
print(li)

运行结果:

<li id="test1" class="test1">use html() dynamic add text</li>
<li id="test1" class="test1">use text() dynamic add text</li>

可见使用html()和text()方法都可以动态的给节点添加或修改节点的文本值。

获取节点文本值

PyQuery提供text()和html()方法获取节点的文本属性值:

from pyquery import PyQuery as pq
html = '<li id = "test_id">li text value</li>'
li = pq(html)('li')
print(li.text())
print(li.html())

运行结果:

li text value
li text value

小结: html()和text()如果没参数,则是获取属性的文本值,如果有参数,则是改变或者添加节点的属性值。

移除节点:

remove()方法可以动态移除节点:

from pyquery import PyQuery as pq
html = '''
<ul>
hello I am ul tag
<li>hello I am li tag</li>
</ul>
'''
ul = pq(html)('ul')
print(ul.text())
print('执行remove()移除节点')
ul.find('li').remove()
print(ul.text())

运行结果:

hello I am ul tag
hello I am li tag
执行remove()移除节点
hello I am ul tag

上述代码的ul节点中有个li节点,执行ul.text()方法会返回包括li节点的文本信息,如果我们不想返回li节点的文本信息,仅仅只需要ul节点的文本信息“hell I am ul tag”,要怎么做呢?这时候remove()方法就派上用场了,它删除掉ul节点内的li节点。

查找节点

PyQuery支持使用css的.和#来查找节点:

from pyquery import PyQuery as pq
html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li'))

运行结果:

<li>hello I am li tag</li>
<li>hello I am li tag too</li>

上述代码是通过.div_tag获取class为div_tag的节点,然后通过#ul_tag获取id为ul_tag的节点,最后返回所有的li节点。

find()方法查找节点:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag').find("li"))

运行结果:

<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>

可见find("li")是把所有li节点及子节点都查找出来。

还有一个children()方法,是获取当前节点的所有子节点。该方法可以传入css选择器:children('.ul_tag')。

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag').find("li"))

运行结果:

<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>

使用parent()方法获取当前节点的父亲节点:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li').parent())

运行结果:

<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>

上述代码通过.div_tag #ul_tag li css选择器定位到li节点,然后调用parent()方法获取li节点的父节点ul。

parents()返回当前节点的所有祖宗节点:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</li>
<li>hello I am li tag too</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag li').parents())

运行结果:

<html><body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
</body></html><body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
</body><div class="div_tag">
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>
</div>
<ul id="ul_tag">
hello I am ul tag
<li>hello I am li tag<a>www.bigdata17.com</a></li>
<li>hello I am li tag too</li>
</ul>

上面代码返回li节点的所有祖宗节点:html,body,div,ul。

siblings()方法返回当前节点的兄弟节点:

html = '''
<div class="div_tag">
<ul id = "ul_tag">
hello I am ul tag
<li class="li_class1">hello I am li tag<a>www.bigdata17.com</li>
<li class="li_class2">hello I am li tag too</li>
<li class="li_class3">hello I am the third li tag</li>
</ul>
</div>
'''
doc = pq(html)
print(doc('.div_tag #ul_tag .li_class1').siblings())

运行结果:

<li class="li_class2">hello I am li tag too</li>
<li class="li_class3">hello I am the third li tag</li>

使用.div_tag #ul_tag .li_class1 CSS节点选择器获取到class为liclassq1的li节点,就是第一个li节点,然后调用siblings()方法获取到子节点,分别是

第二和第三个li节点。

sibligs()还支持传入css选择器筛选符合条件的li节点:

print(doc('.div_tag #ul_tag .li_class1').siblings('.li_class3'))

运行结果:

<li class="li_class3">hello I am the third li tag</li>

总结:本文讲述了如何使用PyQuery获取网页节点,节点的文本信息,改变节点属性,删除节点属性,增加节点属性等知识点。

一起学爬虫——PyQuery常用用法总结的更多相关文章

  1. Python爬虫利器六之PyQuery的用法

    前言 你是否觉得 XPath 的用法多少有点晦涩难记呢? 你是否觉得 BeautifulSoup 的语法多少有些悭吝难懂呢? 你是否甚至还在苦苦研究正则表达式却因为少些了一个点而抓狂呢? 你是否已经有 ...

  2. pyquery 的用法 --爬虫解析库

    如果你对Web有所涉及,如果你比较喜欢用CSS选择器,如果你对jQuery有所了解,那么这里有一个更适合你的解析库--pyquery. 接下来,我们就来感受一下pyquery的强大之处. 1. 准备工 ...

  3. 一起学爬虫——使用selenium和pyquery爬取京东商品列表

    layout: article title: 一起学爬虫--使用selenium和pyquery爬取京东商品列表 mathjax: true --- 今天一起学起使用selenium和pyquery爬 ...

  4. Python爬虫:学爬虫前得了解的事儿

    这是关于Python的第14篇文章,主要介绍下爬虫的原理. 提到爬虫,我们就不得不说起网页,因为我们编写的爬虫实际上是针对网页进行设计的.解析网页和抓取这些数据是爬虫所做的事情. 对于大部分网页来讲, ...

  5. centos的vi常用用法

    centos的vi常用用法 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的 ...

  6. MySql与SqlServer的一些常用用法的差别

    MySql与SqlServer的一些常用用法的差别 本文为转载 本文将主要列出MySql与SqlServer不同的地方,且以常用的存储过程的相关内容为主. 1. 标识符限定符 SqlServer [] ...

  7. [转]ssh常用用法小结

    ssh常用用法小结 1.连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机, ...

  8. 【三支火把】---一份程序看懂C程序printf()的几种常用用法

    闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...

  9. grep参数说明及常用用法

    grep参数说明及常用用法 趁着午休的时间把自己经常使用的一些grep命令整理一下. 方便以后查看. 后续会逐步把awk/sed/find等常用的命令理一理. 增强下记忆. 也算是对得起自己了. ^^ ...

随机推荐

  1. python常用函数用法整理

    1,zeros函数(同理的还有ones函数) http://www.jb51.net/article/127649.htm 注意: (m,n)是生成m行n列的矩阵,但要生成二维矩阵的时候要用两层括号, ...

  2. shell脚本自动化部署服务

    shell脚本自动化部署 !/bin/bash #export PATH=$PATH:/export/maven/bin run_flag_dir="/data0/shell/deploy_ ...

  3. Codeforces 1037C Equalize

    原题 题目大意: 给你两个长度都为\(n\)的的\(01\)串\(a,b\),现在你可以对\(a\)串进行如下两种操作: 1.交换位置\(i\)和位置\(j\),代价为\(|i-j|\) 2.反转位置 ...

  4. utf8的大小写敏感性测试及其修改方法

    utf8的大小写敏感性测试及其修改方法 # 测试utf8的大小写敏感性及其修改方法 -- 以下是utf8不区分大小写 # 修改数据库: ALTER DATABASE database_name CHA ...

  5. Pandas系列(十一)-文件IO操作

    数据分析过程中经常需要进行读写操作,Pandas实现了很多 IO 操作的API,这里简单做了一个列举. 格式类型 数据描述 Reader Writer text CSV read_ csv to_cs ...

  6. Flask进阶

    Threading.local 作用:为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离). 应用: flask上下文管理中的local中比这更高级,为协程. DBUtils ...

  7. 适配器模式-Adapter(Java实现)

    适配器模式-Adapter 是作为两个不兼容的接口之间的桥梁. 本篇文章的代码github地址: https://github.com/GoldArowana/design-patterns/tree ...

  8. 清除系统默认样式,文本样式,高级选择器(权重),边界圆角,a标签的四大伪类,背景图片

    清除系统默认样式 大多系统预定义标签,有默认样式,不满足实际开发需求,反倒影响布局通常清除系统样式,利于开发 body,h1-h6,p,table { margin:; } ul { margin:; ...

  9. HTML(七)HTML 表单(form元素介绍,input元素的常用type类型,input元素的常用属性)

    前言 表单是网页与用户的交互工具,由一个<form>元素作为容器构成,封装其他任何数量的表单控件,还有其他任何<body>元素里可用的标签 表单能够包含<input> ...

  10. [Android] 免费天气预报接口

    [Android] 免费天气预报接口 这是 国家气象局提供的天气预报接口 [免费] 当然,网上有很多的收费API或者每天定次数的接口 使用 国家气象局 的步骤如下: 1.首先获取城市ID号 北京:10 ...