python程序下载天文学数据

  • 文件下载模块
  • 使用正则表达式检索下载链接
  • 接下来就是批量下载了
  • 总程序代码

文件下载模块

首先编写一个专门用于下载文件的函数

def downloadFile(name,url,TIMEOUT):#download File, name=File, url=download address,TIMEOUT是超时时间,并返回下载状态headers = {'Proxy-Connection':'keep-alive'}i = 0while i < 3: #尝试三次try:r = requests.get(url,timeout=TIMEOUT,stream=True, headers=headers)#TIMEOUT 设置超时length = float(r.headers['content-length']) #文件长度f = open(name, 'wb')count = 0count_tmp = 0time1 = time.time()for chunk in r.iter_content(chunk_size = 512):if chunk:f.write(chunk)count += len(chunk)if time.time() - time1 > 2:  #2s 统计一次p = count / length * 100 #下载百分比speed = (count - count_tmp) / 1024 / 1024 / 2#速度 MB/Scount_tmp = countprint(name + ': ' + formatFloat(p) + '%' + ' Speed: ' + formatFloat(speed) + 'MB/S')time1 = time.time()print(name + ': download finished!')f.close()return 'successful'except requests.exceptions.RequestException:#超时异常print(name+'connect timeout——try again',i+1)i = i + 1#只有超时异常才尝试三次except KeyError:#IO异常print(name+'无效链接\n')i=3return 'link_error'except Exception:#所有其它异常print(name+"下载错误\n")i=3return 'link_error'return 'Timeout' #走完循环还没有下载完,即Timeout

此处使用了python request下载文件时,显示进度以及网速的代码。
但是最好加上超时设置,不然很容易会卡死,我的代码部分已经添加在上面的程序一起了。

def gethtml(url,timeout):#超时设置 三次请求i = 0while i < 3:try:html = requests.get(url, timeout).textreturn htmlexcept requests.exceptions.RequestException:i += 1print('connect timeout')

这里是参考了链接: Python:requests:详解超时和重连.

这里的下载代码要求:

  1. 分块下载,下载大文件有用
  2. 有超时设定,跳过下不动的文件
  3. 异常捕获,避免链接错误程序崩溃
  4. 网络连接检测(我这里还没加上去)

使用正则表达式检索下载链接

将目标网页的内容打开,用正则表达式筛选出其中的下载链接,并将链接写到文本输出。

def Url_matching(url,file_link_list):#挑选目标url的所有链接并输出至txt#string要匹配的url内容, file_link_list:输出的文件夹(链接)opener = urllib.request.build_opener()html = opener.open(url).read().decode('utf8')#抽取url网页数据print('open url successfully')pattern1 = re.compile(r'<tr><td><a href=.*?>')#匹配规则1 找出所有下载链接pattern2 = re.compile(r'".*?"')#匹配规则2 去掉多余的'<tr><td><a href=' >link_list = pattern1.findall(html)  #html要匹配的文本 findall返回为列表#link_list = list(set(link_list)) #去掉重合元素 通过列表转集合f = open(file_link_list,'w')for i in range(len(link_list)):temp = pattern2.findall(link_list[i])#第二次筛选link_list[i] = temp[0] #返回回第一个匹配字符串 只有一个link_list[i]=str(link_list[i]).strip('"')#去掉首尾引号f.write(url+link_list[i])#将得到的链接写入txt 加上前缀得到下载地址f.write("\n")f.close()print('link_list have saved in'+file_link_list)

其中这里的匹配规则pattern1和pattern2可以参考以下链接链接:

  1. Python常用正则表达式语法和写法.
  2. 【python】去除字符串头尾的多余符号.
  3. Python网络爬虫——把一个网页中所有的链接地址提取出来(去重).
  4. python爬虫知识:正则表达式

这个函数的作用就是输入url目标网址,把里面的链接都提取出来到file_link_list文本里,当然,要根据需要修改正则表达式pattern1和pattern2等等,这里只是针对我的情况来定。

这里的代码要点是:

  1. 打开需要的网址
  2. 在网址内容中准确识别下载链接(取决于正则表达式的准确,可以使用多次判别)
  3. 把识别的下载链接整齐的保存至文档中,方便接下来使用

接下来就是批量下载了

前面已经写好了爬取下载链接的代码和含超时和错误处理的下载函数,并将链接按规格保存至file_link_list里了,接下来就是批量下载,并输出下载目录了。

