万能的群友经常会发蓝色链接,其中有一些蓝色的蓝奏云,看见那么多学习资料实在是馋得很,必须全部拿下。
话不多说,直接开始。


index

  • 0.引用包
  • 1.分析
  • 2.过程
  • 3.整理
  • 4.完整代码

0.引用包

我这里用到了urllib3,现在的主流还是requests和urllib,各有各的特点,就目前我所需要的工具来说urllib3可以向下兼容,但相对requests来说缺少cookie管理。

import urllib3              # 主角
from lxml import etree        # 用于获取xpath
import re                    # xpath取不到的地方需要正则
import json                  # 用于将js字典转换为python字典
import os                    # 用于获得系统路径

1.分析

需要解析的URL如下图:

我们先用GET方法请求一下

# 实例化产生请求对象
http = urllib3.PoolManager(timeout=4.0)
# 构造请求包
url = '这里是需要解析的URL地址'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.3','referer': url
}
# get请求指定网址
resp = http.request('GET', url, headers=headers)
# 编码/解码
html = resp.data.decode('utf-8')

获得了该网页的源代码并保存到html中,现在很多网页都是这种动态式的,一堆数据发下来让你的浏览器自行处理,现在我们找到主要目标 下载链接 的构建函数:

对照一下,以上代码的执行效果如下:

现在回到函数,整个函数是通过msg的参数来运行的:

那么msg来自哪里呢,通过(初步)学习JS以及(立志)多年爬虫经验,可以知道,这个ajax方法通过post到filemoreajax.php所获取的包作为msg传递给函数,然后函数将数据整理好呈现出来。知道了这个行为,我们就可以跳过浏览器直接去这个地址拿数据。


2.过程

接下来对POST工作做一下前期铺垫:
首先需要构造data,上面的data里面有三个值(pgs / ibhkhh / ihfwja)为变量,可以从script标签开头找到,fid和uid虽然不是变量,但每个网页肯定会变,也要提取。

其余使用re进行提取,并构造包体,这里的 ‘t’ 和 ‘k’ 的变量名都是6位随机数,因此提取6位数开头的分号中的数据,pgs是页码,我们可以手动改,不用提取。

# 用re提取参数
title = re.findall(r'<title>([\w\W]+?)</title>', html, re.MULTILINE)    # 提取文件名,非post参数
# pgs = re.findall(r'pgs =([\d]*);', html, re.MULTILINE)
fid = re.findall(r'\'fid\':([\w]+?),', html, re.MULTILINE)
uid = re.findall(r'\'uid\':\'([\w]+?)\',', html, re.MULTILINE)
params = re.findall(r'var [\w]{6} = \'([\w]+?)\';', html, re.MULTILINE)
# 构造fields
fields = {'lx': 2,'fid': int(fid[0]),'uid': uid[0],'pg': 1,'rep': '0','t': params[0],'k': params[1],'up': 1,
}

铺垫完成,开始进行POST,转个码,然后转换为python格式的字典:

# post文件目录接口
indexApi = 'https://www.lanzoui.com/filemoreajax.php'
indexRes = http.request('POST', indexApi, headers=headers, fields=fields)
indexData = indexRes.data.decode('unicode_escape')
# 转换为python字典
index = json.loads(indexData)

整理后的数据存在了index中,‘text’ 里面的 ‘id’ 就是我们需要获取的下载地址


可以列个表,更加直观:

# 列出文件
print(title[0])
print('链接\t\t文件名\t\t大小\t\t时间')
for i in range(len(index['text'])):print(index['text'][i]['id'], end='\t\t')print(index['text'][i]['name_all'], end='\t\t')print(index['text'][i]['size'], end='\t\t')print(index['text'][i]['time'])


项目已经有了重大进展,但还没有完成,以最上面的链接为例:

可以发现三个按钮用的是同一个链接XD,这个链接才是下载地址,用xpath取出来GET一下(注意,GET的时候headers要带上accept-language参数,不然不给过,这个就很奇怪了)

