1. 程式人生 > >從環境雲網站爬取資料

從環境雲網站爬取資料

1、環境雲網站:http://www.envicloud.cn/
網站中包含全國各地關於環境方面的資料,我們這次只讀取了廣東省24小時天氣歷史資料。
2、關於介面參考環境雲幫助頁面
3、程式碼使用python語言實現
4、爬取需要key,免費申請
5、爬取後的資料儲存在oracle中,所以需要cx_Oracle外掛。
安裝方式在https://oracle.github.io/python-cx_Oracle/中查詢
我使用命令列執行python -m pip install cx_Oracle --upgrade

即可安裝完畢

#coding:utf-8 #用於顯示程式碼中的漢字
'''
簡介:
天氣資料獲取指令碼
資料獲取流程(需要條件:環境雲金鑰):
1.首先在資料庫中讀取需要抓取氣象資料的城市資料,這部分也可以直接在環境雲網站爬取
2.通過環境雲API介面獲取天氣資料
3.對第二步中產生的JSON格式資料進行處理存入到資料庫
'''
import json,sys,urllib2,time,os
import pandas as pd
import cx_Oracle
import datetime

reload(sys)#呼叫setdefaultencoding時必須要先reload一次sys模組
sys.setdefaultencoding('utf8') 

''' 獲取監測站資訊(即城市資訊。
    這裡注意,以廣州為例,廣州分為廣州、番禺、從化、增城、花都等幾部分,
    其中廣州代表了廣州城區。所以這裡使用監測站更準確)
    資料表字段說明
    FID    VARCHAR2(20)    Y            序號
    FSITEID    VARCHAR2(20)    Y            監測站號
    FSITENAME    VARCHAR2(20)    Y            監測站名
    FCITYTYPE    VARCHAR2(20)    Y            行政級別
    FCITY    VARCHAR2(20)    Y            市
    FLON    NUMBER(5,2)    Y            經度
    FLAT    NUMBER(5,2)    Y            緯度
    FABOVESEALEVEL    VARCHAR2(20)    Y            海拔
    FADDRNO    VARCHAR2(20)    Y            地域編碼
    FDATASOURCE    VARCHAR2(20)    Y            資料來源(1為氣候中心資料;2為環境雲資料)
'''
def getsitedata(tablename,datasource):
    sitedata = cur.execute("select fsiteid,fsitename,faddrno from %s where fdatasource = '%s'"%(tablename,datasource))
    sitedata = sitedata.fetchall()#接收全部的返回結果行
    return sitedata

