Python lxml教程

lxml是Python处理xml文档的一个库,速度快,易编程,可以“make life easier”。这篇文章是lxml的快速上手教程。

XML在lxml中的表示

在DOM中,文档是以节点(node)的形式组织的。某节点又有子节点,表示Elements,Attributes,Text等。

例如,下面这个DOM可以用如图所示的节点组织。

在lxml中,只有Element,Element有子Element,构成一棵树。Element有一下属性:

  • .tag – element的名字,比如“p”或“em”等
  • .text – 元素的文本内容,从开头到第一个子节点。如果从开头到一个子节点没有内容,那么就是None。比如p的text是”To find out”
  • .tail – 元素后面的内容,到下一个元素为止。比如em的tail是”, see the”
  • .attrib – 元素的属性。“<h2 class="arch" id="N15">”的.attrib就是 “{"class": "arch", "id": "N15"}
  • (子元素列表) – Element的很多行为都和list类似,可以用来索引。比如Element[0]就是表示Element的第1个子元素。可以使用len()查看这个Element一共有多少个子元素

上面的DOM使用lxml的Element表示:

注意.tail,比如,”,see the \n”本来在DOM中是p的节点,但是在lxml里成为了em的.tail属性。

操作Element

在lxml中,一个Element实体的表现和Python的list很相似,可以使用len()获得这个Element的子元素的数量,可以使用下标操作子元素,可以使用replace(), delete()等方法。假设E是一个Element实体,那么可以进行以下操作。

  • 通过E[i]获得第i+1个元素
  • 通过E[start:end]获得从start到end之间的元素
  • 可以通过下标替换一个元素:E[i] = c
  • 删除一个元素:del E[i]
  • 通过循环迭代所有元素:
  • 通过append()添加子元素
  • 使用clear()将子元素清空,此外:
    • .attrib字典将清空
    • tail和text将设置为None

此外,Element还有一些其他的方法。

Element.find()

找到和path匹配的元素,如果有多个,返回第一个。可以查找子元素的子元素,”tag1/tag2/…/tagn“。

Element.findall()

找到所有匹配的元素,以列表的形式返回。

Element.findtext()

找出所有和path(path是Element的后代即可)匹配的元素中的文本。如果有多个,返回第一个。如果匹配path但是元素没有文本,返回”(default在这种情况下不会使用)。

Element.get()

获得一个attribute的值,如果没有,使用default。

Element.getchildren()

获得所有子元素(感觉这方法和元素本身一样啊……)

Element.getiterator()

得到元素的迭代器。如果tag省略,元素本身会作为第一个元素。

比如遍历下面这个树。

Element.insert()

插入一个新的子元素。

Element.items()

就和字典的items()一样,会返回一个tuple的list。

Element.iterancestors()

和Element.getiterator()类似,不过是从当前节点开始,往上遍历祖先,直到遍历到根目录。

Element.keys()

返回所有attributes的key。

Element.xpath()

非常常用的一个方法,关于xpath有太多要说的了,以后再写吧……

参考资料

  1. Python XML processing with lxml
 

VimScript学习笔记(12):快速开关(Toggle)

Toggle

在前面的章节中,我们介绍过设置Vim的一种方式。使用叹号可以快速将布尔变量设置为相反的值(set someoption!)。把常用的设置映射成快捷键会非常实用。

但是这只对布尔类型的设置有用。对于需要提供参数来设置的项目,就不能用这种方法进行快速设置了。

Toggle选项

在这种情况下,我们可以定义一个函数,然后将某个函数map到这个快捷键。这里用foldcolumn举例,这个设置是在左边打开/关闭代码折叠的层级的。

toggle=0 关闭

foldcolumn=4 显示4个层级

下面的代码可以快速设置foldcolumn为0或4切换。将代码复制到~/.vimrc中然后source一下。

再举一个例子,下面的代码可以快速开关quickfix窗口。

但问题是,关闭窗口的时候会跳到最后一个窗口,我们关闭的时候跳到之前打开的窗口。可以在打开quickfix的时候记录一下是哪个窗口。

 

突如其来的一千块