同时也要考虑超时后的文件不完整,需要将其删除,这里参考了
使用python删除一个文件或文件夹

我这里并没有用这个方法,因为发现程序有冲突,我改而用个取巧的办法:先把文件下在一个temp文件夹里面,如果完整下载就移入path文件夹里。

import os
path = 'F:/新建文本文档.txt'  # 文件路径
if os.path.exists(path):  # 如果文件存在# 删除文件,可使用以下两种方法。os.remove(path)  #os.unlink(path)
else:print('no such file:%s'%my_file)  # 则返回文件不存在

同时也要输出待下载的链接列表,下载完成的链接列表,超时的链接列表,无效的链接列表。

def writing_left(file_name,list_in,i): #剩余的链接写进文本with open(file_name, 'w') as f:    #下次重此开始即可for i in range(i,len(list_in)):f.writelines(list_in[i])f.close()def donwnlaod_all(file_link_list,output_faild):#批量下载 file_link_list:爬到的下载链接 output_faild:下载失败的链接successful_count = 0 #下载成功数量Timeout_count = 0  #超时失败数量error_count = 0 #链接错误数量Total_count = 0 #总数#暂时将所有链接存在列表里link_list = []  with open(file_link_list,'r') as file:for line in file:#按行读取下载地址链接link_list.append(line)with open(file_link_list,'r') as file:for line in file:#按行读取下载地址链接line = line.strip()#去掉行末的换行符file_name = temp + line.rsplit('/', 1)[-1] #取下载链接最后一段为文件名 保存在temp文件夹中    status = downloadFile(file_name,line,TIMEOUT)if status == 'successful' :shutil.move(file_name,path) #成功完整下载 将之移到path文件夹里writing_link(path_output+status+'.txt',line,successful_count)#成功的链接successful_count = successful_count + 1if status == 'link_error' :writing_link(path_output+status+'.txt',line,error_count)#错误链接error_count = error_count + 1if status == 'Timeout' :writing_link(path_output+status+'.txt',line,Timeout_count)#超时的链接Timeout_count = Timeout_count + 1#三次超时后的处理,删除不完整的文件'''if os.path.exists(file_name):  # 如果文件存在os.remove(file_name)       #删除文件'''Total_count = Total_count + 1writing_left(remainder,link_list,Total_count)  #保存剩余没下载的链接          print('successfully download files:',successful_count)#统计下载数量print('faild download files:',error_count+Timeout_count)

为啥我要保留待下载的链接列表呢?因为下次下载的时候可以直接从这里开始。

这里的要点是:

  1. 下载文件要完整,不完整要删除
  2. 要有待下载的链接列表,方便下次再来
  3. 输出无效,错误的下载连接,避免重复下载
  4. 下载不完整的文件去掉

总程序代码

