python:html元素解析
说明
主要是总结我通过python实现html解析的一个初步的思路和记录实现基础html解析的代码。本解析方式仅仅
只是实现了html按元素解析的功能,具体元素的分类获取还得需要再进行进一步的优化。
html解析
html解析,当前实现我将其分为两个部分:一个是元素节点的定义,一个是元素节点解析。
1) 解析实现
解析通过html的节点进行控制,通过遍历html中的所有节点,对节点进行数据描述。html中的节点(即元素)
格式为:
<element ..../> #单闭合
<element ...>....</element> #节点闭合
目前支持这两类节点的解析(对于不规范的节点书写解析当前或存在一些问题),通过对节点的数据的定义(节点
名称,节点状态(start,end),节点包含文本,节点包含属性等),python实现通过定义类对象对元素进行定
义。代码如下:
class Element:
elementName="Doucument"
START_DOCUMENT = 0
START_HTML = 1
START_HEAD = 2
END_HEAD = 3
START_BODY =4
END_BODY=5
START_ELEMENT=6
END_ELEMENT=7
ELEMENT_TEXT=8
END_HTML=9
END_DOCUMENT=10
NO_ELEMENT=100
'''
html基本元素
elementName:元素名称(header,body之类)
text:元素包含文本内容
'''
def __init__(self,elementName=None,text=None,id=None,**attributes):
if elementName:
self.elementName=elementName
if text:
self.text=text
if id:
self.id=id
if attributes and len(attributes)>0:
self.attributes=attributes
self.content=None
self.elementDict={}
def getElementId(self):
return self.id
def toString(self):
if self.content:
return self.content
else:
buffer=""
if self.attributes and len(self.attributes):
for key in self.attributes:
if len(buffer):
buffer = "%s=\"%s\"" % (key[0],key[1])
else:
a=buffer
buffer="%s %s=\"%s\"" %(a,key[0],key[1])
if self.text and len(self.text):
return "<%s %s> %s </%s>" %(self.elementName,buffer,self.text,self.elementName)
else:
return "<%s %s/>" % (self.elementName,buffer)
@staticmethod
def element(content=None):
# print "content:%s" % content
element = Element()
if content and len(content.strip().rstrip())>0:
eleStr=content.strip().rstrip()
element.content=content
if len(eleStr) and not eleStr.startswith("<"):
'''
text 内容
'''
element.elementName=Element.elementName
element.text=eleStr
element.id=Element.ELEMENT_TEXT
elif len(eleStr) and eleStr.startswith("<"):
'''
标签内容
'''
if eleStr.startswith('</'):
'''
element 结束符号
'''
element.id=Element.END_ELEMENT
element.elementName=eleStr[2:len(eleStr)-1]
if element.elementName:
if hasattr(element,"END_"+element.elementName.upper()):
element.id=getattr(element,"END_"+element.elementName.upper())
else:
element.id=Element.END_ELEMENT
else:
'''
element 开始符号
'''
element.id=Element.START_ELEMENT
params_str=None
if eleStr.endswith("/>"):
params_str=eleStr[1:-2]
else:
params_str=eleStr[1:-1]
if not params_str:
assert "Unpredictable error."
params=params_str.split()
element.elementName=params[0]
attr_dict = {}
prev_key=None
for attr in params[1:]:
if "=" in attr:
attr_map=attr.split("=")
key=attr_map[0].strip().rstrip()
value_str=attr_map[1].strip().rstrip()
index=len(value_str)
value=value_str[1:index-1]
attr_dict[key]=value
prev_key=key
else:
if attr.endswith("\""):
attr_dict[prev_key]+=" "+attr[:-1]
else:
attr_dict[prev_key] += " " + attr
if len(attr_dict) >0:
element.attributes=attr_dict
if hasattr(element,"START_"+element.elementName.upper()):
element.id = getattr(element, "START_" + element.elementName.upper())
else:
element.id=Element.START_ELEMENT
Element.elementName=element.elementName
else:
element.elementName=None
element.text=None
element.attributes=None
element.id=Element.NO_ELEMENT
return element
2) 解析实现
html解析通过标志”<”和”>”实现对html元素的解析,解析实现通过生成器的方式,逐个迭代。解析主要分为
三个类型:
简单的单个元素集合
单一开始和结束元素集合,格式如下:
<html> #单一开始 </html> #单一结束
单封闭(自封闭)元素集合
自封闭的元素单独处理,会自动迭代成开始标签和结束标签,格式如下:
<input type="submit" value="Submit" /> #自封闭
元素文本数据
元素文本单独处理,是处于元素开始和结束标签之间的文本数据,依赖文本之前的开始标签
如上,为基本的格式介绍,python解析代码如下所示:
import codecs
from params import *
class Parser:
'''
html parser class.
'''
def __init__(self,fileName=None):
self.fileName=fileName
self.begin=0
self.over=0
self.index=0
def parser(self):
if not self.fileName:
raise "File not found."
with codecs.open(filename=self.fileName, mode='r', encoding='utf-8') as inputfile:
content = inputfile.read()
if (not content) or len(content.strip().rstrip())==0:
raise "get file content false."
content=unicode(content.strip().rstrip())
# print "total content:", content
try:
index=content.index("<html") if ("<html" in content) else content.index("<html")
except BaseException as error:
print "parse erro:",str(error)
assert True
content=content[index:]
# print "get content:",content
#----------------------------------begin parser-------------------------
yield Element.element("<DOCUMENT>")
while True:
try:
self.begin= content.index("<",self.over) #element begin index.
if self.begin> self.over:
text=content[self.over+1:self.begin].strip().rstrip()
if text and len(text)>0:
yield Element.element(text)
self.over= content.index(">",self.begin) #element end index
elementStr=content[self.begin:self.over+1].rstrip().strip()
# print "elementStr:",elementStr
if elementStr and len(elementStr):
if elementStr.startswith("<!"):
pass
elif elementStr.endswith("/>"):
yield Element.element(elementStr[:-2]+">")
yield Element.element("</"+elementStr.split()[0][1:]+">")
else:
yield Element.element(elementStr)
except BaseException as error:
print "index error:",str(error)
break
#-------------------------------end parser----------------------------------
yield Element.element("</DOCUMENT>")
3) 使用
完成如上的解析操作,使用就简单很多,直接通过for循环遍历,具体操作需要自行解析,代码如下:
import codecs,sys,socket
from parser import *
fileName = "test.html"
content = ""
parser=Parser(fileName)
a=parser.parser()
for b in a:
if b.elementName == 'img':
print "img url is:", b.attributes['src']
如上,即是一个简易版的html解析实现,
示例代码在:https://github.com/fishly/graphicsProject-/tree/master/robots/htmlpraser
python:html元素解析的更多相关文章
- 转 web项目中的web.xml元素解析
转 web项目中的web.xml元素解析 发表于1年前(2014-11-26 15:45) 阅读(497) | 评论(0) 16人收藏此文章, 我要收藏 赞0 上海源创会5月15日与你相约[玫瑰里 ...
- python中html解析-Beautiful Soup
1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.pyt ...
- Python迭代和解析(1):列表解析
解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html Python中的解析 Python支持各种解析(comprehensio ...
- Python之XML解析详解
什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这 ...
- python实现XML解析的三种方法
python实现XML解析的三种方法 三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合:二是xml.sax.*模块,它是SAX API的实 ...
- python统计元素重复次数
python统计元素重复次数 # !/usr/bin/python3.4 # -*- coding: utf-8 -*- from collections import Counter arr = [ ...
- python学习(解析python官网会议安排)
在学习python的过程中,做练习,解析https://www.python.org/events/python-events/ HTML文件,输出Python官网发布的会议时间.名称和地点. 对ht ...
- python爬虫数据解析之BeautifulSoup
BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. BeautfulSoup是python爬虫三 ...
- python命令行解析模块--argparse
python命令行解析模块--argparse 目录 简介 详解ArgumentParser方法 详解add_argument方法 参考文档: https://www.jianshu.com/p/aa ...
随机推荐
- easyswoole对接支付宝,微信支付
在easyswoole中,已经开发好了相关的支付组件,只需要引入即可: composer require easyswoole/pay pay组件支持协程 支付宝 支付方法 支付宝支付目前支持 7 种 ...
- SSM框架之spring(1)
spring(1) 1.spring概述 Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP( ...
- Java开发人员必备十大工具
Java世界中存在着很多工具,从著名的IDE(例如Eclipse,NetBeans和IntelliJ IDEA)到JVM profiling和监视工具(例如JConsole,VisualVM,Ecli ...
- google跟踪代码管理器gtm无法给相同class元素绑定click事件埋点解决
Google 跟踪代码管理器是一个跟踪代码管理系统 (TMS),可以帮助您快速轻松地更新网站或移动应用上的跟踪代码及相关代码段(统称为“代码”).将一小段跟踪代码管理器代码添加到项目后,您可以通过网页 ...
- 简单快速上手Jackson使用
1简介 Jackson具有比较高的序列化和反序列化效率,据测试,无论是哪种形式的转换,Jackson > Gson > Json-lib,而且Jackson的处理能力甚至高出Json-li ...
- 通过Android反编译技术研究国内陌生人社交即时通讯的技术方案
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/100 即时通讯IM类App分析 这两周对国内陌生人社交领域 ...
- OC深浅复制
浅复制:指针的复制 深复制:内容的复制 主要有两个关键字 copy 和mutablecopy 对于基本类型 判断深浅方法 1.只要=右边从创建到赋值,至少包含一个NSMutable便会重新生成一个对 ...
- 未能找到元数据文件**.dll解决办法
解决方案里有很多项目.生成时提示100多个错误,都是未能找到元数据文件**.dll. 那就清理一下解决方案,一个一个来吧. 生成GateWay.Utilities项目时,虽然提示成功了,却发现bin/ ...
- TypeScript 学习笔记(四)
函数: 1.函数是一组一起执行一个任务的语句 2.我们可以把一段可复用的代码放到一起组成函数,从而提高效率 3.函数声明(通过关键字 function 来声明)告诉编译器函数的名称.返回类型和参数 4 ...
- 微信小程序API交互反馈,wx.showToast显示消息提示框
导读:wx.showToast(OBJECT) 显示消息提示框. OBJECT参数说明: 参数 类型 必填 说明 最低版本 title String 是 提示的内容 icon String 否 图标, ...