摘要: 教你如何用 Python 自带的 htmlParser 解析 HTML 文本.
* 写在前面: 为了更好的学习 python, 博主记录下自己的学习路程. 本学习笔记基于廖雪峰的 Python 教程, 如有侵权, 请告知删除. 欢迎与博主一起学习 Python ヽ(~▽~)ノ *
目录
常用内置模块
HTMLParser
[练习] 解析网页源代码
常用内置模块
HTMLParser
HTMLParser 是解析 HTML 文本的工具.
与解析 xml 类似, 我们需要定义好标签处理的方法.
HTMLParser 常用方法有:
handle_starttag(tag, attrs) : 处理开始标签, 比如 < head>
handle_endtag(tag) : 处理结束标签, 比如</head>;
handle_startendtag(tag, attrs) : 处理自己结束的标签, 如 < img />;
handle_data(data) : 处理数据, 标签之间的文本;
handle_comment(data) : 处理注释,`` 之间的文本.
这里的 tag 是指标签, attrs 是指属性列表, 以元组 tuple 的方式展示;
看个示例:
- from HTML.parser import HTMLParser # 引入 HTML 解析模块
- class MyHTMLParser(HTMLParser):
- def handle_starttag(self, tag, attrs):
- print("<start tag>:", tag)
- def handle_endtag(self, tag):
- print("<end tag>:", tag)
- def handle_data(self, data):
- print("<some data>:", data)
- def handle_startendtag(self, tag, attrs):
- print("<startendtag>:", tag)
- def handle_comment(self,data):
- print("<comment>:", data)
- parser = MyHTMLParser() # 创建 HTML 解析器
- parser.feed('<HTML><head><title>Test</title></head>' # 解析 HTML 文本
- '<body><h1>Parse me!</h1><img src ="" />''<!-- comment --></body></HTML>')
运行结果:
- <start tag>
- : HTML
- <start tag>
- : head
- <start tag>
- : title
- <some data>
- : Test
- <end tag>
- : title
- <end tag>
- : head
- <start tag>
- : body
- <start tag>
- : h1
- <some data>
- : Parse me!
- <end tag>
- : h1
- <startendtag>
- : img
- <comment>
- : comment
- <end tag>
- : body
- <end tag>
- : HTML
其中 feed( )方法就是来解析 HTML 文本, 可以分多次调用, 不用一次把所有文本都解析.
[练习] 解析网页源代码</font>
(练习源自廖雪峰官网)
找一个网页, 例如 https://www.python.org/events/python-events/ , 用浏览器查看源码并复制, 然后尝试解析一下 HTML, 输出 Python 官网发布的会议时间, 名称和地点.
- #!/usr/bin/python3
- # -*- coding:utf-8 -*-
- from HTML.parser import HTMLParser # 引入 HTML 解析模块
- from urllib import request # 引入 URL 请求模块
- import re # 引入正则表达式模块
- class MyHTMLParser(HTMLParser):
- def __init__(self):
- HTMLParser.__init__(self) # 继承父类的属性
- self.is_time = False # 初始化时间布尔值, 用于判断标签是否表示时间, 下面类似
- self.is_title = False
- self.is_location = False
- self.is_year = False
- self.info = [] # 初始化一个 list, 用于储存获取的信息
- def handle_starttag(self, tag, attrs): # 定义开始标签处理器
- if tag == 'time' : # 判断标签是否表示时间, 若是, 更改布尔值, 下面类似
- self.is_time = True
- if tag == 'h3' and ('class','event-title') in attrs: # 判断标题标签
- self.is_title = True
- if tag == 'span' and ('class','event-location') in attrs: # 判断地点标签
- self.is_location = True
- if tag == 'span' and ('class','say-no-more') in attrs: # 判断年份标签
- self.is_year = True
- def handle_data(self, data): # 定义数据内容处理器
- if self.is_time == True: # 如果标签为时间
- self.is_time = False # 初始化时间布尔值
- self.info.append(dict(会议时间 = data)) # 把数据储存在 info 中, 下面类似操作标题, 地点, 年份
- if self.is_title == True:
- self.is_title = False
- self.info.append(dict(会议名称 = data))
- if self.is_location == True:
- self.is_location = False
- self.info.append(dict(会议地点 = data))
- if self.is_year == True:
- self.is_year = False
- # 由于网页源码中出现是年份标签但显示的内容不是年份, 所以增加一个正则表达式来判断
- if re.match(r'[0-9]', data.strip()):
- self.info.append(dict(会议年份 = data))
- def getinfo(data,u): # 定义信息处理函数
- parser = MyHTMLParser() # 创建 HTML 解析器
- parser.feed(data) # 解析 HTML 文件
- count = 0 # 初始化 count
- print('抓取网址:%s\n 抓取信息如下:' % u)
- for x in parser.info: # 打印 info
- for key in x : # 由于 info 存的是 dict 组成的 list, 所以还要遍历 dict
- print(key + ':' + str(x[key]))
- count += 1
- if count % 4 == 0: # 当输出四个数据后, 打印分割线
- print('-------------------------------')
- web = 'https://www.python.org/events/python-events/'
- with request.urlopen(Web) as f: # 打开网页
- Data = f.read()
- Data = Data.decode('utf-8')
- getinfo(Data,Web) # 解析文件并打印信息
运行结果:
抓取网址: https://www.python.org/events/python-events/
抓取信息如下:
会议名称: PyCon Nigeria
会议时间: 13 Sept. - 16 Sept.
会议年份: 2018
会议地点: Lagos, Nigeria
-------------------------------
会议名称: PyCon UK 2018
会议时间: 15 Sept. - 20 Sept.
会议年份: 2018
会议地点: Cardiff City Hall, Cathays Park, Cardiff, CF10 3ND, UK
-------------------------------
会议名称: PyConJP 2018
会议时间: 17 Sept. - 19 Sept.
会议年份: 2018
会议地点: Tokyo, Japan
-------------------------------
会议名称: PyCon Estonia
会议时间: 04 Oct. - 05 Oct.
会议年份: 2018
会议地点: Tallinn, Estonia
-------------------------------
会议名称: PyCon India 2018
会议时间: 05 Oct. - 10 Oct.
会议年份: 2018
会议地点: Hyderabad, India
-------------------------------
会议名称: PyCon ZA 2018
会议时间: 10 Oct. - 15 Oct.
会议年份: 2018
会议地点: Johannesburg, South Africa
-------------------------------
会议名称: FrOSCon 2018
会议时间: 25 Aug. - 27 Aug.
会议年份: 2018
会议地点: University of Applied Sciences Bonn-Rhein-Sieg, Sankt Augustin, Germany
-------------------------------
会议名称: PyCon AU 2018
会议时间: 24 Aug. - 29 Aug.
会议年份: 2018
会议地点: ICC, Sydney, Australia
-------------------------------
上面是解析 HTML 文本的一个实例, 源码都附有具体的注释, 小伙伴们应该都能看得懂 (`ω ´) 嗯.
以上就是本节的全部内容, 感谢你的阅读.
下一节内容: 常用第三方模块
有任何问题与想法, 欢迎评论与吐槽.
和博主一起学习 Python 吧(~▽~)~*
来源: http://www.jianshu.com/p/df9353c26d52