''' 獲取資料
    引數1:監控站
    引數2:開始日期
    引數3:結束日期
    引數4:環境雲key
'''
def getapidata(sitedata,begin_date,end_date,key):

    for site in map(None,sitedata):
        siteid = site[0]#參考getsitedata函式註釋,編號
        sitename = site[1]#名字
        siteaddrno = site[2]#所屬城市
        site_index = pd.Index(site)
        site_index = site_index.get_loc(siteid)#設定編號。
        ''' 這裡或許直接用函式替代none,沒有試過
            def add(num):
            return num + 1
 
            rs = map(add, lt)
        '''
        for querydate in pd.date_range(begin_date,end_date):#拆分成每一天
            querydate = str(querydate)[:10]#不使用時間,只保留日期
            querydate_true = querydate.replace('-','')#將2017-08-17變為20170817
            #24小時歷史天氣。返回結構詳見:http://www.envicloud.cn/pages/guide.html#v2dailyweatherhistory
            headers={'cache-control': "no-cache"}#這行我也不明白
            result='bad'        
            try:
                for hour in range(24):
                    sHour = str(hour)
                    print sHour
                    if (len(sHour) == 1):
                        sHour = "0" + sHour#將小時變為兩位數字

                    url = 'http://service.envicloud.cn:8082/v2/weatherhistory/%s/%s/%s/%s' % (
                        key, siteid, querydate_true,sHour)
                    request=urllib2.Request(url,headers=headers)
                    content=urllib2.urlopen(request,timeout = 3 )
                    content=content.read()
                    data=json.loads(content)
                    #weather_data = pd.DataFrame(data,index=[0])   #指定日期歷史天氣
                    #columns 更新時間 天氣現象 氣溫(℃) 體感溫度(℃) 氣壓(hPa) 相對溼度(%) 降雨量(mm) 風向 風力 風速(m/s)
                    if data['rdesc']=="Success":
                        ''' 檢查某監測站在資料庫內,該日期已存在多少條資料。引數:檢測點ID,要查詢的日期
                        這個判斷是有問題的。因為這個程式由一箇舊的程式改的。舊程式是獲取某一天的資料(不具體到某個小時),
                        所以只要資料庫內該日期有資料,及可以不再插入了。
                        但現在程式已經變為按小時查詢了,所以即使該日期有資料,也資料不一定完整。
                        另外也不可以用資料量=24來判斷,因為有些時間環境雲網站也沒有資料,所以上一行才需要判斷返回結果是Success
                        '''
                        checkresult = checksitedata(siteid, data['updatetime'])  
                        if checkresult > 0:
                            print 'data already exists'
                            continue
                        #插入到資料庫
                        insertintooracle(siteid, data['updatetime'],
                                        data['phenomena'],
                                        data['temperature'],
                                        data['feelst'],
                                        data['airpressure'],
                                        data['humidity'],
                                        data['rain'],
                                        data['winddirect'],
                                        data['windpower'],
                                        data['windspeed']
                                        )
                    result = 'good'
                    print 'result is good'

                    '''這部分註釋是舊程式碼,用於獲取過去24小時的歷史資料(注意:是當前時間的過去24小時,所以不需要傳遞日期和時間)
                    這部分的返回json格式和上面不同,詳細參考環境雲幫助頁面
                        weather_data = pd.DataFrame(data['history'],
                                                columns=['updatetime','phenomena','temperature',
                                                         'feelst','airpressure','humidity','rain',
                                                         'winddirect','windpower','windspeed'])#24小時歷史天氣 
                        result='good'
                        print 'result is good'
                        for ind in weather_data.index:
                            checkresult = checksitedata(siteid,weather_data.at[ind,'updatetime'])#檢查某監測站在該日期已存在多少條資料。引數:檢測點ID,要查詢的日期
                            #print checkresult

                            if checkresult>0:
                                print 'data already exists'
                                continue
                            insertintooracle(siteid,weather_data.at[ind,'updatetime'],
                                         weather_data.at[ind,'phenomena'],
                                         weather_data.at[ind,'temperature'],
                                         weather_data.at[ind,'feelst'],
                                         weather_data.at[ind,'airpressure'],
                                         weather_data.at[ind,'humidity'],
                                         weather_data.at[ind,'rain'],
                                         weather_data.at[ind,'winddirect'],
                                         weather_data.at[ind,'windpower'],
                                         weather_data.at[ind,'windspeed']
                                         )
                    '''
            except:
                result='bad'
                #print request
                print siteid
                print 'result is bad'
                continue
            '''這部分是舊程式碼,用於判斷環境雲中的錯誤資訊,例如空氣溼度值為100。
            注意:環境雲中很多錯誤資訊
            這部分程式碼未經測試,不保證正確性
            windspeed=float(str(weather_data.wspd_avg)[4:8].replace(' ','0'))
            if windspeed>60:
                windspeed=''
            airpressure=weather_data.pressure_avg.astype(float).mean()
            if airpressure>1300:
                airpressure=''
            humidity=weather_data.hum_avg.astype(float).mean()
            if humidity>100:
                humidity=''
            rain=weather_data.rain_full.astype(float).mean()
            if rain>200:
                rain=''
            #temperature_max=str(weather_data.tem_max)[5:9]
            #temperature_min=str(weather_data.tem_min)[5:9]
            #temperature_mean=''
            temperature_max=weather_data.tem_max.astype(float).max()
            if temperature_max>50:
                temperature_max=''
            temperature_min=weather_data.tem_min.astype(float).min()
            if temperature_min>50:
                temperature_min=''
            temperature_mean=''
            '''
        print 'one city inserted'
    print 'all citys inserted'

''' 查詢該監測站在某個日期一共有多少條監測記錄'''
def checksitedata(siteid,querydate):
    sql="select count(*) from imp_weather_data where siteid = '"+siteid+"' and updatetime =to_date('"+querydate+":00','yyyy-mm-dd hh24:mi:ss')"
    result = cur.execute(sql)
    result = result.fetchall()
    result = result[0][0]
    return result
   # conn.commit()
  
'''找出資料庫表中的記錄總數,用於判斷插入時的id'''  
def checkAllData():
    result = cur.execute("select count(*) from imp_weather_data ")
    result = result.fetchall()
    result = result[0][0]
    return result
    conn.commit()#如果sql語句不是insert、delete、uodate等不需要提交。參考checksitedata函式
    #return 0
    
