• 售前

  • 售后

热门帖子
入门百科

用Python主动下载网站全部文件

[复制链接]
侬去斯 显示全部楼层 发表于 2021-10-26 12:50:59 |阅读模式 打印 上一主题 下一主题
目次


  • 总体思绪:
  • 判断链接是否指向文件:
  • 下载文件:
  • 获取 url 下的全部链接:
最近维基 jie mi 彻底公开了网站的全部文件,我就在想怎样利用 Python 将其下载到本地永世生存,于是就有了这篇文章,写爬虫会碰到很多坑,借鉴他人经验,思量越全面,出错的概率就越小。

假如一个网站,内里有很多链接,有指向文件的,有指向新链接的,新的链接点击进去后,仍旧是有指向文件的,有指向新链接的,雷同一个文件夹,内里即有文件,又有目次,目次中又有文件和目次。怎样从这样的网站上下载全部的文件,并按网站的目次结构来生存这些文件呢?
关键词:Python、下载、正则表达式、递归。
按照自顶向下来计划步调,我们整理自己的思绪,然后利用 Python 语言来翻译下即可。
思绪:由于目次的深度不固定,也不大概穷举,且每一个目次的处理方式和子目次父目次的处理流程都是一样的,因此我们可以利用递归来下载全部文件。
递归代码必须要有退出条件,退出条件要放在前面,本例中的递归退出条件就是:假如是文件就下载,下载完递归函数即完成使命。

总体思绪:


1、给定一个 url,判断是否是文件,假如是文件,下载即可,然后函数竣事。
2、假如给定 url 不是文件,那么访问该 url,并获取它下面的全部链接。
3、遍历步调 2 产生的全部链接,递归的执行步调 1 和 2,直到步调运行竣事。
以上思绪,用代码描述如下:
  1. import urllib.request
  2. import requests
  3. import re, os
  4. def get_file(url):
  5. '''
  6. 递归下载网站的文件
  7. :param url:
  8. :return:
  9. '''
  10. if isFile(url):
  11.   print(url)
  12.   try:
  13.    download(url)
  14.   except:
  15.    pass
  16. else:
  17.   urls = get_url(url)
  18.   for u in urls:
  19.    get_file(u)
复制代码
前面导入的包在接下来函数中会用到,下面就是渐渐层向下,实现子功能。

判断链接是否指向文件:


这里总结 url 规律,很容易写出。
  1. def isFile(url):
  2. '''
  3. 判断一个链接是否是文件
  4. :param url:
  5. :return:
  6. '''
  7. if url.endswith('/'):
  8.   return False
  9. else:
  10.   return True
复制代码
下载文件:


下载文件时要从 url 中获取文件应该存储的位置,并利用 os.makedirs 来创建多级目次。然后利用 urllib.request.urlretrieve 来下载文件。
  1. def download(url):
  2. '''
  3. :param url:文件链接
  4. :return: 下载文件,自动创建目录
  5. '''
  6. full_name = url.split('//')[-1]
  7. filename = full_name.split('/')[-1]
  8. dirname = "/".join(full_name.split('/')[:-1])
  9. if os.path.exists(dirname):
  10.   pass
  11. else:
  12.   os.makedirs(dirname, exist_ok=True)
  13. urllib.request.urlretrieve(url, full_name)
复制代码
获取 url 下的全部链接:


这里要详细网站详细分析,看看怎样利用正则表达式获取网页中的链接,这样的正则表达式可以说是再简朴不过了。
  1. def get_url(base_url):
  2. '''
  3. :param base_url:给定一个网址
  4. :return: 获取给定网址中的所有链接
  5. '''
  6. text = ''
  7. try:
  8.   text = requests.get(base_url).text
  9. except Exception as e:
  10.   print("error - > ",base_url,e)
  11.   pass
  12. reg = '<a href="(.*)" rel="external nofollow" >.*</a>'
  13. urls = [base_url + url for url in re.findall(reg, text) if url != '../']
  14. return urls
复制代码
这里有个小坑,就是网站有个链接是返回上级页面的,url 的后辍是 '../' 这样的链接要去掉,否则递归函数就限入了死循环。
接下来就是写主函数,执利用命了,慢慢等它下载完吧。
  1. if __name__ == '__main__':
  2. get_file('https://file.wikileaks.org/file/')
复制代码
着实,还会存两个问题:
1、假如网站某页有个链接它指向了首页,那么递归步调仍旧会限入一个死循环,解决方法就是将访问过的 url 生存在一个列表里(或者其他数据结构),假如接下来要访问的 url 不在此列表中,那么就访问,否则就忽略。
2、假如下载的过程中步调忽然报错退出了,由于下载文件较慢,为了节约时间,那么怎样让步调从报错处继承运行呢?这里可接纳分层递归,一开始时先获取网站的全部一级 url 链接,次序遍历这些一级 url 链接,执行上述的 get_file(url) ,每访问一次一级 url 就将其索引位置加1(索引位置默以为0,存储在文件中或数据库中),步调停止后再运行时先读取索引,然后从索引处开始执行即可。别的,每下载乐成一个文件,就把对应的 url 也生存在文件中或数据库中,假如一级 url 下的链接已经下载过文件,那么就不需要重新下载了。
以上就是用Python主动下载网站全部文件的详细内容,更多关于python 主动下载网站文件的资料请关注草根技术分享其它相干文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作