摘要:教你如何用Python自带的HTMLParser解析HTML文本。
写在前面:为了更好的学习python,博主记录下自己的学习路程。本学习笔记基于廖雪峰的Python教程,如有侵权,请告知删除。欢迎与博主一起学习Pythonヽ( ̄▽ ̄)ノ
目录
常用内置模块
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文本,可以分多次调用,不用一次把所有文本都解析。
【练习】解析网页源代码
(练习源自廖雪峰官网)
找一个网页,例如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吧( ̄▽ ̄)~*