def insertintooracle(siteid,updatetime,phenomena,temperature,feelst,airpressure,humidity,rain,winddirect,windpower,windspeed):
    table_num=checkAllData()+1
    #print table_num
    sql="""INSERT INTO imp_weather_data(dataid,siteid,updatetime,phenomena,temperature,
                    feelst,airpressure,humidity,rain,winddirect,windpower,windspeed)
                    VALUES (to_number(nvl('"""+str(table_num)+"""',null)),'"""+siteid+"""',
                    to_date('"""+updatetime+""":00','YYYY-MM-DD HH24:MI:ss'),'"""+phenomena+"""',
                    to_number(nvl('"""+temperature+"""',null)),to_number(nvl('"""+feelst+"""',null)),
                    to_number(nvl('"""+airpressure+"""',null)),to_number(nvl('"""+humidity+"""',null)),
                    to_number(nvl('"""+rain+"""',null)),'"""+winddirect+"""','"""+windpower+"""',
                    to_number(nvl('"""+windspeed+"""',null)))"""
    cur.execute(sql)
    '''這是兩種sql語句的寫法,個人喜歡上面那種
    cur.execute("""INSERT INTO imp_weather_data 
                  (dataid,siteid,updatetime,phenomena,temperature,feelst,airpressure,humidity,rain,winddirect,windpower,windspeed) 
                  VALUES (to_number(nvl('%s',null)),'%s',to_date('%s','YYYY-MM-DD HH24:MI'),'%s',to_number(nvl('%s',null)),to_number(nvl('%s',null)),to_number
                  (nvl('%s',null)),to_number(nvl('%s',null)),to_number(nvl('%s',null)),,'%s','%s',
                  to_number(nvl('%s',null)))""" 
                  %(table_num,siteid,updatetime,phenomena,temperature,feelst,airpressure,humidity,rain,winddirect,windpower,windspeed)
               )'''
    
    conn.commit()

if __name__=='__main__':
    connect='parName/
[email protected]
/ParDbName'#parName、parPw、parIP、ParDbName分別代表資料庫賬號、密碼、ip地址、資料庫名。 conn = cx_Oracle.connect(connect) cur = conn.cursor() #獲取所有監控站 sitedata = getsitedata('imp_weather_sites','2')#資料來源(1為氣候中心資料;2為環境雲資料) sysdate = datetime.datetime.now() end_date = sysdate+datetime.timedelta(days=-1)#前一天 begin_date = sysdate+datetime.timedelta(days=-2)#前兩天 end_date = str(end_date)[0:10] begin_date = str(begin_date)[0:10]#去除時間,保留日期 end_date = end_date.replace('-','') begin_date = begin_date.replace('-','') getapidata(sitedata,begin_date,end_date,key)#key是環境雲的key,大家自行申請。目前免費 conn.close()


相關推薦

環境網站資料

1、環境雲網站:http://www.envicloud.cn/網站中包含全國各地關於環境方面的資料,我們這次只讀取了廣東省24小時天氣歷史資料。 2、關於介面參考環境雲幫助頁面 3、程式碼使用python語言實現 4、爬取需要key,免費申請 5、爬取後的資料儲存在ora

java中高德地圖資料

    最近一個人負責公司的一個app專案開發,需要從高德地圖爬取杭州市全部的超市資訊,放入mongodb的資料庫中。做地理位置查詢。(mongodb這部分有時間補上)    首先去高德地圖建立一個開發者賬號,獲取一個開發web服務的高德key.這個是必須要有的,可以用我

