pyquery-1.2.4中文文档(翻译注释版)
一、PyQuery简介:一款类似于jquery的python库
PyQuery允许你像JQuery一样对快速对xml(lxml)文档进行元素查询
、元素操作
的python库。如果你熟悉JQuery的api,那么掌握PyQuery是一件十分容易的事情,因为PyQuery的api和JQuery的api基本上一致。PyQuery是一款基于lxml的库,而lxml能够快速处理xml和html文档。
起初仅仅是因为我有个想法:想在python里面使用jquery类似api来操作xml文档,所以PyQuery就诞生了。你要明白一点的是,PyQuery库并不是用JavaScript来写的,正如上面所提到,这是一个python语言库,它基于lxml快速处理库。
PyQuery可以用来做很多xml相关的事情,下面是我能想到的一些用途:
- 使用PyQuery对纯HTTP模板(html)进行修改。
- 移除废弃或者不需要的web元素。
- 提取程序的主题元素。
PyQuery被放置在了github上,该项目被我设置了一些提交策略和代码审查策略,也就是被允许的人才能够提交和审查代码,如果你想提交你的修改,那么请给我邮件。
另外,请把bug提交到github上的issue面板上。
二、快速入门
1. 使用PyQuery之前应该使用pip或者别的工具进行安装:
pip install pyquery
一般会自动帮你把依赖库安装上,如lxml库。
2. 使用PyQuery快速加载xml文档,加载源可以是以下几个情形:
- 字符串
- xml文档
- 文件路径
- url链接
代码示例(python终端):
>>> from pyquery import PyQuery as pq
>>> from lxml import etree #引入依赖库
>>> import urllib #引入依赖库
>>> d = pq("<html></html>")
>>> d = pq(etree.fromstring("<html></html>")) #字符串
>>> d = pq(url='http://google.com/') #url路径
>>> # d = pq(url='http://google.com/', opener=lambda url, **kw: urllib.urlopen(url).read()) #读流
>>> d = pq(filename=path_to_html_file) #文件夹
加载以后得到变量d
,该变量如jquery里面的$操作符一样,可以对元素进行操作:
>>> d("#hello") #ID选择器,选择id=hello的元素
[<p#hello.hello>] #打印ID为hello的元素(PyQuery对象)
>>> p = d("#hello")
>>> print(p.html()) #打印p元素
Hello world !
>>> p.html("you know <a href='http://python.org/'>Python</a> rocks") #赋值html内容,相当于innerHtml=xx
[<p#hello.hello>]
>>> print(p.html())
you know <a href="http://python.org/">Python</a> rocks
>>> print(p.text()) #提取p标签内的text,不含html标签。
you know Python rocks
除此以外,你还可以使用非css标准的 :first :last :even :odd :eq :lt :gt :checked :selected :file伪符号来对元素进行定位,如:
>>> d('p:first')
[<p#hello.hello>]
更多快速入门请阅读:PyQuery快速入门-十分钟搞定PyQuery
三、选择器语法
和JQuery一样,PyQuery同样提供了丰富的选择器语法,满足你提取一个或者多个元素。
建立html文档并且命名为:demo.html
<div>
<tr class="item-0">
<td>first section</td>
<td>第一项</td>
<td>备注</td>
</tr>
<tr class="item-1">
<td>second section</td>
<td>第二项</td>
<td>备注</td>
</tr>
</div>
PyQuery各种选择器语法示例:
# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq#引入 PyQuery
doc = pq(filename='demo.html')# 传入文件 demo.html
print doc.html() # html()方法获取当前选中的 html 块
print doc('.item-1') # 相当于 class 选择器,选取 class 为 item-1 的 html 块
data = doc('tr') # 选取 <tr> 元素
for tr in data.items():# 遍历 data 中的 <tr> 元素
temp = tr('td').eq(2).text() # 选取第3个 <td> 元素中的文本块
print temp
上面示例摘取自:
作者:己立
链接:http://www.jianshu.com/p/c07f7cd1b548
四、操作html的属性
操作属性是PyQuery比较有魅力的功能,用于清洗网页数据。
使用类似于JQuery api对html属性进行操作,实例:
>>> p = pq('<p id="hello" class="hello"></p>')('p')
>>> p.attr("id") #打印p的ID值
'hello'
>>> p.attr("id", "plop") #给p元素的ID重新赋值,赋值后结果为plop
[<p#plop.hello>]
>>> p.attr("id", "hello")
[<p#hello.hello>]
使用更Python的语法进行操作,实例:
>>> p.attr.id = "plop"
>>> p.attr.id
'plop'
>>> p.attr["id"] = "ola"
>>> p.attr["id"]
'ola'
>>> p.attr(id='hello', class_='hello2')
[<p#hello.hello2>]
>>> p.attr.class_
'hello2'
>>> p.attr.class_ = 'hello'
五、操作CSS
你可以对html元素的css进行操作:
>>> p.addClass("toto") # 添加css
[<p#hello.hello.toto>]
>>> p.toggleClass("titi toto")
[<p#hello.hello.titi>]
>>> p.removeClass("titi") # 移除css
[<p#hello.hello>]
添加内联style的css样式:
>>> p.css("font-size", "15px")
[<p#hello.hello>]
>>> p.attr("style")
'font-size: 15px'
>>> p.css({"font-size": "17px"})
[<p#hello.hello>]
>>> p.attr("style")
'font-size: 17px'
使用Python语法进行编写(只需要将-变成下划线_,如font-size对应名字为font_size):
>>> p.css.font_size = "16px" #font_size 对应css的font-size
>>> p.attr.style
'font-size: 16px'
>>> p.css['font-size'] = "15px"
>>> p.attr.style
'font-size: 15px'
>>> p.css(font_size="16px")
[<p#hello.hello>]
>>> p.attr.style
'font-size: 16px'
>>> p.css = {"font-size": "17px"}
>>> p.attr.style
'font-size: 17px'
六、Manipulating(操作)API
- append函数:在元素末尾(元素内部的内容末尾)追加内容,添加的内容仍然在该元素内
>>> d = pq('<p class="hello" id="hello">you know Python rocks</p>')
>>> d('p').append(' check out <a href="http://reddit.com/r/python"><span>reddit</span></a>') #使用append api追加
[<p#hello.hello>]
>>> print d
<p class="hello" id="hello">you know Python rocks check out <a href="http://reddit.com/r/python"><span>reddit</span></a></p>
- prepend函数:在元素前面添加内容,添加的内容仍然在该元素内
>>> p = d('p')
>>> p.prepend('check out <a href="http://reddit.com/r/python">reddit</a>') #添加的内容
[<p#hello.hello>]
>>> print p #查看p标签全部内容
<p class="hello" id="hello">check out <a href="http://reddit.com/r/python">reddit</a>you know Python rocks</p>
>>> p.html()
u'check out <a href="http://reddit.com/r/python">reddit</a>you know Python rocks'
- prependTo函数:在前面或者末尾添加内容
>>> d = pq('<html><body><div id="test"><a href="http://python.org">python</a> !</div></body></html>')
>>> p.prependTo(d('#test'))
[<p#hello.hello>]
>>> d('#test').html()
u'<p class="hello" id="hello">check out <a href="http://reddit.com/r/python">reddit</a>you know Python rocks</p><a href="http://python.org">python</a> !'
这一段逻辑没有那么直观,解释下:
- 初始化一个d变量,内容为:
<html><body><div id="test"><a href="http://python.org">python</a> !</div></body></html>
- 把p元素
添加到
(prependTo)d('#test')的前面,d('#test')的内容为:<div id="test"><a href="http://python.org">python</a> !</div>
,那么就相当于在a标签前面加东西。 - 最后打印 d('#test')中的html内容:可以看到a标签之前多了p的内容。
同样的append对p进行操作:p.append(d('#test')),那么得到的结果:
>>> print p
<p class="hello" id="hello">check out <a href="http://reddit.com/r/python">reddit</a>you know Python rocks<div id="test"><a href="http://python.org">python</a> !</div></p>
相反的API还有insertBefore和insertAfter。
- remove函数:移除符合条件的元素
>>> d = pq('<html><body><p id="id">Yeah!</p><p>python rocks !</p></div></html>')
>>> d.remove('p#id') # 移除id=id的p,整个元素都移除,移除后后打印html
[<html>]
>>> d('p#id') # 打印
[]
- empty函数:置空元素内的html
>>> d('p').empty() # 置空操作,置空后没有html内容
[<p>]
七、条件过滤
一些JQuery过滤方法同样适用于PyQuery,下面是几个API例子:
- filter函数:过滤符合条件(class或者id等)的元素
>>> d = pq('<p id="hello" class="hello"><a/></p><p id="test"><a/></p>')
>>> d('p').filter('.hello') # 提取class=hello的p标签元素
[<p#hello.hello>]
- eq函数:筛选序号等于x的元素
>>> d('p').eq(0)
[<p#hello.hello>]
- find函数:筛选x标签的元素,返回list列表
>>> d('p').find('a') # 筛选a标签的元素,返回所有的a元素
[<a>, <a>]
>>> d('p').eq(1).find('a') # 筛选第二个p元素中的所有a元素
[<a>]
- end函数同样适用于链式筛选
>>> d('p').find('a').end()
[<p#hello.hello>, <p#test>]
>>> d('p').eq(0).end()
[<p#hello.hello>, <p#test>]
>>> d('p').filter(lambda i: i == 1).end()
[<p#hello.hello>, <p#test>]
八、其它常用API
- .hasClass(name):判断是否包含指定的 class,返回 True 或 False;
- .children():获取子元素;
- .parents():获取父元素;
- .next():获取下一个元素;
- .nextAll():获取后面全部元素块;
- .not_('selector'):获取所有不匹配该选择器的元素;
- for i in d.items('li'): print i.text():遍历 d 中的 li 元素;
end