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 相关文章推荐
gearman的安装启动及python API使用实例
Jul 08 Python
在Python中使用判断语句和循环的教程
Apr 25 Python
详解Python中find()方法的使用
May 18 Python
python简单获取本机计算机名和IP地址的方法
Jun 03 Python
Python脚本实现Web漏洞扫描工具
Oct 25 Python
python 编程之twisted详解及简单实例
Jan 28 Python
Python 创建空的list,以及append用法讲解
May 04 Python
Scrapy-Redis结合POST请求获取数据的方法示例
May 07 Python
基于Python实现人脸自动戴口罩系统
Feb 06 Python
Python自定义聚合函数merge与transform区别详解
May 26 Python
python实现批量命名照片
Jun 18 Python
Python暴力破解Mysql数据的示例
Nov 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
php产生随机数的两种方法实例代码 输出随机IP
2011/04/08 PHP
PHP实现文件下载断点续传详解
2014/10/15 PHP
thinkPHP批量删除的实现方法分析
2016/11/09 PHP
PHP让网站移动访问更加友好方法
2019/02/14 PHP
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
php+js实现倒计时功能
2014/06/02 Javascript
javascript限制用户只能输汉字中文的方法
2014/11/20 Javascript
jQuery层级选择器用法分析
2015/02/10 Javascript
以Python代码实例展示kNN算法的实际运用
2015/10/26 Javascript
Jquery easyui开启行编辑模式增删改操作
2016/01/14 Javascript
JavaScript判断数组是否存在key的简单实例
2016/08/03 Javascript
AngularJS教程之环境设置
2016/08/16 Javascript
BootStrap按钮标签及基本样式
2016/11/23 Javascript
vue router自动判断左右翻页转场动画效果
2017/10/10 Javascript
vue代码分割的实现(codesplit)
2018/11/13 Javascript
JS实现的合并两个有序链表算法示例
2019/02/25 Javascript
[01:51]DAC趣味视频-如何成为职业选手.mp4
2017/04/02 DOTA
21行Python代码实现拼写检查器
2016/01/25 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
python中Apriori算法实现讲解
2017/12/10 Python
Python中函数的基本定义与调用及内置函数详解
2019/05/13 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
阿根廷首家户外用品制造商和经销商:Montagne
2018/02/12 全球购物
亚洲领先的设计购物网站:Pinkoi
2020/11/26 全球购物
自主实习接收函
2014/01/13 职场文书
2014年关工委工作总结
2014/11/17 职场文书
项目建议书
2015/02/04 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
2016年助残日旅游活动总结
2016/04/01 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
测量JavaScript函数的性能各种方式对比
2021/04/27 Javascript
Python实现单例模式的5种方法
2021/06/15 Python
教你利用Nginx 服务搭建子域环境提升二维地图加载性能的步骤
2021/09/25 Servers
JavaScript实现队列结构过程
2021/12/06 Javascript