爬蟲實戰:鏈家網資料

      學習python已經很久了,從各個大牛的技術部落格中獲益良多。現在也想把自己的小小收穫公開一下,以方便大家學習python,讓python更加普及的應用。下面我準備寫一個爬蟲例項:從鏈家網爬取福田區二手房的資料。 環境: win10專業版 python3.6(需

另類爬蟲:PDF檔案中表格資料

簡介   本文將展示一個稍微不一樣點的爬蟲。   以往我們的爬蟲都是從網路上爬取資料,因為網頁一般用HTML,CSS,JavaScript程式碼寫成,因此,有大量成熟的技術來爬取網頁中的各種資料。這次,我們需要爬取的文件為PDF檔案。本文將展示如何利用Python的camelot模組

python資料熱點詞生成詞

這是當時在中國mooc學 用python玩轉資料 時,寫的一個小demo. 程式實現步驟 1.從某一網站爬取資料,比如我是在豆瓣爬取的書評 利用Requests庫的get()爬取網頁 使用BeatifulSoup庫對爬取網頁進行解析。 寫入

Python爬蟲scrapy框架動態網站——scrapy與selenium結合資料

 scrapy框架只能爬取靜態網站。如需爬取動態網站,需要結合著selenium進行js的渲染,才能獲取到動態載入的資料。如何通過selenium請求url,而不再通過下載器Downloader去請求這個url?方法:在request物件通過中介軟體的時候,在中介軟體內部開始

通過scrapy,模擬登入開始知乎的問答資料

這篇文章將講解如何爬取知乎上面的問答資料。 首先,我們需要知道,想要爬取知乎上面的資料,第一步肯定是登入,所以我們先介紹一下模擬登入: 先說一下我的思路: 1.首先我們需要控制登入的入口,重寫start_requests方法。來控制到這個入口之後,使用

用python的matplotlib和numpy庫繪製股票K線均線的整合效果(含網路介面資料和驗證交易策略程式碼)

    本人最近在嘗試著發表“以股票案例入門Python程式語言”系列的文章,在這些文章裡,將用Python工具繪製各種股票指標,在講述各股票指標的含義以及計算方式的同時,驗證基於各種指標的交易策略,本文是第一篇,通過K線和均線案例講述Numpy,Maplotlib

爬蟲+詞豆瓣電影top100的導演制作圖

ray 爬取 open tex 下載頁面 down app zhong form 前段時間做了一個關於豆瓣電影的爬蟲,之後又寫了一個陳奕迅歌詞的詞雲制作,於是我想不如做一個關於豆瓣高分電影導演的詞雲試試,於是有了接下來這篇隨筆。 首先,我需要知道豆瓣top100電影詳情頁面

網站-案例一:貓眼電影TOP100

瀏覽器 取數據 pos 代碼 裏的 十個 wid 頁面 image 今天有小朋友說想看一下貓眼TOP100的爬取數據,要TOP100的名單,讓我給發過去,其實很簡單,先來看下目標網站: 建議大家都用谷歌瀏覽器: 這是我們要抓取的內容,100個數據,很少 我們看一下頁面結構

網站-案例二:天貓( 第一卷:首頁數據抓)

img .com 我想 提供商 網站 col class scoller bubuko 說到網站數據的爬取,目前為止我見過最復雜的就是天貓了,現在我想對它進行整站的爬取 我們先來看下天貓主頁的界面 天貓頁面很明顯是動態頁面 所以我們需要用selenium模塊 首先

網站-案例三:今日頭條抓(ajax抓JS數據)

今日頭條 頭條 img gin 方便 pos 網頁 圖片 http 今日頭條這類的網站制作,從數據形式,CSS樣式都是通過數據接口的樣式來決定的,所以它的抓取方法和其他網頁的抓取方法不太一樣,對它的抓取需要抓取後臺傳來的JSON數據,先來看一下今日頭條的源碼結構:我們抓取文

網站-案例四:知乎抓(COOKIE登錄抓個人中心)(第二卷)

img 正則 人員 gin 爬取 com 個人 我們 一個 接著上卷來分析,作為開發人員我們都知道,登錄是一個想指定URL發送POST請求的過程,所以我們需要找到請求的URL,以及字段,先用一個錯誤賬號和密碼做一下嘗試,如果是正確的話會直接跳轉到別的頁面,這樣COOKIE就

【Python3 爬蟲】06_robots.txt查看網站限制情況

使用 mage none logs HR python3 clas 分享 處理 大多數網站都會定義robots.txt文件來限制爬蟲爬去信息,我們在爬去網站之前可以使用robots.txt來查看的相關限制信息例如:我們以【CSDN博客】的限制信息為例子在瀏覽器輸入:http

將豆瓣排名前250資料通過sqlite3存入資料庫

#爬取豆瓣top250電影,並儲存到資料庫 import requests from bs4 import BeautifulSoup import sqlite3 def get_html(web_url): user_agent = 'Mozilla/5.0 (Linux; Andro

R中使用rvest資料小試

總結R中使用 xpath 和 css selectors 獲取標籤內容(xpath功能強大,而CSS選擇器通常語法比較簡潔,執行速度更快些) 例:抓取下面標籤的內容: <h3 class="lister index unbold text"><span>小明他很忙</

selenium+python資料跳轉網頁

專案要做一個四個層級欄的資料抓取,而且點選查詢後資料會在新跳出的網頁。 原始碼如下 註釋解釋 from selenium import webdriver import selenium #from time import sleep as sp url='http://202.127.42.15

python:爬蟲資料的處理之Json字串的處理(2)

#Json字串的處理 Json字串轉化為Python資料型別 import json JsonStr ='{"name":"sunck","age":"18","hobby":["money","power","English"],"parames":{"a":1,"b":2}}' Js

python :通過爬蟲資料(1)

(1)通過url爬取網頁資料 import urllib.request #指定url url ="https://www.baidu.com" #向伺服器發起請求,返回響應的資料,通過infor接收 infor = urllib.request.urlopen(url)

資料省市縣鎮村

package aa; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.jsoup.Jsoup; import org.jsoup.nodes.Document;