写了一个GK2A卫星数据爬取的程序,本身不难,记录下小知识。
根据URL下载文件,有些需要cookie,大文件下载防止文件损坏
headers = {
"Content-Type": ContentType,
"User-Agent": UA,
"Cookie": cookie
}
response = requests.get(uri, headers = headers,stream=True)
with open(the_file_path, "wb") as fp:
for chunk in response.iter_content(chunk_size=1024*2):
if chunk:
fp.write(chunk)
下载zip包,zip包解压
zipname = f"{static_uri_path[flag]}_{type}.zip"#压缩包名
the_file_path = os.path.join(file_path, zipname)#压缩文件地址
the_file_URL = f"{first_URL}{static_uri_path[flag]}&fileName={static_uri_path[flag]}.zip"#要下载的连接
try:
request_file(the_file_URL, cookie, the_file_path)#下载函数
print(the_file_URL, the_file_path)
#以下是zip操作
zip_file = zipfile.ZipFile(the_file_path)#对压缩包地址操作
zip_list = zip_file.namelist() # 得到压缩包里所有的文件
for f in zip_list:
zip_file.extract(f, file_path) # 循环解压文件到指定目录
zip_file.close() # 关闭文件,必须有,释放内存
except Exception as exc:
print("下载与解压错误", exc)
清理空白文件夹和压缩包
def dir_arrange(file_path):
"""
整理文件到指定目录
并删除空白文件夹
"""
dirpath = rf"{file_path}\work\00" #要删除的文件路径
filelist = os.listdir(dirpath)
allfile = []
for file in filelist:
allfile.append(dirpath + '/' + file)
for file in allfile:
shutil.move(file,file_path) #把文件夹内文件移走
os.removedirs(dirpath)
print("已删除空白文件夹!")
for files in os.listdir(file_path):
if files.endswith(".zip"):
os.remove(os.path.join(file_path, files))#删除zip文件
print("已删除zip文件!")
用正则表达式的方式提取cookie,正则的方式应用广泛
import re
SCOUTER = re.split('[,;]',response.headers['Set-Cookie'])[2].strip()#正则提取,通过,;进行分隔,并去空格
也可以用split连写,达成同样效果
remberuser = response.headers['Set-Cookie'].split(";")[3].split(",")[1].strip()
已经下载的文件排列顺序会按照0,1,10,11,19,2,20,21的顺序,不满足需求,需要排序
contents = show_files(traversal_file, []) # 循环打印show_files函数返回的文件名列表
contents.sort(key=lambda x: int(re.split('[._]',x)[3]))#按照数字顺序排序,re部分是正则表达式写法,整个int()内是文件名的数字部分即可
运用tqdm,实现等待时间读条
import tqdm
for i in tqdm(range(120),desc='等待缓存中'):#共120秒
time.sleep(1)#每1秒走一次
对于文件,tqdm下载时的进度显示
from tqdm import tqdm
import requests
url='https://dldir1.qq.com/qqtv/TencentVideo11.14.4043.0.exe'
response=requests.get(url,stream=True) # 设stream流传输方式为真
print(response.headers) # 打印查看基本头信息
data_size=round(int(response.headers['Content-Length'])/1024/1024) # 字节/1024/1024=MB,加上round上取整可以避免一种报错
with open('测试.exe','wb') as f:#测试.exe是路径下要命名的文件
for data in tqdm(iterable=response.iter_content(1024*1024),total=data_size,desc='正在下载',unit='MB'):
f.write(data)
"""
将iter_content(chunk_size)->chunk_size理解为一个列表的容量,
而iterable=response.iter_content(1024*1024)理解为分割字符串的函数,
将response.content分割为每个元素的长度是1024*1024大小的列表,在对每个部分进行下载。
这只是助于理解chunk_size的一个方法
而response.iter_content 是流传输(简单说就是边下载边写入磁盘),如果将chunk_size设置的很小,意味着每次
下载和存在很小的一部分,下载的速度也会很慢,如果设置的很大,则进度条的进度会错乱,因此我们在确定chunk_size
大小的时候应该对应文件大小,data_size除以多少,chunk_size就乘以多少,才能使进度条对应。
"""
一种从json格式中提取文件列表的简洁写法
data_list = response.json()
filesize_list = [data["fileSize"] for data in data_list["data"]]#把data中的所有fi