lxml的另一种用法
python中lxml库是一个十分强大的xml解析库,最近在看《白帽子将web扫描》这本书的时候,里面提供了一种不同于以往的用法,因此在这将这个方法记录下来
传统的lxml库的使用方法类似于下面这样:
from lxml import etree
tree = etree.HTML(html) #假定html是一个html文本字符串
tag_a = tree.xpath("//a")
这是一种DOM的解析方法,它事先生成了一个一个dom树tree,然后在树中根据xpath字符串筛选出我们想要的元素,至于具体的用法就不再在这演示了,百度lxml可以搜到很多东西
书中提供了一种类似于SAX模型的解析方法,但是又有些不同,SAX模型一般有一些固定的函数需要去重写,比如进入到标签中和退出标签等等。在这种情况下,我们只知道它进入到了标签开始位置,但是并不知道进入的是何种标签。书中的那个写法达到了一个很好的效果,它能做到为每一个标签定义一个对应的处理函数,比如刚进入到a标签,就会调用我们自己定义的处理这个事件的函数,并且可以获取它对应的属性的列表,废话不多说,直接上代码:
from lxml import etree
class HtmlParser:
def __init__(self):
#在函数中定义一些属性,比如解析出来的url或者希望保存的中间变量
parser = etree.HTMLParser(target=self, recover=True, encoding='utf-8')
try:
etree.fromstring(self._html, parser)
except ValueError:
pass
def start(self, tag, attrbs):
meth = getattr(self, "_handle_" + tag + "_tag_start")
meth(tag, attrbs)
def _handle_a_tag_start(self, tag, attrbs):
#dosomething
pass
def end(tag):
meth = getattr(self, "_handle_" + tag + "_tag_end")
meth(tag, attrbs)
在调用fromstring()将字符串转化为dom时每当进入一个标签开始位置将调用start函数,而当即将离开该标签时调用end函数,start函数传入标签名tag和标签的属性列表attrbs。在这两个函数中使用getattr函数获取类中对应名称的函数,这个函数名称以标签名作为唯一标识,如果有该函数则调用,这样根据不同函数的调用就知道到了哪个标签里面,针对不同的标签编写不同的处理代码即可。
lxml的另一种用法的更多相关文章
- using 的三种用法
using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...
- c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...
- Wix 安装部署教程(十五) --CustomAction的七种用法
在WIX中,CustomAction用来在安装过程中执行自定义行为.比如注册.修改文件.触发其他可执行文件等.这一节主要是介绍一下CustomAction的7种用法. 在此之前要了解InstallEx ...
- Android Intent的几种用法全面总结
Android Intent的几种用法全面总结 Intent, 用法 Intent应该算是Android中特有的东西.你可以在Intent中指定程序要执行的动作(比如:view,edit,dial), ...
- Js闭包常见三种用法
Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...
- operator 的两种用法
C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).1.操作符 ...
- Service的两种用法及其生命周期
先来一点基础知识: Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作).Servic ...
- C#中this的 四种 用法
C#中的this用法,相信大家应该有用过,但你用过几种?以下是个人总结的this几种用法,欢迎大家拍砖,废话少说,直接列出用法及相关代码. this用法1:限定被相似的名称隐藏的成员 /// < ...
- js正则表达式中的问号几种用法小结
这篇文章主要介绍了js正则表达式中的问号几种用法,比如+?,*?,{2,3}?可以停止匹配的贪婪模式,感兴趣的朋友可以参考下 在表示重复的字符后面加问号,比如+?,*?,{2,3}?可以停止匹配的贪婪 ...
随机推荐
- Activiti源代码分析
ExecutionEntity内部含有parent,是一个运行树或运行路径.应该是一个流程实例的运行过程,一个实例相应一个ExecutionEntity,通过getActivity得到的是当前正在运行 ...
- git命令的使用
git命令行的使用 0. 工作中常使用的命令行(小结) 假设我们工作共同使用的开发分支为dev,我自己的开发分支为dev_cx.安装git,在工作文件夹下打开git bash. $ git check ...
- Python的几个常用模块
一.sys 用于提供对Python解释器相关的操作: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version ...
- 用IFeatureWorkspaceAnno.CreateAnnotationClass 创建注记图层时报“The application is not licensed to modify or create schema”的错误的解决方案。
用IFeatureWorkspaceAnno.CreateAnnotationClass 的方法创建注记图层的时候报"The application is not licensed to m ...
- Apache反向代理的配置
Apache反向代理的配置 一: Mac系统自带apache服务器 1. 查看apache版本命令如下: sudo apachectl -v 2. 启动apache sudo apachect ...
- 【java设计模式】【创建模式Creational Pattern】建造模式Builder Pattern
package com.tn.pattern; public class Client { public static void main(String[] args) { Director dire ...
- iOS MJRefresh上拉加载更多
1.导入MJRefresh包 2.在类中引入:#import "MJRefresh.h" 3.添加footerView 添加加载更多的UI样式: MJRefreshAutoNorm ...
- Libevent源码分析 (1) hello-world
Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...
- [数据结构]C语言队列的实现
我个人把链表.队列.栈分为一类,然后图.树分为一类.(串不考虑),分类的理由就是每一类有规律可循,即你能通过修改极少数的代码把链表变成队列.栈.(这里我们不考虑其他诸如设计模式等因素),因此本贴在讲完 ...
- js的Date对象
1.构造Date对象 var dt = new Date(); //获取当地包含日期和时间的对象,格式为:Thu Aug 31 2017 09:15:43 GMT+0800 (中国标准时间) 2.使用 ...