Discuss / Python / HTMLParser 练习的最简洁实现

HTMLParser 练习的最简洁实现

Topic source

ywjco_567

#1 Created at ... [Delete] [Delete and Lock User]

看前一位同学的,感觉已经是最好的了。稍修改。

Python官网发布的会议时间、名称和地点的网页源码样式:

 <li>
      <h3 class="event-title"><a href="/events/python-events/776/">PyCon AU 2019</a></h3>
    <p>                 
        <time datetime="2019-08-02T00:00:00+00:00">02 Aug. &ndash; 06 Aug. <span class="say-no-more"> 2019</span></time>
        <span class="event-location">Sydney, Australia</span>              
    </p>
 </li>

# -*-coding:UTF-8-*-

from html.parser import HTMLParser
from urllib.request import Request,urlopen
import re

def get_data(url):
   '''
   GET请求到指定的页面
   :return: HTTP响应
   '''

   headers = {
      'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'
      }
   req = Request(url, headers=headers)
   with urlopen(req, timeout=25) as f:
      data = f.read()
      print(f'Status: {f.status} {f.reason}')
      print()
   return data.decode("utf-8")

class MyHTMLParser(HTMLParser):
   def __init__(self):
      super().__init__()
      self.__parsedata='' # 设置一个空的标志位
      self.info = []

   def handle_starttag(self, tag, attrs):
      if ('class', 'event-title') in attrs:
         self.__parsedata = 'name'  # 通过属性判断如果该标签是我们要找的标签,设置标志位
      if tag == 'time':
         self.__parsedata = 'time'
      if ('class', 'say-no-more') in attrs:
         self.__parsedata = 'year'
      if ('class', 'event-location') in attrs:
         self.__parsedata = 'location'

   def handle_endtag(self, tag):
      self.__parsedata = ''# 在HTML 标签结束时,把标志位清空

   def handle_data(self, data):

      if self.__parsedata == 'name':
         # 通过标志位判断,输出打印标签内容
         self.info.append(f'会议名称:{data}')

      if self.__parsedata == 'time':
         self.info.append(f'会议时间:{data}')

      if self.__parsedata == 'year':
         if re.match(r'\s\d{4}', data): # 因为后面还有两组 say-no-more 后面的data却不是年份信息,所以用正则检测一下
            self.info.append(f'会议年份:{data.strip()}')

      if self.__parsedata == 'location':
         self.info.append(f'会议地点:{data} \n')

def main():
   parser = MyHTMLParser()
   URL = 'https://www.python.org/events/python-events/'
   data = get_data(URL)
   parser.feed(data)
   for s in parser.info:
      print(s)

if __name__ == '__main__':
   main()

运行结果:

D:\Python37\python.exe D:/Python37/Code/html_parser_官网会议_v2.py
Status: 200 OK

会议名称:PyCon AU 2019
会议时间:02 Aug. – 06 Aug. 
会议年份:2019
会议地点:Sydney, Australia

会议名称:DjangoCon AU 2019
会议时间:02 Aug.
会议年份:2019
会议地点:Sydney, Australia

会议名称:PyBay
会议时间:15 Aug. – 18 Aug. 
会议年份:2019
会议地点:Mission Bay, San Francisco, CA, USA

会议名称:PyCon Korea 2019
会议时间:15 Aug. – 18 Aug. 
会议年份:2019
会议地点:Seoul

会议名称:Kiwi PyCon X
会议时间:23 Aug. – 25 Aug. 
会议年份:2019
会议地点:Wellington, New Zealand

mark一下

mark两下

牛逼

学习了

Blaine_k

#6 Created at ... [Delete] [Delete and Lock User]

mark

流云

#7 Created at ... [Delete] [Delete and Lock User]

mark

新一仔

#8 Created at ... [Delete] [Delete and Lock User]

太厲害了

n.

#9 Created at ... [Delete] [Delete and Lock User]

mark

SetNM

#10 Created at ... [Delete] [Delete and Lock User]

niuaniua

学习一下


  • 1
  • 2

Reply