Python中类似于jquery的pyquery库用法分析


Posted in Python onDecember 02, 2019

本文实例讲述了Python中类似于jquery的pyquery库用法。分享给大家供大家参考,具体如下:

pyquery:一个类似于jquery的Python库

pyquery可以使你在xml文档上做jquery查询,它的API尽可能地类似于jquery。pyquery使用lxml执行快速的xml和html操作。

这并非(至少目前还不是)一个生成javascript代码或者与javascript代码做交互的库。pyquery的作者只是由于非常喜欢jquery的API因而将其用python实现。

该项目目前托管在Github仓库中并且处于活跃开发状态。作者可以为任何想要贡献源码的开发者赋予push权限,并且会对其做的变更做回顾。如果你想要贡献源码,可以发Email给项目作者。

项目的Bug可以通过Github Issue Tracker进行提交。

快速入门

你可以使用PyQuery类从一个字符串,一个lxml文档,一个文件或者一个url钟载入一个xml文档:

>>> 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=your_url)
>>> d = pq(url=your_url,
...    opener=lambda url, **kw: urlopen(url).read())
>>> d = pq(filename=path_to_html_file)

现在,d就相当于jquery里的$:

>>> d("#hello")
[<p#hello.hello>]
>>> p = d("#hello")
>>> print(p.html())
Hello world !
>>> p.html("you know <a href='http://python.org/'>Python</a> rocks")
[<p#hello.hello>]
>>> print(p.html())
you know <a href="http://python.org/" rel="external nofollow" >Python</a> rocks
>>> print(p.text())
you know Python rocks

你也可以使用某些jQuery中可用而并非css标准的伪类,诸如 :first :last :even :odd :eq :lt :gt :checked :selected :file:等

>>> d('p:first')
[<p#hello.hello>]

参见http://pyquery.rtfd.org/查看全部文档

CSS

你可以像这样添加、切换、移除CSS:

>>> p.addClass("toto")
[<p#hello.hello.toto>]
>>> p.toggleClass("titi toto")
[<p#hello.hello.titi>]
>>> p.removeClass("titi")
[<p#hello.hello>]

或者操作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'

使用更加Pythonic的方式完成同样的功能 (‘_' 字符转换为 ‘-‘):

>>> p.css.font_size = "16px"
>>> 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'

使用伪类:

  • :button

匹配所有按钮输入元素和按钮元素 Matches all button input elements and the button element

  • :checkbox

匹配所有复选框输入元素 Matches all checkbox input elements

  • :checked

匹配选中的元素,下标从0开始 Matches odd elements, zero-indexed

  • :child

右边是左边的直接子元素 right is an immediate child of left

  • :contains()

包含元素 Matches all elements that contain the given text

  • :descendant

右边是左边的子元素、孙元素或者更远的后继元素 right is a child, grand-child or further descendant of left

  • :disabled

匹配所有被禁用的元素 Matches all elements that are disabled

  • :empty

匹配所有不包括任何其他元素的元素 Match all elements that do not contain other elements

  • :enabled

匹配所有启用的元素 Matches all elements that are enabled

  • :eq()

使用下标匹配 Matches a single element by its index

  • :even

从下标0开始,匹配所有偶数元素 Matches even elements, zero-indexed

  • :file

匹配所有文件类型的输入元素 Matches all input elements of type file

  • :first

匹配第一个被选择的元素 Matches the first selected element

  • :gt()

匹配下标大于指定值的元素 Matches all elements with an index over the given one

  • :header

匹配所有标题元素 Matches all header elelements (h1, ..., h6)

  • :image

匹配所有图像输入元素 Matches all image input elements

  • :input

匹配所有输入元素 Matches all input elements

  • :last

匹配最后一个选择的元素 Matches the last selected element

  • :lt()

匹配所有下标小于指定值的元素 Matches all elements with an index below the given one

  • :odd

匹配奇元素,下标从0开始 Matches odd elements, zero-indexed

  • :parent

匹配所有包含其他元素的元素 Match all elements that contain other elements

  • :password

匹配所有密码输入元素 Matches all password input elements

  • :radio

匹配单选按钮输入元素 Matches all radio input elements

  • :reset

匹配所有重置输入元素 Matches all reset input elements

  • :selected

匹配所有被选中的元素 Matches all elements that are selected

  • :submit

匹配所有提交输入元素 Matches all submit input elements

  • :text¶

匹配所有文本输入元素 Matches all text input elements

操作

你也可以向标签的尾部追加元素:

>>> d = pq('<p class="hello" id="hello">you know Python rocks</p>')
>>> d('p').append(' check out <a href="http://reddit.com/r/python" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><span>reddit</span></a>')
[<p#hello.hello>]
>>> print(d)
<p class="hello" id="hello">you know Python rocks check out <a href="http://reddit.com/r/python" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><span>reddit</span></a></p>

或者加至开头:

>>> p = d('p')
>>> p.prepend('check out <a href="http://reddit.com/r/python" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >reddit</a>')
[<p#hello.hello>]
>>> print(p.html())
check out <a href="http://reddit.com/r/python" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >reddit</a>you know ...

在其他元素之前或者之后追加元素:

>>> d = pq('<html><body><div id="test"><a href="http://python.org" rel="external nofollow" rel="external nofollow" >python</a> !</div></body></html>')
>>> p.prependTo(d('#test'))
[<p#hello.hello>]
>>> print(d('#test').html())
<p class="hello" ...

在其他元素之后插入元素:

>>> p.insertAfter(d('#test'))
[<p#hello.hello>]
>>> print(d('#test').html())
<a href="http://python.org" rel="external nofollow" rel="external nofollow" >python</a> !

或者插入其他元素之前:

>>> p.insertBefore(d('#test'))
[<p#hello.hello>]
>>> print(d('body').html())
<p class="hello" id="hello">...

对每个元素做一些事情:

>>> p.each(lambda i, e: pq(e).addClass('hello2'))
[<p#hello.hello.hello2>]

移除一个元素:

>>> d = pq('<html><body><p id="id">Yeah!</p><p>python rocks !</p></div></html>')
>>> d.remove('p#id')
[<html>]
>>> d('p#id')
[]

移除选中元素的内容:

>>> d('p').empty()
[<p>]

你可以获得修改后的html内容:

>>> print(d)
<html><body><p/></body></html>

你可以生成html片段:

>>> from pyquery import PyQuery as pq
>>> print(pq('<div>Yeah !</div>').addClass('myclass') + pq('<b>cool</b>'))
<div class="myclass">Yeah !</div><b>cool</b>

移除所有命名空间:

>>> d = pq('<foo xmlns="http://example.com/foo"></foo>')
>>> d
[<{http://example.com/foo}foo>]
>>> d.remove_namespaces()
[<foo>]

遍历

一些jQuery遍历方法也可以支持。这里有几个例子。

你可以使用字符串选择器过滤选择列表:

>>> d = pq('<p id="hello" class="hello"><a/></p><p id="test"><a/></p>')
>>> d('p').filter('.hello')
[<p#hello.hello>]

可以使用eq选择器选中单个元素:

>>> d('p').eq(0)
[<p#hello.hello>]

你可以找出嵌套元素:

>>> d('p').find('a')
[<a>, <a>]
>>> d('p').eq(1).find('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>]

网络 Scraping

pyquery也可以从一个url载入html文档:

>>> pq(your_url)
[<html>]

缺省使用的是python的urllib。

如果安装了requests就使用requests。你可以使用大部分requests的参数。

>>> pq(your_url, headers={'user-agent': 'pyquery'})
[<html>]
>>> pq(your_url, {'q': 'foo'}, method='post', verify=True)
[<html>]

pyquery ? PyQuery完整API参见:http://pyquery.readthedocs.org/en/latest/api.html

pyquery.ajax ? PyQuery AJAX 扩展

如果安装了WebOb(它并不是pyquery的依赖项目),你可以查询一些wsgi app。在本例中,测试app在/处返回一个简单的输入,在/submit处返回一个提交按钮: IN this example the test app returns a simple input at / and a submit button at /submit:

>>> d = pq('<form></form>', app=input_app)
>>> d.append(d.get('/'))
[<form>]
>>> print(d)
<form><input name="youyou" type="text" value=""/></form>

app在新节点中也可用: The app is also available in new nodes:

>>> d.get('/').app is d.app is d('form').app
True

你也可以请求另外一个路径:

>>> d.append(d.get('/submit'))
[<form>]
>>> print(d)
<form><input name="youyou" type="text" value=""/><input type="submit" value="OK"/></form>

如果安装了restkit,你就可以直接从一个HostProxy app获取url:

>>> a = d.get(your_url)
>>> a
[<html>]

你可以获取到app的响应:

>>> print(a.response.status)
200 OK

小贴士 Tips

你可以使链接转化为绝对链,在屏幕抓取时还会比较有用: You can make links absolute which can be usefull for screen scrapping:

>>> d = pq(url=your_url, parser='html')
>>> d('form').attr('action')
'/form-submit'
>>> d.make_links_absolute()
[<html>]

使用不同的解析器

缺省情况下,pyquery使用lxml xml解析器并且如果它不能工作的话,继续尝试lxml.html中的html解析器。xml解析器在解析xhtml页面时可能出现一些问题,因为解析器不会抛出一个错误,而是给出一个不能用的树。 The xml parser can sometimes be problematic when parsing xhtml pages because the parser will not raise an error but give an unusable tree (on w3c.org for example).

你也可以显式地声明使用哪一个解析器:

>>> pq('<html><body><p>toto</p></body></html>', parser='xml')
[<html>]
>>> pq('<html><body><p>toto</p></body></html>', parser='html')
[<html>]
>>> pq('<html><body><p>toto</p></body></html>', parser='html_fragments')
[<p>]

html和html_fragments解析器都在lxml.html当中。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python3使用urllib示例取googletranslate(谷歌翻译)
Jan 23 Python
python使用xlrd模块读写Excel文件的方法
May 06 Python
python爬虫实现教程转换成 PDF 电子书
Feb 19 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 Python
基于Python闭包及其作用域详解
Aug 28 Python
Python中使用Counter进行字典创建以及key数量统计的方法
Jul 06 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 Python
详解Django的model查询操作与查询性能优化
Oct 16 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
Jan 15 Python
Python设计模式之外观模式实例详解
Jan 17 Python
selenium+python自动化测试之鼠标和键盘事件
Jan 23 Python
django ManyToManyField多对多关系的实例详解
Aug 09 Python
python 检查数据中是否有缺失值,删除缺失值的方式
Dec 02 #Python
python实现两个字典合并,两个list合并
Dec 02 #Python
Python:合并两个numpy矩阵的实现
Dec 02 #Python
DataFrame.to_excel多次写入不同Sheet的实例
Dec 02 #Python
python实现数据清洗(缺失值与异常值处理)
Dec 02 #Python
python字符串反转的四种方法详解
Dec 02 #Python
python实现两个一维列表合并成一个二维列表
Dec 02 #Python
You might like
造势之举?韩国总统候选人发布《星际争霸》地图
2017/04/22 星际争霸
Yii实现多数据库主从读写分离的方法
2014/12/29 PHP
PHP7.0安装笔记整理
2015/08/28 PHP
php学习笔记之mb_strstr的基本使用
2018/02/03 PHP
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
2012/01/15 Javascript
javascript解析json实例详解
2014/11/05 Javascript
javascript操作符&quot;!~&quot;详解
2015/02/10 Javascript
js实现横向伸展开的二级导航菜单代码
2015/08/28 Javascript
Webpack 实现 Node.js 代码热替换
2015/10/22 Javascript
JavaScript黑洞数字之运算路线查找算法(递归算法)实例
2016/01/28 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
2016/05/11 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
手机Web APP如何实现分享多平台功能
2016/08/19 Javascript
AngularJS实现select的ng-options功能示例
2017/07/12 Javascript
JS实现的加减乘除四则运算计算器示例
2017/08/09 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
[40:06]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第一场
2018/04/04 DOTA
Python 爬虫学习笔记之正则表达式
2016/09/21 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
python实现对指定字符串补足固定长度倍数截断输出的方法
2018/11/15 Python
python二元表达式用法
2019/12/04 Python
Python3运算符常见用法分析
2020/02/14 Python
Python解释器以及PyCharm的安装教程图文详解
2020/02/26 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
Europcar德国:全球汽车租赁领域的领导者
2018/08/15 全球购物
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
Richards网上商店:当代时尚,遍布巴西
2019/11/03 全球购物
成教自我鉴定
2013/10/27 职场文书
幼儿园教师国培感言
2014/02/02 职场文书
安全标语口号
2014/06/09 职场文书
一份关于丢失公司财物的检讨书
2014/09/19 职场文书
水浒传读书笔记
2015/06/25 职场文书
python opencv人脸识别考勤系统的完整源码
2021/04/26 Python
Python编写车票订购系统 Python实现快递收费系统
2022/08/14 Python