Python获取天气,python爬取中国天气网
本文主要介绍如何使用Python爬虫异步获取天气信息。使用的API是中国天气网。本文中的样本代码解释的很详细,有兴趣的朋友可以去试试。
00-1010前言目标请求格式请求限制请求非异步采集异步采集系统上限代码
目录
本来想更新scrapy,但是怎么说呢?这个事情不难。看官方文件,基本上可以做到,主要是前面。如果你的爬虫基础不好,你也玩不好这个刺儿头。而且安装scrapy可能对大多数人来说都是个问题,因为有一些历史遗留问题。毕竟是python2的老框架。当然,还有一个原因。我想做的事情不需要scrapy,我可以用scrapy。如果我只是做一个爬虫,那一定是分布式爬虫。但是我这里要做的可能只是一个客户端,也就是一个蜘蛛采集软件,所以这个scrapy不能用。
前言
今天要做的是获取天气,用的API是中国天气网。
base URL= http://wthrcdn . etouch.cn/weather _ mini?city={}
网上爬虫很多,我就是想不通。为什么我要先去网页再去xpath或者regular才能做到?显然,使用了来自同一个api的所有数据。为什么我要去页面逆向分析别人的渲染结果?为什么我不直接拿走数据?
目标
回到这里,我们的接口是一个get请求,然后,你只需要把城市或者数字放在city的字段里,返回的结果就是json,就是我们把这个东西变成字典之后的这个样子。
{ 数据 :
{ 昨天 :
{ 日期 : 星期六5日,高 : 高温16 , FX 3360 东北风,低 : 低温9 , FL 3360 ![CDATA [Level 3]], type 3360 多云 },
城市 : 九江:
预报 3360 [{ 日期 : 周日6 ,高 : 高温12 ,丰利 3360 ![CDATA[3级]],低 3360 低温7,风行 3360 东北风,类型 : 中雨 },
{ 日期 : 周一七,高 : 高温14,丰利 3360 ![CDATA [Level 2]],低 3360 低温7,风行 3360 北风,类型 : 多云 },
{ 日期 : 星期二8 ,高 : 高温19,丰利 3360 ![CDATA [Level 2]], Low 3360 低温8, Fengxing 3360 东南风, type: 晴 },
{ 日期 : 星期三9 ,高 : 高温21 ,丰利 3360 ![CDATA [Level 2]], Low 3360 低温11, Fengxing 3360 东南风, type: 晴 },
{ 日期 : 周四10 ,高温 : 高温23 ,丰利 3360 ![CDATA [Level 1]],低 3360 低温11,风行 3360 南风,类型 : 多云 }
],
感冒频繁期间,适当减少外出次数,适当补充水分,适当增减衣物。杜文 : 8},状态 : 1000, desc: 正常 }
请求格式
这里不得不说,中国天气网yyds的界面完全没有限制。为什么?我想做的是获取全国的天气信息,包括县城,全国几千个县城,还要按时间分析,所以每天的请求访问至少2w起。如果有限制,我们就得倒着爬,但通过我的测试,没问题。
请求限制
来,我们先做个对比。没有比较就没有伤害对吧?因为很简单,我就直接编码了。
lass="brush:py;">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,"次访问")
times+=1
print("访问",times,"次耗时",time.time()-start,"秒")
这段代码呢,我做了一个简单的封装。 我们来看看结果,5000次访问花了多久
这里我5000次重复访问的是同一个城市 九江
异步获取
这个代码的话我是没有封装的,所以看起来比较乱。 这里有几个注意点先说一下
系统上限
由于这个,异步的话还是使用的操作系统的一个底层嘛,所以这个并发是有上限的,因为这个协程异步是要不断切换的是吧。看起来有点像python自己的多线程,只是这个多线程完全是当IO的时候才会切换,不然不会切换。 所以哟啊限制一下
编码
import timeimport 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() #得到返回结果
data = data.get("data").get("forecast")
for today_w in data:
if (today_w.get("date") == day):
TIMES+=1#只有IO操作的时候才会切换,所以这个++操作还是一个原子性操作
if(TIMES%100==0):
print(today_w,"第",TIMES,"次访问")
return today_w
if __name__ == __main__:
semaphore = asyncio.Semaphore(500)
#操作系统上限是同一个时刻509/1024个并发,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("耗时",time.time() - start,"秒")
到此这篇关于Python实战之异步获取中国天气信息的文章就介绍到这了,更多相关Python获取天气信息内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。