import requests
import time
import os
import shutil
import re
import urllib.requestTIMEOUT = 5 #单次超时设定
file_link_list = "link_list.txt"
output_faild = "faild_download.txt"
url="https://*********"  #这里我删除的我爬的网址了
path = './date_set/'
temp = './temp/' #下载数据暂存
path_output = './output/'
remainder = './output/remainder_link.txt' #剩余没下载的链接def formatFloat(num):#输出统一格式return '{:.3f}'.format(num)def downloadFile(name,url,TIMEOUT):#download File, name=File, url=download address,TIMEOUT是超时时间,并返回下载状态headers = {'Proxy-Connection':'keep-alive'}i = 0while i < 3: #尝试三次try:r = requests.get(url,timeout=TIMEOUT,stream=True, headers=headers)#TIMEOUT 设置超时length = float(r.headers['content-length']) #文件长度f = open(name, 'wb')count = 0count_tmp = 0time1 = time.time()for chunk in r.iter_content(chunk_size = 512):if chunk:f.write(chunk)count += len(chunk)if time.time() - time1 > 2:  #2s 统计一次p = count / length * 100 #下载百分比speed = (count - count_tmp) / 1024 / 1024 / 2#速度 MB/Scount_tmp = countprint(name + ': ' + formatFloat(p) + '%' + ' Speed: ' + formatFloat(speed) + 'MB/S')time1 = time.time()print(name + ': download finished!')f.close()return 'successful'except requests.exceptions.RequestException:#超时异常print(name+'connect timeout——try again',i+1)i = i + 1#只有超时异常才尝试三次except KeyError:#IO异常print(name+'无效链接\n')i=3return 'link_error'except Exception:#所有其它异常print(name+"下载错误\n")i=3return 'link_error'return 'Timeout' #走完循环还没有下载完,即Timeoutdef Url_matching(url,file_link_list):#挑选目标url的所有链接并输出至txt#string要匹配的url内容, file_link_list:输出的文件夹(链接)opener = urllib.request.build_opener()html = opener.open(url).read().decode('utf8')#抽取url网页数据print('open url successfully')pattern1 = re.compile(r'<tr><td><a href=.*?>')#匹配规则1 找出所有下载链接pattern2 = re.compile(r'".*?"')#匹配规则2 去掉多余的'<tr><td><a href=' >  link_list = pattern1.findall(html)  #html要匹配的文本 findall返回为列表#link_list = list(set(link_list)) #去掉重合元素 通过列表转集合with open(file_link_list,'w') as f:for i in range(len(link_list)):temp = pattern2.findall(link_list[i])#第二次筛选link_list[i] = temp[0] #返回回第一个匹配字符串 只有一个link_list[i]=str(link_list[i]).strip('"')#去掉首尾引号f.write(url+link_list[i])#将得到的链接写入txt 加上前缀得到下载地址f.write("\n")f.write('TOTAL LINK '+ str(i))#在文档最好统计链接个数print('link_list have saved in'+file_link_list)def writing_link(file_name,contents,i):#输出记录if i == 0 :with open(file_name, 'w') as f:  f.writelines(contents+'\n')else :with open(file_name, 'a') as f:  f.writelines(contents+'\n')f.close()def writing_left(file_name,list_in,i): #剩余的链接写进文本with open(file_name, 'w') as f:    #下次重此开始即可for i in range(i,len(list_in)):f.writelines(list_in[i])f.close()def donwnlaod_all(file_link_list,output_faild):#批量下载 file_link_list:爬到的下载链接 output_faild:下载失败的链接successful_count = 0 #下载成功数量Timeout_count = 0  #超时失败数量error_count = 0 #链接错误数量Total_count = 0 #总数#暂时将所有链接存在列表里link_list = []  with open(file_link_list,'r') as file:for line in file:#按行读取下载地址链接link_list.append(line)with open(file_link_list,'r') as file:for line in file:#按行读取下载地址链接line = line.strip()#去掉行末的换行符file_name = temp + line.rsplit('/', 1)[-1] #取下载链接最后一段为文件名 保存在temp文件夹中    status = downloadFile(file_name,line,TIMEOUT)if status == 'successful' :shutil.move(file_name,path) #成功完整下载 将之移到path文件夹里writing_link(path_output+status+'.txt',line,successful_count)#成功的链接successful_count = successful_count + 1if status == 'link_error' :writing_link(path_output+status+'.txt',line,error_count)#错误链接error_count = error_count + 1if status == 'Timeout' :writing_link(path_output+status+'.txt',line,Timeout_count)#超时的链接Timeout_count = Timeout_count + 1#三次超时后的处理,删除不完整的文件'''if os.path.exists(file_name):  # 如果文件存在os.remove(file_name)       #删除文件'''Total_count = Total_count + 1writing_left(remainder,link_list,Total_count)  #保存剩余没下载的链接          print('successfully download files:',successful_count)#统计下载数量print('faild download files:',error_count+Timeout_count)#Url_matching(url,file_link_list)#爬取链接
donwnlaod_all(file_link_list,output_faild)#批量下载文件

最好一点,就是这里我没有针对反爬虫做任何操作,因为我要爬的网站并没有反爬虫,如果要增加对应反爬虫的网站,可以试一下使用代理等方法。
最后还参考了这里:
Python实现断点续传下载文件,大文件下载还怕下载到一半就断了吗?不存在!