downUrl = 'https://www.lanzoui.com/%s' % ibkvJtkvykj
downRes = http.request('GET', downUrl, headers=headers)
# 编码/解码
downData = downRes.data.decode('utf-8')
# 将data数据作为HTML选择器
selector = etree.HTML(downData)
# 下载按钮用的是iframe,所以还要再get一次真正的下载地址
downLink = selector.xpath('/html/body/div[3]/div[2]/div[4]/iframe/@src')[0]
# 请求iframe原链接
url2 = 'https://www.lanzoui.com%s' % downLink
headers2 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36','Accept-Language': 'zh-CN,zh;q=0.9','referer': url2
}
res2 = http.request('GET', url2, headers=headers2)
data2 = res2.data.decode('utf-8')

从data2中可以看到,下载连接就在ajaxm.php中,老样子构建并POST

# sign参数会改变,要先得到sign
sign = re.findall(r'\'sign\':([\w]+?),\'ves\'', data2, re.MULTILINE)[0]
ajaxdata = re.findall(r'var ajaxdata = \'(\??[\w]+?)\';', data2, re.MULTILINE)[0]
postsign = re.findall(r'var %s = \'([\w]+?)\';' % sign, data2, re.MULTILINE)[0]
websignkey = re.findall(r'\'websignkey\':\'([\w]+?)\'', data2, re.MULTILINE)[0]
# 构建fields
fields2 = {'action':'downprocess','signs':ajaxdata,'sign':postsign,'ves':1,'websign':'','websignkey':websignkey }
# 这次POST得到真正的下载链接
realUrl = 'https://www.lanzoui.com/ajaxm.php'
realRes = http.request('POST', realUrl, headers=headers2, fields=fields2)
realData = realRes.data.decode('utf-8')
realLink = json.loads(realData)

将dom与url组装起来就是真正的下载地址了

# 组装链接
downloadLink = realLink['dom'] + '/file/' + realLink['url']
# 然后GET
fin = http.request('GET', downloadLink, headers=headers2)

现在得到了针对浏览器的下载链接,如果要进一步偷懒则需要一点加工
这里的data实际上就是二进制流,可以直接储存为文件

# 先获取当前py文件位置
cd = os.getcwd()
# 如果当前位置没有该文件夹则创建一个
if not os.path.exists(title[0]) :os.mkdir(cd + '\\' + title[0])
# 创建 当前位置=>标题=>文件名 然后将获取的二进制数据写入
with open('%s\\%s\\%s' % (cd, title[0], index['text'][0]['name_all']), "wb") as file:file.write(fin.data)print('已下载\t%s' % index['text'][0]['name_all'])

3.整理

接下来进入最后一步,写一个循环进行批量下载。循环就简单了,把单个下载线程括起来变量改掉就完事了。

跑一下

alright,结束战斗

4.完整代码