前段时间一直在忙毕业设计的事情,实习的公司请了很多假,到手的工资很少。自己业余时间还有些额外收入,前几天老板打电话,问最近忙不,进度有些慢。我也发现自己很少顾及这边,就说这个月少要1000块钱吧。

到下个月就没什么收入了,都没钱交下个月的房租了,就差这1000块钱了,说是少要了,又不能厚着脸皮反悔。

正发愁呢,结果今天玩手机,随便打开中国银行的app(真的是随便打开的,因为之前CSDN的稿费不定时打,所以平时没事就会打开app看看),发现竟然多了七百多块钱。这卡已经不使用很久了,只有CSDN会给我打稿费,还有就是学校的钱都进这个卡。我已经半年多没写稿子了,只可能是学校。最大的可能是之前的实习补贴吧,可是实习在12月份就结束了,我以为早就已经都结算清了……

然后晚上(就是刚刚),在超市买东西的时候往支付宝里充钱,发现一直充不进去。原来选的是早已经不用的一张卡,可是昨天也是这么用的啊…… 我又试着用这张“废卡”充了10块,发现充进去了。查了查账单,原来最近用的一直是这张卡里的钱,我以为用的是一张常用卡,而常用卡的钱压根就没少!“废卡里”大约有将近三百。思前想后,真想不起来什么时候还在这张卡里剩了300块钱。我的Mac电脑又上不了网银查明细。

开头说的那个老板,之前还有一个事情。

3年前我在那里兼职,十月一的时候,我在俱乐部给老板值班,也没说好给多少钱。假期结束之后,老板给我四百,我说“哇,这么多”。老板说,嫌多啊,那我拿回来一张。最后就给了我三百。这件事后来我跟我爸说了,我爸说,从这件事就看出来你还年轻。

今年回家的时候,妈妈又提起来这件事,说每次想起来就觉得心疼,你还是个学生,那个老板怎么这么狠心,给你的钱又要回去呢。这件事我都忘记了,妈妈一直还记得。其实这件事我也没怎么放在心上,也就难受了一小会,所以后还和他合作。

这一千块钱,真是意外的惊喜。可能,是妈妈在帮我吧。

 

自行更换卡西欧电子表电池

高中的时候从亚马逊买了一块卡西欧手表,型号是SGW-400H,电子指针双显的,还带压强和温度传感器。说起来,也服役六年了,卡西欧的质量真是好。最近突然发现它没电了,在网上查了一下,去徐家汇维修需要60元,又在淘宝搜了一下这个型号的电池,只需要27元,作为工科生,这趟路费和手工费省了。

淘宝买零件这种东西真是实惠,发来一看,竟然是两块电池,还附赠这么多工具和防水膏。

一般的电子表都不用拆表带的,直接卸下螺丝就可以打开(有些机械表可能要掰开的)。

打开之后,发现电池后面贴着一行提示“After battery replacement, contact AC with (-) using tweezers.”意思是换过电池之后,要用镊子把负极和AC短接一下。虽然不明白是什么,但是网上说不这么做可能会有奇怪的事情发生。写AC和-的地方很好找,都是小孔,标的很明白。我这次更换电池并没有短接,一切正常。

接下来的换电池步骤分三步:打开电池盖,换电池,合上电池盖。

开电池的地方是没有弹簧的,需要用镊子强行打开。

换好电池之后,把黑色的垫圈按照轨道铺好(见上面的图),涂防水膏。不用太多,湿了就好。垫圈很软,涂的时候很容易活动,需要有耐心。

涂好之后,盖上盖子,上螺丝。完成。

 

 

微信和telegram

使用telegram一段时间之后,深深地爱上了这款软件。第一次得知telegram,是通过这篇比较有名的文章——《Telegram传奇:一个关于俄罗斯富豪、黑客、极权和阴谋的创业故事》。当时下载下来,身边几乎没有朋友使用,就删掉了。最近发现telegram开放了机器人的api(其实是上一年的事情了),又重新下载来,写bot玩儿,顺便推荐给几个朋友一起用一用。发现原来这是如此优秀的一款软件!对比国内最火爆的微信,简直完爆。

我个人信奉的一个哲学是:做一件事,做好它。从软件来说,一个软件应该把应该有的功能做到极致,对于不属于自己的功能,交给其他专业的软件去做。很显然,telegram和微信,就是两个不同的典型。