python程序下载大量天文学数据相关推荐

  1. Python批量下载CHIRPS气象数据并完成解压裁剪等

    文章目录 前言 一.CHIRPS是什么? 二.实现步骤 1.下载数据 2.解压缩 3.批量裁剪 三.完整代码如下 四.代码结果 前言   最近需要下载气象数据--CHIRPS,借助之前学的批量下载哨兵 ...

  2. Python 程序员如何防止数据被修改?

    作者 | PayneLi 责编 | 郭芮 程序员转行学什么语言? https://edu.csdn.net/topic/ai30?utm_source=csdn_bw 在平时工作中,经常涉及到数据的传 ...

  3. python程序下载_Python 基础起步 (二) 5分钟内下载环境并运行第一个Python 程序

    下载并安装Anaconda 好啦,作为小白,我们的第一步是安装能够运行Python的环境,所谓环境就是指我们要安装一个软件,之后就能用它来写Python代码 (觉得我对环境解释特别智障的请绕行,我们是 ...

  4. python电脑下载-PC端数据下载软件开发(Python)

    存储工具:阿里云->对象存储 需要将数据从云端下载到本地后再进行后续分析处理. 手动下载 需要下载的文件不多时,可以用这个方式. 依次点击:阿里云->控制台->对象存储->Bu ...

  5. Python脚本下载TCGA大数据,非常简单,开放源代码

    前言 使用TCGA官方的gdc-client下载工具有时候很慢,经常会挂掉,那干脆自己写一个下载小程序.于是使用TCGA的API写了个下载TCGA数据的脚本,脚本也是需要下载manifest文件的. ...

  6. python程序下载是免费的吗_python软件都是免费的吗

    python软件免费吗? python是免费的,是自由.开放源码的软件之一,在python官网可以免费下载,使用者可以自由地发布这个软件的拷贝.阅读它的源代码.对它做改动.把它的一部分用于新的自由软件 ...

  7. Python 程序下载经办人照片

    进行图片下载,需要提前准备好下载图片的存放文件夹: python在与文件.目录打交道时,少不了os模块.os模块包含普遍的操作系统功能. os.path.exists(filepath)--检验指定的 ...

  8. Python 批量下载 ERA-5 Reanalysis 数据

    ECMWF大气再分析数据集 ERA-interim 已被 ERA-5 数据集取代,ERA-5 详细信息看这里 下面介绍下载的具体步骤: 1. 要下载 ERA-5 数据集,需要先注册一个 CDS 账号. ...

  9. python程序下载及安装_安装下载python的安装和配置

    查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧! 1.安装python pythson2.4下载址地:http://www.python.or ...

最新文章

  1. php 比较字符串差,PHP字符串比较函数strcmp()和strcasecmp()使用总结
  2. SAP 如何看某个TR是否传入了Q或者P系统?
  3. 规范-编码规范总结(微信分销系统)
  4. oracle中批量更新,oracle 批量更新
  5. 计算机控制zos,第二章zOS操作系统的功能概述2.1zOS的内存管理.PDF
  6. 用3ds导入spk文件好小坐标多_2020东莞长安贴片厂代工代料哪家好-鸿鑫辉
  7. search string iteration
  8. android 模拟 cdrom,stm32 usb 虚拟一个cdrom
  9. 120万人同时在线考试,这么大的流量如何支撑
  10. iPhone 12 5G更耗电?续航时间较4G妥妥地缩短不少
  11. c++求两点的距离利用友元_用c++定义两个坐标点,计算两点间距离;进而计算线段的面积...
  12. SQL SERVER存储过程批量插入数据库表数据
  13. java canvas画矩形,HTML5 编程之Canvas
  14. 智能电话机器人源码安装 部署好后,人工智能电话机器人,不仅仅是打电话而已!
  15. 微信小程序申请微信支付0.2费率商户号微信小程序接入开通流程
  16. 推荐10本大数据领域必读的经典好书(火速收藏)
  17. C语言题目:新胖子公式 (10 分)
  18. 举个栗子!Tableau 技巧(185):实现多度量嵌套排序
  19. 树莓派智能家居homeassistant之homekit篇
  20. python随机漫步_Python实现随机漫步功能

热门文章

  1. 有些事一转身就是一辈子(转载)
  2. element ui 弹出网页 像layui弹出url一样 iframe element ui 弹出层嵌入网页
  3. linux安装新字体的方法
  4. 联想yoga 14s 2021标压版怎么样?测评值得买吗?详细性能点评
  5. 【IDEA插件开发】Quick Fix 快速修复插件开发
  6. 【已解决】为什么每次打开word2010都显示windows正在配置
  7. 【适合Python语言小白的股价图】利用Python中的matplotlib绘制股价图(非k线图)
  8. YZNCMS基于thinkphp开发的cms
  9. Educational Codeforces Round 127 (Rated for Div. 2) A~E 题解
  10. JavaWeb day10会话技术