import urllib3
from lxml import etree
import re
import json
import osdef getIndex(lanzoui):global titleglobal indexglobal headersurl = lanzouiheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.3','referer': url}resp = http.request('GET', url, headers=headers)html = resp.data.decode('utf-8')# pgs = re.findall(r'pgs =([\d]*);', html, re.MULTILINE) 提取出来没有用,我们手动去翻页title = re.findall(r'<title>([\w\W]+?)</title>', html, re.MULTILINE)fid = re.findall(r'\'fid\':([\w]+?),', html, re.MULTILINE)uid = re.findall(r'\'uid\':\'([\w]+?)\',', html, re.MULTILINE)params = re.findall(r'var [\w]{6} = \'([\w]+?)\';', html, re.MULTILINE)fields = {'lx': 2,'fid': int(fid[0]),'uid': uid[0],'pg': 1,'rep': '0','t': params[0],'k': params[1],'up': 1,}indexApi = 'https://www.lanzoui.com/filemoreajax.php'indexRes = http.request('POST', indexApi, headers=headers, fields=fields)indexData = indexRes.data.decode('unicode_escape')index = json.loads(indexData)print(title[0])print('链接\t\t文件名\t\t大小\t\t时间')for i in range(len(index['text'])):print(index['text'][i]['id'], end='\t\t')print(index['text'][i]['name_all'], end='\t\t')print(index['text'][i]['size'], end='\t\t')print(index['text'][i]['time'])def downFiles():for i in range(len(index['text'])):downUrl = 'https://www.lanzoui.com/%s' % index['text'][i]['id']downRes = http.request('GET', downUrl, headers=headers)downData = downRes.data.decode('utf-8')selector = etree.HTML(downData)downLink = selector.xpath('/html/body/div[3]/div[2]/div[4]/iframe/@src')[0]url2 = 'https://www.lanzoui.com%s' % downLinkheaders2 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36','Accept-Language': 'zh-CN,zh;q=0.9','referer': url2}res2 = http.request('GET', url2, headers=headers2)data2 = res2.data.decode('utf-8')sign = re.findall(r'\'sign\':([\w]+?),', data2, re.MULTILINE)[0]ajaxdata = re.findall(r'var ajaxdata = \'(\??[\w]+?)\';', data2, re.MULTILINE)[0]postsign = re.findall(r'var %s = \'([\w]+?)\';' % sign, data2, re.MULTILINE)[0]websignkey = re.findall(r'\'websignkey\':\'([\w]+?)\'', data2, re.MULTILINE)[0]fields2 = {'action':'downprocess','signs':ajaxdata,'sign':postsign,'ves':1,'websign':'','websignkey':websignkey}realUrl = 'https://www.lanzoui.com/ajaxm.php'realRes = http.request('POST', realUrl, headers=headers2, fields=fields2)realData = realRes.data.decode('utf-8')realLink = json.loads(realData)downloadLink = realLink['dom'] + '/file/' + realLink['url']fin = http.request('GET', downloadLink, headers=headers2)cd = os.getcwd()if not os.path.exists(title[0]):os.mkdir(cd + '\\' + title[0])with open('%s\\%s\\%s' % (cd, title[0], index['text'][i]['name_all']), "wb") as file:file.write(fin.data)print('已下载\t%s' % index['text'][i]['name_all'])print('已完成所有下载')http = urllib3.PoolManager(timeout=4.0)if __name__ == '__main__':getIndex('https://www.lanzoui.com/xxxxxxx')  # 这里是网址downFiles()     # 这里是下载函数,可以考虑做一个中断控制,我用不到就不做了# -*- coding: utf-8 -*-
# @Description  : 蓝奏云是个好网站,下载请不要泛滥,良好的互联网环境需要我们共同来维护
# @Date         : 2021/09/10
# Copyleft © 2021 Ursa

