1. 程式人生 > >Python3爬蟲小程式——爬取各類天氣資訊

Python3爬蟲小程式——爬取各類天氣資訊

本來是想從網上找找有沒有現成的爬取空氣質量狀況和天氣情況的爬蟲程式,結果找了一會兒感覺還是自己寫一個吧。

主要是爬取北京包括北京周邊省會城市的空氣質量資料和天氣資料。

過程中出現了一個錯誤:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 250。

原來發現是頁面的編碼是gbk,把語句改成data=urllib.request.urlopen(url).read().decode("gbk")就可以了。

然後我把爬到的資料寫到文字文件裡了,往後可以匯入到excel表中使用。

實驗室的電腦不經常開,然後就放到伺服器上了,讓它自己慢慢一小時爬一次吧~哈哈哈~

後面有一次晚上出現了異常,因為沒加入異常處理,所以從零點到早上五點的資料都沒爬到。。。

(⊙﹏⊙)然後這次修改就加入了異常處理。如果出現URLError,就一分鐘後重試。

程式碼:

#coding=utf-8
#北京及周邊省會城市汙染資料、天氣資料每小時監測值爬蟲程式
import urllib.request
import re
import urllib.error
import time
#模擬成瀏覽器
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36")
opener = urllib.request.build_opener()
opener.addheaders=[headers]
#將opener安裝為全域性
urllib.request.install_opener(opener)
def get_pm25_and_weather(city):
    #首先執行獲取空氣質量資料,返回資料更新時間
    data_time=getpm25(city)
    #然後將獲取到的資料更新時間賦值給獲取天氣資料函式使用
    getweather(city,data_time)
def getpm25(city):
    try:
        #設定url地址
        url="http://pm25.in/"+city
        data=urllib.request.urlopen(url).read().decode("utf-8")
        print("城市:"+city)
        #構建資料更新時間的表示式
        data_time='<div class="live_data_time">\s{1,}<p>資料更新時間:(.*?)</p>'
        #尋找出資料更新時間
        datatime=re.compile(data_time, re.S).findall(data)
        print("資料更新時間:"+datatime[0])
        #構建資料收集的表示式
        data_pm25 = '<div class="span1">\s{1,}<div class="value">\n\s{1,}(.*?)\s{1,}</div>'
        data_o3='<div class="span1">\s{1,}<div class ="value">\n\s{1,}(.*?)\s{1,}</div>'
        #尋找出所有的監測值
        pm25list = re.compile(data_pm25, re.S).findall(data)
        o3list=re.compile(data_o3, re.S).findall(data)
        #將臭氧每小時的值插入到原列表中
        pm25list.append(o3list[0])
        print("AQI指數,PM2.5,PM10,CO,NO2,SO2,O3:(單位:μg/m3,CO為mg/m3)")
        print(pm25list)
        #將獲取到的值寫入檔案中
        writefiles_pm25(city,datatime,pm25list)
        #返回資料更新時間值
        return datatime
    except urllib.error.URLError as e:
        print("出現URLERROR!一分鐘後重試……")
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
        time.sleep(60)
        #出現異常則過一段時間重新執行此部分
        getpm25(city)
    except Exception as e:
        print("出現EXCEPTION!十秒鐘後重試……")
        print("Exception:"+str(e))
        time.sleep(10)
        # 出現異常則過一段時間重新執行此部分
        getpm25(city)
def writefiles_pm25(filename,datatime,pm25list):
    #將獲取的資料寫入檔案中,資料分別為時間,AQI指數,PM2.5,PM10,CO,NO2,SO2,O3。(單位:μg/m3,CO為mg/m3)
    f = open("D:\Python\Python35\myweb\data_pm25\data_pm25_"+filename+".txt", "a")
    f.write(datatime[0])
    f.write(",")
    for pm25 in pm25list:
        f.write(str(pm25))
        f.write(",")
    f.write("\n")
    print("該條空氣質量資料已新增到檔案中!")
    f.close()
def getweather(city,datatime):
    try:
        #構建url
        url="http://"+city+".tianqi.com/"
        data=urllib.request.urlopen(url).read().decode("gbk")
        #構建資料收集的表示式
        data_weather = '<li class="cDRed">(.*?)</li>'
        data_wind='<li style="height:18px;overflow:hidden">(.*?)</li>'
        data_temperature='<div id="rettemp"><strong>(.*?)°'
        data_humidity='</strong><span>相對溼度:(.*?)</span>'
        #尋找出所有的監測值
        weatherlist = re.compile(data_weather, re.S).findall(data)
        windlist=re.compile(data_wind, re.S).findall(data)
        temperaturelist = re.compile(data_temperature, re.S).findall(data)
        humiditylist = re.compile(data_humidity, re.S).findall(data)
        #將其他值插入到天氣列表中
        weatherlist.append(windlist[0])
        weatherlist.append(temperaturelist[0])
        weatherlist.append(humiditylist[0])
        print("天氣狀況,風向風速,實時溫度,相對溼度:")
        print(weatherlist)
        #將獲取到的值寫入檔案中
        writefiles_weather(city,datatime,weatherlist)
    except urllib.error.URLError as e:
        print("出現URLERROR!一分鐘後重試……")
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
        time.sleep(60)
        # 出現異常則過一段時間重新執行此部分
        getweather(city,datatime)
    except Exception as e:
        print("出現EXCEPTION!十秒鐘後重試……")
        print("Exception:"+str(e))
        time.sleep(10)
        # 出現異常則過一段時間重新執行此部分
        getweather(city, datatime)
def writefiles_weather(filename,datatime,weatherlist):
    #將獲取的資料寫入檔案中,資料分別為時間,天氣狀況,風向風速,實時溫度,相對溼度。
    f = open("D:\Python\Python35\myweb\data_weather\data_weather_"+filename+".txt", "a")
    f.write(datatime[0])
    f.write(",")
    for weather in weatherlist:
        f.write(str(weather))
        f.write(",")
    f.write("\n")
    print("該條天氣資料已新增到檔案中!")
    f.close()
#退出迴圈可用Ctrl+C鍵
while True:
    print("開始工作!")
    get_pm25_and_weather("beijing")
    get_pm25_and_weather("tianjin")
    get_pm25_and_weather("shijiazhuang")
    get_pm25_and_weather("taiyuan")
    get_pm25_and_weather("jinan")
    get_pm25_and_weather("shenyang")
    get_pm25_and_weather("huhehaote")
    get_pm25_and_weather("zhengzhou")
    #每一小時執行一次
    print("休息中……")
    print("\n")
    time.sleep(3600)

執行狀態圖: