Python實(shí)戰(zhàn)之異步獲取中國(guó)天氣信息
前言
本來(lái)是想要更新scrapy的,但是怎么說(shuō)呢,這玩意不難,看著官方文檔,基本上就能做,主要是前面的如果你的爬蟲(chóng)基礎(chǔ)不好的話,這個(gè)scrapy你也玩不好,而且對(duì)于大部分的人來(lái)說(shuō)安裝scrapy可能都是個(gè)問(wèn)題,因?yàn)橛幸恍v史遺留的問(wèn)題,畢竟是從python2過(guò)來(lái)的老框架。當(dāng)然還有個(gè)原因,我要做的東西,用不上scrapy,能夠用上scrapy如果只是做爬蟲(chóng),那必然是分布式爬蟲(chóng),但是我這里要做的可能只是一個(gè)客戶端,也就是一個(gè)spider采集軟件,所以這個(gè)scrapy沒(méi)法上。
目標(biāo)
今天我們要搞的是獲取天氣,用的API是中國(guó)天氣網(wǎng)。
BaseUrl = "http://wthrcdn.etouch.cn/weather_mini?city={}"網(wǎng)上呢也有很多,那個(gè)直接爬取中國(guó)天氣網(wǎng)的爬蟲(chóng),但是我就是搞不懂,為啥非要去網(wǎng)頁(yè)里面然后去xpath或者正則去搞,明明用的都是同一個(gè)api出來(lái)的數(shù)據(jù),我為啥要去頁(yè)面把人家渲染后的結(jié)果去反向解析出數(shù)據(jù)?我直接拿數(shù)據(jù)不好嘛?
請(qǐng)求格式
回到這里,咱們的這個(gè)接口呢,是一個(gè)get請(qǐng)求,然后的話,那啥只需要把城市或者編號(hào)放在city那個(gè)字段就行了,返回結(jié)果是個(gè)json,我們把這玩意變成字典后是這樣的
{'data':
{'yesterday':
{'date': '5日星期六', 'high': '高溫 16℃', 'fx': '東北風(fēng)', 'low': '低溫 9℃', 'fl': '<![CDATA[3級(jí)]]>', 'type': '多云'},
'city': '九江',
'forecast': [{'date': '6日星期天', 'high': '高溫 12℃', 'fengli': '<![CDATA[3級(jí)]]>', 'low': '低溫 7℃', 'fengxiang': '東北風(fēng)', 'type': '中雨'},
{'date': '7日星期一', 'high': '高溫 14℃', 'fengli': '<![CDATA[2級(jí)]]>', 'low': '低溫 7℃', 'fengxiang': '北風(fēng)', 'type': '多云'},
{'date': '8日星期二', 'high': '高溫 19℃', 'fengli': '<![CDATA[2級(jí)]]>', 'low': '低溫 8℃', 'fengxiang': '東南風(fēng)', 'type': '晴'},
{'date': '9日星期三', 'high': '高溫 21℃', 'fengli': '<![CDATA[2級(jí)]]>', 'low': '低溫 11℃', 'fengxiang': '東南風(fēng)', 'type': '晴'},
{'date': '10日星期四', 'high': '高溫 23℃', 'fengli': '<![CDATA[1級(jí)]]>', 'low': '低溫 11℃', 'fengxiang': '南風(fēng)', 'type': '多云'}
],
'ganmao': '感冒多發(fā)期,適當(dāng)減少外出頻率,適量補(bǔ)充水分,適當(dāng)增減衣物。', 'wendu': '8'}, 'status': 1000, 'desc': 'OK'}請(qǐng)求限制
這里不得不說(shuō)一下,中國(guó)天氣網(wǎng) yyds 這個(gè)接口完全沒(méi)有限制。為啥,我要做的是獲取全國(guó)的天氣信息,包括縣城,中國(guó)大大小小幾千個(gè)縣城,而且還要分時(shí)段去分析,所以每天的請(qǐng)求訪問(wèn)至少2w起步。如果有限制的話,咱們就得那啥反反爬了,但是通過(guò)我的測(cè)試,沒(méi)問(wèn)題。
requests非異步獲取
來(lái),我們來(lái)先做一個(gè)對(duì)比,沒(méi)有對(duì)比就沒(méi)有傷害是吧,由于非常簡(jiǎn)單我就直接上代碼了。
import requests
from datetime import datetime
class GetWeather(object):
urlWheather = "http://wthrcdn.etouch.cn/weather_mini?city={}"
requests = requests
error = {}
today = datetime.today().day
weekday = datetime.today().weekday()
week = {0:"星期一",1:"星期二",2:"星期三",3:"星期四",4:"星期五",5:"星期六",6:"星期天"}
def __getday(self)->str:
day = str(self.today)+"日"+self.week.get(self.weekday)
return day
def get_today_wheather(self,city:str)->dict:
data = self.getweather(city)
data = data.get("data").get("forecast")
today = self.__getday()
for today_w in data:
if(today_w.get("date")==today):
return today_w
def getweather(self,city:str,timeout:int=3)->dict:
url = self.urlWheather.format(city)
try:
resp = self.requests.get(url,timeout=timeout)
jsondata = resp.json()
return jsondata
except Exception as e:
self.error['error'] = "天氣獲取異常"
return self.error
def getweathers(self,citys:list,timeout:int=3):
wheathers_data = {}
for city in citys:
url = self.urlWheather.format(city)
try:
resp = self.requests.get(url=url,timeout=timeout)
wheather_data = resp.json()
wheathers_data[city]=wheather_data
except Exception as e:
self.error['error'] = "天氣獲取異常"
return self.error
return wheathers_data
if __name__ == '__main__':
getwheather = GetWeather()
start = time.time()
times = 1
for i in range(5000):
data = getwheather.get_today_wheather("九江")
if((times%100==0)):
print(data,"第",times,"次訪問(wèn)")
times+=1
print("訪問(wèn)",times,"次耗時(shí)",time.time()-start,"秒")這段代碼呢,我做了一個(gè)簡(jiǎn)單的封裝。 我們來(lái)看看結(jié)果,5000次訪問(wèn)花了多久

