贴代码先:
#!/usr/bin/env python #知识点1
# -*- coding: UTF-8 -*-
import requests
import os
import time
#写日志
def write_log(full_path, file_name,status_code):
if status_code == 1 :
note = '开始下载文件:' + file_name + '\n保存地址:' + full_path + '\n等待服务器响应,这需要几十秒............\n请求服务器:成功\n正在下载文件,请稍等.......' + '\n文件:' + file_name + ' 已下载完成\n'+'时间:'+time.strftime("%Y/%m/%d/ %H:%M:%S")+'\n========================Done=========================\n'
open(full_path + 'log.txt', 'a').write(note + '\n')
else:
note = '开始下载文件:' + file_name + '\n保存地址:' + full_path + '\n等待服务器响应,这需要几十秒............\n请求服务器:失败\n请确认日期是否在数据库范围' + '\n请在另外一个命令行启动脚本下载 ' + file_name + ' 文件'+'\n时间:'+time.strftime("%Y/%m/%d/ %H:%M:%S")+'\n========================Done=========================\n'
open(full_path + 'log.txt', 'a').write(note + '\n')
#判断是否继续下一次下载
def whether_start():
while 1:
if_continue = input('上一个任务已经完成,是否继续下载 【y/n】')
if if_continue == 'y':
if_continue = True
break
elif if_continue == 'n':
if_continue = False
break
else:
print('输入有误请重新确认')
continue
return if_continue
#生成目录
def get_dir(start_month):
son_path = '2018-' + str(start_month).zfill(2) + '\\' #知识点2 指定长度的字符串前面填充0。
if not os.path.exists(father_path+son_path):
os.makedirs(father_path+son_path) #知识点3 递归创建目录
else:
pass
return father_path+son_path
#下载文件
def download(url,path,file_name,full_path):
# url = 'http://pifsc-oceanwatch.irc.noaa.gov/erddap/griddap/OceanWatch_goes-poes_sst_2day.htmlTable?sst[(2018-01-10T00:00:00Z):1:(2018-01-10T00:00:00Z)][(-1):1:(43)][(146):1:(336)]'
requ = requests.get(url, stream=True) #知识点4 网页请求 大文件下载
if requ.status_code == 200:
status_code = 1
note = '请求服务器:成功'
print(note)
note = '正在下载文件,请稍等.......'
print(note)
f = open(path, "wb")
for chunk in requ.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.flush()
# iter_content:一块一块的遍历要下载的内容
# iter_lines:一行一行的遍历要下载的内容
# 这两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据
# end = time.time()
# print('Finish in :', end - whether_start)
note = '文件:' + file_name + ' 已下载完成'
print(note)
print('时间:' + time.strftime("%Y/%m/%d/ %H:%M:%S"))
else:
status_code = 0
note = '请求服务器:失败\n请确认日期是否在数据库范围\n'+'请求服务器:失败\n请确认日期是否在数据库范围'
print(note)
note = '请在另外一个命令行启动脚本下载 '+file_name+'文件'
print(note)
print('时间' + time.strftime("%Y/%m/%d/ %H:%M:%S"))
write_log(full_path, file_name, status_code)
#主功能
def get_file():
print('=============================开始执行脚本=============================')
sign = 1
while sign :
try:
start_month = int(input('请输入开始月份:'))
start_date = int(input('请输入开始日期:'))
end_date = int(input('请输入结束日期:'))
if type(start_month) == int and type(start_date) == int and type(end_date) == int: #知识点5 if的简化
break
except ValueError: #知识点6 打印异常信息
print('输入数值有误,请重新输入,请输入数字\n')
full_path = get_dir(start_month) #full_path 是不包括文件名的路径
for page_num in range(start_date, end_date+1):
url = 'http://pifsc-oceanwatch.irc.noaa.gov/erddap/griddap/OceanWatch_goes-poes_sst_2day.nc?sst[(2018-{}-{}T00:00:00Z):1:(2018-{}-{}T00:00:00Z)][(-90.0):1:(89.95)][(0.0):1:(359.95)]'.format(str(start_month).zfill(2),
str(start_date ).zfill(2), str(start_month).zfill(2),str(start_date).zfill(2))
start_date += 1
file_name = url[-59:-49] + '.nc'
path = full_path + file_name # path是包含文件名的路径
note = '开始下载文件:' + file_name
print(note)
note = '保存地址:' + full_path + file_name
print(note)
print('下载链接:' + url)
print('等待服务器响应,这需要几十秒............')
download(url, path,file_name,full_path)
note = '========================Done=========================\n'
print(note)
return whether_start()
if __name__ == '__main__':
father_path = 'E:\\Panoply_data\\'
if_continue = 1
while if_continue:
if_continue = get_file()
#知识点1
#!/usr/bin/env python
这个在unix类的操作系统才有意义。
#!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python解释器;
#!/usr/bin/env python这种用法是为了防止操作系统用户没有将python装在默认的/usr/bin路径里。当系统看到这一行的时候,首先会到env设置里查找python的安装路径,再调用对应路径下的解释器程序完成操作。
#知识点2
str(start_month).zfill(2) 中 zfill()方法
Python zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。
str.zfill(width)
width -- 指定字符串的长度。原字符串右对齐,前面填充0。
#!/usr/bin/python
str = "this is string example....wow!!!";
print str.zfill(40);
print str.zfill(50);
结果
00000000this is string example....wow!!!
000000000000000000this is string example....wow!!!
#知识点3
os.makedirs(father_path+son_path)
1.mkdir( path [,mode] )
作用:创建一个目录,可以是相对或者绝对路径,mode的默认模式是0777。
如果目录有多级,则创建最后一级。如果最后一级目录的上级目录有不存在的,则会抛出一个OSError。
2.makedirs( path [,mode] )
作用: 创建递归的目录树,可以是相对或者绝对路径,mode的默认模式也是0777。
如果子目录创建失败或者已经存在,会抛出一个OSError的异常,Windows上Error 183即为目录已经存在的异常错误。如果path只有一级,与mkdir一样。所以使用时用判断语句判断下目录是否存在,如果存在就pass
if not os.path.exists(father_path+son_path):
os.makedirs(father_path+son_path) #知识点3
else:
pass
#知识点4
requ = requests.get(url, stream=True)
这个是网络请求的常用模块,如果是网页爬虫,那里面常用可能是
wb_data = requests.get(full_url,proxies=proxies,headers=headers)
proxies=proxies里面是代理ip的信息,防止你爬虫的时候人家封你ip
headers=headers里面的是用户代理信息,模仿人家点击访问的操作
在下载大文件的过程中,用到的是stream=Tru参数,当把get函数的stream参数设置成False时,它会立即开始下载文件并放到内存中,如果文件过大,有可能导致内存不足,下载下来的文件会不完整。
iter_content:一块一块的遍历要下载的内容
iter_lines:一行一行的遍历要下载的内容
使用上面两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据。
示例代码:
r = requests.get(url_file, stream=True)
f = open("file_path", "wb")
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
f.flush() 刷新缓存
#知识点5
if 结构简化
如果你需要检查几个数值你可以用以下方法:
if n in [1,4,5,6]:
来替代下面这个方式:
if n==1 or n==4 or n==5 or n==6:
所以原文知识点5那个
if type(start_month) == int and type(start_date) == int and type(end_date) == int:
可以替换成这个
if type(start_month)==type(start_date)==type(end_date): #知识点5
#知识点6
打印异常信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置。
下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序结构。如下所示
try:
...
except Exception as e:
print(str(e))
1、str(e)返回字符串类型,只给出异常信息,不包括异常信息的类型,如1/0的异常信息
2、repr(e)
给出较全的异常信息,包括异常信息的类型,如1/0的异常信息
3 或者except到了后,自定义处理