技术图文:如何爬取一个地区的气象数据(上)?
背景
架空线路主要指架空明线,架设在地面之上,是用绝缘子将输电导线固定在直立于地面的杆塔上以传输电能的输电线路。架设及维修比较方便,成本较低,但容易受到气象和环境(如大风、雷击、污秽、冰雪等)的影响而引起故障。
在对架空线路故障进行研究的时候,我们需要从网上爬取其所在位置的气象数据。
在爬取气象数据之前需要对爬取数据的网站进行分析,以邯郸地区为例:
2019年10月份天气数据的URL:
http://lishi.tianqi.com/handan/201910.html
2019年09月份天气数据的URL:
http://lishi.tianqi.com/handan/201909.html
以此类推,该网站可以获取邯郸地区2011年到2019年的全部数据,只要发现请求url地址的规律就可以自动化的下载这些数据了。本篇图文作为爬取数据的引导,先来介绍构造一个区间段日期的方法。
技术分析
1. datetime
模块简介
datetime
是Python处理日期和时间的模块,该模块包含一个datetime
类用来处理程序中遇到的日期和时间,还包含一个timedelta
类,通过该类可以对datetime
对象进行加减运算。
str
转换为datetime
datetime.strptime(date_string, format)
Return a datetime corresponding to date_string, parsed according to format.
from datetime import datetime
cday = datetime.strptime('2019-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
print(cday)
# 2019-06-01 18:19:59
字符串'%Y-%m-%d %H:%M:%S'
规定了日期和时间部分的格式。
%Y:四个数字表示的年份 2019
%y:两个数字表示的年份 19
%m:返回月份 范围[0,12]
%d:返回的是当前时间是当前月的第几天
%H:以24小时制表示当前小时
%I:以12小时制表示当前小时
%M:返回分钟数 范围 [0,59]
%S:返回秒数 范围 [0,61]
datetime
转换为str
time.strftime(format)
Return a string representing the time, controlled by an explicit format string.
from datetime import datetime
now = datetime.now()
sday = now.strftime('%Y-%m-%d %H:%M:%S')
print(sday)
# 2019-12-15 17:04:04
datetime
加减
对日期和时间进行加减实际上就是把datetime
往后或往前计算,得到新的datetime
。加减可以直接用+
和-
运算符,不过需要导入timedelta
这个类:
from datetime import datetime, timedelta
now = datetime.now()
print(now)
print(now + timedelta(hours=10))
print(now - timedelta(days=1))
print(now + timedelta(days=2, hours=12))
# 2019-12-15 17:26:51.035849
# 2019-12-16 03:26:51.035849
# 2019-12-14 17:26:51.035849
# 2019-12-18 05:26:51.035849
可见,使用timedelta
可以很容易地算出前几天和后几天的时刻。
2. calendar
模块简介
calendar.monthrange(year,month)
返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日);月从1到12。
calendar.weekday(year,month,day)
返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。
print(calendar.weekday(year=2019, month=12, day=1))
# 6
print(calendar.monthrange(year=2019, month=12))
# (6, 31)
代码实现(Python)
1. 引入的模块
from datetime import datetime, timedelta
import calendar
2. 获取所有天,返回一个列表。
def getBetweenDay(begin_date, end_date):
date_list = []
begin_date = datetime.strptime(begin_date, "%Y%m%d")
end_date = datetime.strptime(end_date, "%Y%m%d")
while begin_date <= end_date:
date_str = begin_date.strftime("%Y%m%d")
date_list.append(date_str)
begin_date += timedelta(days=1)
return date_list
例子
date = getBetweenDay('20110201', '20110301')
print(date)
# ['20110201', '20110202', '20110203', '20110204', '20110205', '20110206', '20110207', '20110208', '20110209', '20110210', '20110211', '20110212', '20110213', '20110214', '20110215', '20110216', '20110217', '20110218', '20110219', '20110220', '20110221', '20110222', '20110223', '20110224', '20110225', '20110226', '20110227', '20110228', '20110301']
3. 获取所有月,返回一个列表。
def add_months(dt, months):
# 返回dt隔months个月后的日期,months相当于步长
month = dt.month - 1 + months
year = dt.year + month // 12
month = month % 12 + 1
day = min(dt.day, calendar.monthrange(year, month)[1])
return dt.replace(year=year, month=month, day=day)
def getBetweenMonth(begin_date, end_date):
date_list = []
begin_date = datetime.strptime(begin_date, "%Y%m%d")
end_date = datetime.strptime(end_date, "%Y%m%d")
while begin_date <= end_date:
date_str = begin_date.strftime("%Y%m")
date_list.append(date_str)
begin_date = add_months(begin_date, 1)
return date_list
例子
month = getBetweenMonth('20111201', '20130201')
print(month)
# ['201112', '201201', '201202', '201203', '201204', '201205', '201206', '201207', '201208', '201209', '201210', '201211', '201212', '201301', '201302']
4. 获取所有季度,返回一个字典。
def getBetweenQuarter(begin_date, end_date):
# 加上每季度的起始日期、结束日期
quarter_list = {}
month_list = getBetweenMonth(begin_date, end_date)
for value in month_list:
year = value[:4]
month = value[4:]
if month in ['01', '02', '03']:
quarter_list[year + "Q1"] = ['%s0101' % year, '%s0331' % year]
elif month in ['04', '05', '06']:
quarter_list[year + "Q2"] = ['%s0401' % year, '%s0630' % year]
elif month in ['07', '08', '09']:
quarter_list[year + "Q3"] = ['%s0731' % year, '%s0930' % year]
elif month in ['10', '11', '12']:
quarter_list[year + "Q4"] = ['%s1001' % year, '%s1231' % year]
return quarter_list
例子
quarter = getBetweenQuarter('20111201', '20130201')
print(quarter)
# {'2012Q1': ['20120101', '20120331'], '2012Q3': ['20120731', '20120930'], '2012Q4': ['20121001', '20121231'], '2012Q2': ['20120401', '20120630'], '2011Q4': ['20111001', '20111231'], '2013Q1': ['20130101', '20130331']}
代码实现(C#)
1. 获取所有天,返回一个列表。
static List<string> GetBetweenDay(DateTime begin, DateTime end)
{
List<string> result = new List<string>();
while (begin <= end)
{
string year = begin.Year.ToString();
string month = begin.Month.ToString().PadLeft(2, '0');
string day = begin.Day.ToString().PadLeft(2, '0');
result.Add(string.Concat(year,month,day));
begin = begin.AddDays(1);
}
return result;
}
2. 获取所有月,返回一个列表。
static List<string> GetBetweenMonth(DateTime begin, DateTime end)
{
List<string> result = new List<string>();
begin = new DateTime(begin.Year, begin.Month, 1);
while (begin <= end)
{
string year = begin.Year.ToString();
string month = begin.Month.ToString().PadLeft(2, '0');
result.Add(string.Concat(year, month));
begin = begin.AddMonths(1);
}
return result;
}
3. 获取所有季度,返回一个字典。
static Dictionary<string, string> getBetweenQuarter(DateTime begin, DateTime end)
{
Dictionary<string, string> result = new Dictionary<string, string>();
List<string> lst = GetBetweenMonth(begin, end);
foreach (string str in lst)
{
string year = str.Substring(0, 4);
string month = str.Substring(4, 2);
switch (month)
{
case "01":
case "02":
case "03":
if (result.Keys.Contains(year + "Q1") == false)
{
result.Add(year + "Q1", year + "0101," + year + "0331");
}
break;
case "04":
case "05":
case "06":
if (result.Keys.Contains(year + "Q2") == false)
{
result.Add(year + "Q2", year + "0401," + year + "0630");
}
break;
case "07":
case "08":
case "09":
if (result.Keys.Contains(year + "Q3") == false)
{
result.Add(year + "Q3", year + "0701," + year + "1031");
}
break;
case "10":
case "11":
case "12":
if (result.Keys.Contains(year + "Q4") == false)
{
result.Add(year + "Q4", year + "1101," + year + "1231");
}
break;
}
}
return result;
}
总结
本篇图文介绍了如何利用 Python 和 C# 语言来构建一个区间段日期的方法,为后面爬取气象数据做准备。大家如果感兴趣可以试验一下啊。今天就这样吧!See You!
参考文献
- https://blog.csdn.net/joson1234567890/article/details/80946974
- https://www.liaoxuefeng.com/wiki/1016959663602400/1017648783851616
- http://www.imooc.com/wiki/detail/id/1911
往期活动
LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!
上一篇: mllib 假设检验