蓝奏云批量下载 with urllib3 — Python39相关推荐

  1. 蓝奏云批量下载修复版 v0.3

    蓝奏云可以说的上是一款下载速度快且小巧的小工具,找电子资源的时候都可以随意下载完成,但是由于有的电子资源文件比较多,又因为蓝奏云没有批量下载这一项功能.因此小编今天为大家带来了蓝奏云批量下载器,是该作 ...

  2. 蓝奏云批量下载v0.3修复版

    简介: 这是一款可以批量下载蓝奏云分享的文件夹下的所有文件的小工具,之前找电子书资源的时候,网友分享的蓝奏云地址,里面的文件有点多,但是,蓝奏云并没有批量下载功能,我又不想一个个点击下载,便是产生了这 ...

  3. 如何把蓝奏云里的文件进行批量导出分享?蓝奏云批量分享的工具

    蓝奏云用的的多了,里面文件管理起来就非常的麻烦,在这里分享一下如何方便得批量分享蓝奏云中的文件. 首先需要下载一个软件 简单麦麦客户端 下载地址在 https://gitee.com/firesuir ...

  4. 高仿蓝奏云盘下载页面源码

    介绍: 最近刚扒的蓝奏云下载页面,喜欢的可以下载下来! 网盘下载地址: http://www.bytepan.com/uRK58CrLRK4 图片:

  5. php获取蓝凑云文件列表,PHP获取蓝奏云直链下载地址

    @link https://mlooc.cn */ function MloocCurl($url,$method,$ifurl,$post_data){$UserAgent = 'Mozilla/5 ...

  6. qq复读机java脚本分享蓝奏云_真正可用的蓝奏云地址解析及下载脚本

    蓝奏云的下载链接解析思路并不复杂,但网上几款真实链接解析工具,要么解析出的地址只是跳转链接,要么需要输入验证码,而蓝奏云网页版在使用是几乎是不会遇上验证码的,这实际上是因为蓝奏云在下载过程中有几个小坑 ...

  7. 蓝奏云数值验证码识别,python调用虹鱼图灵识别插件,超高正确率

    识别验证码一直是本人想要做的事情,一直在接触按键精灵,了解到有一个虹鱼图灵识别插件专门做验证码和图像识别,原理就是图片处理和制作字库识别,制作字库我一直觉得很麻烦,工程量太大.不管怎样,它能用能达到我 ...

  8. 验证码识别的原理python_蓝奏云数值验证码识别,python调用虹鱼图灵识别插件,超高正确率...

    本帖最后由 打字的小强 于 2020-6-5 13:11 编辑 识别验证码一直是本人想要做的事情,一直在接触按键精灵,了解到有一个虹鱼图灵识别插件专门做验证码和图像识别,原理就是图片处理和制作字库识别 ...

  9. 蓝奏云外链批量下载软件

    软件介绍: 蓝奏云外链批量下载软件是一款功能强大的外链解析下载工具,能够帮助用户轻松下载各种蓝奏云文件,为文件的下载提供了便利:软件提供了各种方便快捷的下载功能,只需要粘贴下载链接即可使用,满足用户的 ...

最新文章

  1. BCH大涨带领币市小幅走高 个别币种走势逐步分化
  2. 润乾V5部署url应用名为空applet无法打印解决方案
  3. 主板后置音频接口图解_颜值出众、用料靠谱——华擎(ASRock)Z490 Extreme4极限玩家主板 简析...
  4. VSCode 如何新建vue模板 - 插件引入篇
  5. C# 关闭当前窗口打开另一窗口
  6. listdir在python3_Python3 os.listdir() 方法
  7. linux c 网络编程与信号量,linux网络编程-----线程同步--信号量
  8. ArcGis中这些你真的清楚么
  9. docker update
  10. SQLServer收缩数据库日志
  11. SHELL字符串使用总结
  12. noi 9271 奶牛散步
  13. oracle官方文档下载使用
  14. BlackBerry Enterprise Service 10 for Android下载
  15. 这16个数据可视化案例,惊艳了全球数据行业
  16. 视频下载工具annie 安装与使用
  17. input 框隐藏光标问题
  18. mac mini u盘安装系统_如何制作U盘启动盘安装操作系统
  19. [IT名人堂]《人件》作者:汤姆.迪马可
  20. 积化和差、和差化积公式及记忆

热门文章

  1. Windows系统U盘的检测
  2. K8S 1.13.4安装部署
  3. codeforces 120D Three Sons
  4. Chrome浏览器调试教程
  5. 美的空气能计算机故障维修,请问一下美的空气能热水器出现E0故障如何维修
  6. java毕业生设计学校旧书交易网站计算机源码+系统+mysql+调试部署+lw
  7. Android屏幕录像转换GIF解决方案
  8. 【巨杉数据库SequoiaDB】巨杉数据库 v5.0 Beta版 正式发布
  9. Flutter 插件url_launcher
  10. java通过反射越过范性检查