说明

主要是总结我通过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

Enjoytoday,EnjoyCoding

python:html元素解析的更多相关文章

  1. 转 web项目中的web.xml元素解析

    转 web项目中的web.xml元素解析 发表于1年前(2014-11-26 15:45)   阅读(497) | 评论(0) 16人收藏此文章, 我要收藏 赞0 上海源创会5月15日与你相约[玫瑰里 ...

  2. python中html解析-Beautiful Soup

    1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.pyt ...

  3. Python迭代和解析(1):列表解析

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html Python中的解析 Python支持各种解析(comprehensio ...

  4. Python之XML解析详解

    什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这 ...

  5. python实现XML解析的三种方法

    python实现XML解析的三种方法 三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合:二是xml.sax.*模块,它是SAX API的实 ...

  6. python统计元素重复次数

    python统计元素重复次数 # !/usr/bin/python3.4 # -*- coding: utf-8 -*- from collections import Counter arr = [ ...

  7. python学习(解析python官网会议安排)

    在学习python的过程中,做练习,解析https://www.python.org/events/python-events/ HTML文件,输出Python官网发布的会议时间.名称和地点. 对ht ...

  8. python爬虫数据解析之BeautifulSoup

    BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. BeautfulSoup是python爬虫三 ...

  9. python命令行解析模块--argparse

    python命令行解析模块--argparse 目录 简介 详解ArgumentParser方法 详解add_argument方法 参考文档: https://www.jianshu.com/p/aa ...

随机推荐

  1. GPS NMEA-0183协议常用报文数据格式

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 整理的GPS有关的协议分析资料." 之前分析一些车载设备的流量时,有部分经验,在这里和大家分享. 产生这些流量的设备通常是实体终端 ...

  2. 用了这么久HTTP, 你是否了解Content-Length?

    摘要: 理解HTTP协议... 原文:用了这么久HTTP, 你是否了解Content-Length和Transfer-Encoding ? 作者:朴瑞卿的博客 由Content-Length导致的问题 ...

  3. C Primer Plus 第六版—— 6.16 编程练习题(附代码)

    1.编写一个程序,创建一个包含26个元素的数组,并在其中存储26个小写字母.然后打印数组的所有内容. #include <stdio.h> int main(void) { int num ...

  4. 机器学习--PCA算法代码实现(基于Sklearn的PCA代码实现)

    一.基于Sklearn的PCA代码实现 import numpy as np import matplotlib.pyplot as plt from sklearn import datasets ...

  5. 机器学习--主成分分析(PCA)算法的原理及优缺点

    一.PCA算法的原理 PCA(principle component analysis),即主成分分析法,是一个非监督的机器学习算法,是一种用于探索高维数据结构的技术,主要用于对数据的降维,通过降维可 ...

  6. leetcode 752. 打开转盘锁

    地址 https://leetcode-cn.com/problems/open-the-lock/ 你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字: '0', '1', '2', '3', ...

  7. python(leetcode)498. 对角线遍历

    这题难度中等,记录下思路 第一个会超时, 第二个:思想是按斜对角线行进行右下左上交替遍历, def traverse(matrix): n=len(matrix)-1 m=len(matrix[0]) ...

  8. WPF 精修篇 page

    原文:WPF 精修篇 page 前言 前段时间看UML 大象 这本书 虽然马上看到了精华片 最后还是暂时暂停 因为这本书 很好 但是暂时对现在的我来说 有点超前 很多东西理解起来还是很难 但是 这本书 ...

  9. WPF DATAGrid 空白列 后台绑定列 处理

    原文:WPF DATAGrid 空白列 后台绑定列 处理 AutoGenerateColumns <DataGrid x:Name="dataGrid" Margin=&qu ...

  10. 【洛谷5335】[THUSC2016] 补退选(指针实现Trie)

    点此看题面 大致题意: 三种操作:加入一个字符串,删除一个字符串,求最早什么时候以某个字符串为前缀的字符串个数超过给定值. \(Trie\) 这道题显然是\(Trie\)的暴力裸题. 考虑我们对于\( ...