這里我5000次重復(fù)訪問(wèn)的是同一個(gè)城市 九江
異步獲取
這個(gè)代碼的話我是沒(méi)有封裝的,所以看起來(lái)比較亂。 這里有幾個(gè)注意點(diǎn)先說(shuō)一下
系統(tǒng)上限
由于這個(gè),異步的話還是使用的操作系統(tǒng)的一個(gè)底層嘛,所以這個(gè)并發(fā)是有上限的,因?yàn)檫@個(gè)協(xié)程異步是要不斷切換的是吧??雌饋?lái)有點(diǎn)像python自己的多線程,只是這個(gè)“多線程”完全是當(dāng)IO的時(shí)候才會(huì)切換,不然不會(huì)切換。 所以喲啊限制一下

編碼
import time
import aiohttp
from datetime import datetime
import asyncio
BaseUrl = "http://wthrcdn.etouch.cn/weather_mini?city={}"
WeekIndex = {0:"星期一",1:"星期二",2:"星期三",3:"星期四",4:"星期五",5:"星期六",6:"星期天"}
today = datetime.today().day
day = str(today)+"日"+WeekIndex.get(datetime.today().weekday())
TIMES = 0
async def request(city:str,semaphore:asyncio.Semaphore,timeout:int = 3):
url = BaseUrl.format(city)
try:
async with semaphore:
async with aiohttp.request("GET", url) as resp:
data = await resp.json(content_type='')
return data
except Exception as e:
raise e
def getwheater(task):
data = task.result()
return data
def get_today_weather(task):
global TIMES
data = task.result() #得到返回結(jié)果
data = data.get("data").get("forecast")
for today_w in data:
if (today_w.get("date") == day):
TIMES+=1#只有IO操作的時(shí)候才會(huì)切換,所以這個(gè)++操作還是一個(gè)原子性操作
if(TIMES%100==0):
print(today_w,"第",TIMES,"次訪問(wèn)")
return today_w
if __name__ == '__main__':
semaphore = asyncio.Semaphore(500)
#操作系統(tǒng)上限是同一個(gè)時(shí)刻509/1024個(gè)并發(fā),windows509 linux 1024
start = time.time()
tasks = []
for i in range(5000):
c = request("九江",semaphore,3)
task = asyncio.ensure_future(c)
task.add_done_callback(get_today_weather)
tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print("耗時(shí)",time.time() - start,"秒")
到此這篇關(guān)于Python實(shí)戰(zhàn)之異步獲取中國(guó)天氣信息的文章就介紹到這了,更多相關(guān)Python獲取天氣信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解鎖Python中神器vars內(nèi)置函數(shù)的使用
vars()函數(shù)是一個(gè)內(nèi)置函數(shù),用于返回對(duì)象的__字典__,其中包含對(duì)象的__屬性__,本文主要為大家詳細(xì)介紹了vars()函數(shù)的具體使用,需要的小伙伴可以了解下2023-11-11
pytorch 中pad函數(shù)toch.nn.functional.pad()的用法
今天小編就為大家分享一篇pytorch 中pad函數(shù)toch.nn.functional.pad()的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01
Python爬取哆啦A夢(mèng)-伴我同行2豆瓣影評(píng)并生成詞云圖
哆啦A夢(mèng)系列是陪伴我,乃至陪伴了幾代人成長(zhǎng)的故事.50年來(lái),藤子·F·不二雄先生創(chuàng)造了竹蜻蜓,任意門,時(shí)光機(jī)器等等無(wú)數(shù)的新奇道具,讓大雄和他的小伙伴們經(jīng)歷了各種冒險(xiǎn),也經(jīng)歷了許多充滿戲劇性的啼笑皆非的日常.特意寫了這篇文章,教大家怎么繪制詞云圖,需要的朋友可以參考下2021-06-06
ITK 實(shí)現(xiàn)多張圖像轉(zhuǎn)成單個(gè)nii.gz或mha文件案例
這篇文章主要介紹了ITK 實(shí)現(xiàn)多張圖像轉(zhuǎn)成單個(gè)nii.gz或mha文件案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
Python入門必須知道的11個(gè)知識(shí)點(diǎn)
這篇文章主要為大家詳細(xì)介紹了Python入門必須知道的11個(gè)知識(shí)點(diǎn),幫助更好地了解python,感興趣的小伙伴們可以參考一下2018-03-03