微信是一个“巨型”的app,目前,微信6.5.8版本是183M,而这时候的telegram(3.18)是64M。其实,这还是压缩之后的,一般下载微信之后使用一段时间,微信占用的内存就会上升到几G,除了聊天资料之后,应用内很多模块都是web形式提供的,可以在app安装之后从服务器在下载。

微信的野心很大,除了聊天,还有公众号,有游戏,发“朋友圈”,甚至还有小程序,这几乎想去替代一个操作系统了。而telegram呢,除了聊天,再没有其他功能了。

既然大家都是IM软件,那么聊天功能,这两家的表现如何呢?随便一想,就可以数出一堆telegram完爆微信的地方:

  • telegram提供搜索功能,搜索的时候直接定位在信息中,所见即所得,可以从日历中选择日期搜索,可以直接在分享过的[links,files,media]中搜索,微信的搜索结果展示在一个列表中……
  • telegram在群组聊天中可以选择reply某一条信息,forward某一条信息(会带上原信息的主人),而微信,你转发的就成了你的,在群聊中更是混乱,在说什么都不知道。
  • telegram可以删除(为收信人删除)信息,可以编辑发送过的信息。而微信……你可能会尴尬的被人问,“你到底撤回了什么?”
  • 打开telegram的时候,你停留在上次看到的地方,就像标签一样,可以往下翻直到最新的信息;而微信,是让你从下往上翻的……如果一段时间没看群聊,再回来的时候你发现自己已经淹没在了信息里。

telegram的端对端通讯功能

关于聊天,有一个最重要的功能。今天的很多IM软件(比如whatsapp),都实现了IM的基本功能——端对端通讯。也就是不经过服务器直接由发送方发消息到接收方。而微信,不管由于技术方面或者由于政策方面,目前没有、将来也不可能有这个功能。

除此之外,界面上,微信自创一套界面,还要求很多基于微信的小程序、web app都遵守它的界面规范,而telegram完美符合google和苹果的界面规范。什么是美,大家都心里有数。平台方面,你也可以说微信的web端就是支持全平台了,但是telegram,有linux版,mac os app,ios,android,chrome app,windows桌面版,而且都是适配各种系统界面,功能一致的。微信的桌面版好像不能处理红包类型的消息和gif吧?有一点我恨不能忍受的是,为什么别的地方登录还需要手机去扫个码呢?我手机没电了想用电脑微信也用不了。

开放是互联网的核心精神。微信要做的,却是与开放背道而驰。小程序,公众号,朋友圈,这些都很难被搜索引擎收录。大概是想自己做一个独特的互联网出来吧。能把url设计成这个样子的app,可能从一开始就没想过“开放”二字。

微信公众号发布的文章冗长的url

而telegram,你可以通过url分享任何东西(url在微信中会先经过微信服务器然后跳到目标url),而且提供了bot这种好东西。在我看来,bot比微信公众号、服务号、小程序高到了不知道哪里去。用bot你可以开发出无数好玩的东西出来(甚至可以用它来收发微信消息),小程序能干的事情它都能干,而且权限也比小程序高,你也可以写一个发布资讯的小程序,完美的“公众号bot”,比如techchurch,就有官方的bot。众所周知,申请公众要、服务号,要提供一大堆个人资料,审核繁琐,比如这位。而申请一个telegram的bot呢?简单到不可想象!telegram里面有个botfather(对,长的很像god father!其实botfather也是一个bot),你只要告诉他,你想要一个bot,就完成了……就是这么简单。

申请一个新bot只是一句话的事儿

bot father

有人可能会说,这么好用有什么用,微信用户是telegram的几百倍?我想说,可能人家就没想做成微信那样,看看《Telegram传奇:一个关于俄罗斯富豪、黑客、极权和阴谋的创业故事》这篇文章就知道了。Twitter市值已经落后weibo40多亿了,但是那又如何呢?还是改变不了weibo是一坨屎的事实。好歹twitter不会迫于淫威删用户内容,weibo呢?先做到不随意给用户加关注,乱发广告再说吧。

屎就是屎,就算你造一堵墙,把好东西都档在外面,用臭味覆盖了整个房子,把房子熏成厕所,我也不承认这坨屎好。