【PYTHON3學習】廖雪峯HTMLParser網頁信息爬蟲初入門

題目

找一個網頁,例如https://www.python.org/events/python-events/,用瀏覽器查看源碼並複製,然後嘗試解析一下HTML,輸出Python官網發佈的會議時間、名稱和地點。

代碼版本1——時區轉換

from html.parser import HTMLParser
from urllib import request
from datetime import datetime		
from pytz import utc  
from pytz import timezone
class EventSearchParser(HTMLParser):   
    def __init__(self):
        super().__init__()
        self.Cons=[]
        self.times=[]
        self.locs=[]
        self.__Conference=' '     #標誌位(conference和location)

    def handle_starttag(self, tag, attrs):      #首元素 <start>       
        attrs=dict(attrs)
        if tag=='h3' and 'class' in attrs:
            if attrs['class']=='event-title':          #判斷爲事件,其字段數據爲會議名字
                self.__Conference='conference'
        if tag=='time' and 'datetime' in attrs:        #判斷爲日期                                                                      
            cst_tz = timezone('Asia/Shanghai')  	   #上海時區
            utc_tz = timezone('UTC')				   #UTC  
            dt=datetime.strptime(attrs['datetime'][:-6],'%Y-%m-%dT%H:%M:%S')    #str->datetime
            dt_utc=dt.replace(tzinfo=utc_tz)                                    #添加時區0:00
            dt_Shanghai=dt_utc.astimezone(cst_tz)                               #轉換爲上海時區
            self.times.append(dt_Shanghai)
        if tag=='span' and 'class' in attrs:
            if attrs['class']=='event-location':             #判斷爲地點,其字段數據爲地點
                self.__Conference='location'
                  
    def handle_data(self, data):         #字段數據
        if self.__Conference=='conference':
            self.Cons.append(data)

        if self.__Conference=='location':
            self.locs.append(data)
   

    def handle_endtag(self,tag):        #結束標籤時清空
        self.__Conference=' '


def url2html(url):              
    header={ 
      '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.Request(url,headers=header)
    with request.urlopen(req,timeout=25) as f:
        print(f'Status:{f.status} {f.reason} \n')		#狀態碼和對應狀態
        html=f.read().decode(encoding='utf_8')			#bytes->str
    return html

def output(parser):
    i=1
    for x,y,z in zip(parser.Cons,parser.times,parser.locs):
        print('第%d個會議\nConferencesName:%s\nDate:%s\nLocation:%s\n'%(i,x,y,z))
        i+=1
def main():
	parser=EventSearchParser()
	url='https://www.python.org/events/python-events/'
	htmlsource=url2html(url)
	parser.feed(htmlsource)
	output(parser)
if __name__=='__main__':
	main()
	

運行結果

Status:200 OK

第1個會議
ConferencesName:HackBVICAM National Student’s Convention 2k20
Date:2020-03-13 08:00:00+08:00
Location:New Delhi, India

第2個會議
ConferencesName:MoscowPythonConf++
Date:2020-03-27 08:00:00+08:00
Location:Moscow, Russia

第3個會議
ConferencesName:PyCon SK 2020
Date:2020-03-27 08:00:00+08:00
Location:Bratislava, Slovakia

第4個會議
ConferencesName:PyCon Italia 2020
Date:2020-04-02 08:00:00+08:00
Location:Florence, Italy

第5個會議
ConferencesName:PyCon US 2020
Date:2020-04-15 08:00:00+08:00
Location:Pittsburgh, PA, USA

第6個會議
ConferencesName:Django Day Copenhagen
Date:2020-04-17 08:00:00+08:00
Location:Copenhagen, Denmark

第7個會議
ConferencesName:PyCon Belarus 2020
Date:2020-02-21 08:00:00+08:00
Location:Minsk, Belarus

第8個會議
ConferencesName:Open Source Festival
Date:2020-02-20 08:00:00+08:00
Location:Lagos, Nigeria

代碼版本2(轉載)——正則表達式

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()

運行結果

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章