本文实例讲述了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数据结构与算法教程》、《Python加密解密算法与技巧总结》、《Python编码操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》
希望本文所述对大家Python程序设计有所帮助。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?