解决方案:如何获取百度云下载直链
优采云 发布时间: 2022-11-03 11:17解决方案:如何获取百度云下载直链
2021-07-27
最近在百度云学习资源上遇到了一个大问题。百度云把我的速度锁死了。然后百度了一个PanDownload神器,感觉很好用。总的原则是获取直接链接,然后全速下载。我很好奇,想看看如何获取百度云直连。我找到了一个现在仍然可以使用的方法。虽然有缺陷,只能用于从下载直链获取单个文件,但没关系。毕竟压缩后的文件也是单个文件哈哈哈。
1.将要下载的资源保存到自己的网盘中。
2. 右键分享。创建公共链接,一定要创建公共链接。得到下面的结果。
3.复制链接并用Chrome打开。打开控制台
4、输入如下js代码,用ajax发送请求。
$.ajax({
type: "POST",
url: "/api/sharedownload?sign="+yunData.SIGN+"×tamp="+yunData.TIMESTAMP,
data: "encrypt=0&product=share&uk="+yunData.SHARE_UK+"&primaryid="+yunData.SHARE_ID+"&fid_list=%5B"+yunData.FS_ID+"%5D",
dataType: "json",
success: function(d){
<p>
window.location.href = d.list[0].dlink;
}
});</p>
5. 然后它会自动开始作为直接链接下载。
当然,最后还是推荐使用 Pandownload 之类的。当然,这种东西大家都知道,传播得越快,死的也就越快。在这种情况下,我们可以通过上面的方法获取直接链接,然后愉快的下载。其实感觉就是处理后才能得到直链,最后向Pandownload的作者们致敬!
分类:
技术要点:
相关文章:
解决方案:调用链系列(三):解读UAVStack中的贪吃蛇-调用链
为了从请求中提取body和header,使代码的改动尽可能小,进入容器的请求必须被统一拦截,否则代码必须嵌入到所有的HttpServlet实现类中。在这里,我们需要再次感谢 servlet 说明符为我们提供的过滤机制。
该规范指定过滤器是一段可重用的代码,用于转换 HTTP 请求、响应和标头信息的内容。过滤器通常不会为请求创建响应,而是修改或调整请求和响应。其中,filter主要提供四种拦截方式:
这里我们只使用 REQUEST 模式。配置过滤器后,我们可以从过滤器的doFilter方法中获取HttpServletRequest和HttpServletResponse(简称请求和响应)。
获取标题
在上面,我们通过过滤机制获得了请求和响应。打开对应的源码实现,我们可以找到如下API:
规范为我们提供了一个 API 来直接获取标头。通过结合 getHeaderNames() 和 getHeader(String name) 方法,我们可以轻松获取请求和响应中的标头。
得到身体
获取请求体和响应体的方法大致相同。这里以request为例,后面会调整差异。
从请求API中我们可以发现body在java中是以ServletInputStream的形式存储的,而ServletInputStream是一个继承的InputStream。如果我们直接读取,用户获取到的body会是空的(因为InputStream只能读取一次),除非可以把指针放回去)。这里需要用到servlet的包装机制。
Servlet 中的包装器
有的人可能不会用到requestWrapper和responseWrapper,这里简单介绍一下。wrapper 是通过继承 servlet 规范中的 HttpServletResponseWrapper 和 HttpServletRequestWrapper 实现的装饰模式。相当于请求和响应的一个shell,类似于java中的代理,这样操作请求和响应的所有动作都会经过我们自定义的wrapper,使得在请求中重复获取body成为可能和回应。
编写自己的包装器
我们以 request 为例来说明如何编写自定义包装器。打开servlet-api源码可以看到HttpServletRequestWrapper继承了ServletRequestWrapper,实现了HttpServletRequest接口。
并且大部分方法已经在 ServletRequestWrapper 中为我们实现了。
我们只需要重写我们关心的几个方法,例如:getInputStream和getReader等。
当用户尝试调用 getReader 或 getInputStream 时,我们将其替换为自己的流,并额外提供一个 getContent() 方法来提前读取 StringBuilder 或 byte[] 中的正文内容进行提取。
编写好自定义包装器后,我们可以将其放入我们上面定义的过滤器中,替换原来的请求。然后把用户的请求变成我们的requestWrapper。
优化提取逻辑
上面提到的方法等价于预先读取收录body的inputStream,并将其存储在一个中间byte[]或StringBuilder中。当用户调用 getInputStream 时,byte[] 或 StringBuilder 被转换为 inputStream 返回给用户。如果用户根本不关心这个http请求的body,也就是用户根本不使用这个请求的body,那么我们提前把它读出来,相当于做了无用功(浪费宝贵的 CPU 时间和内存资源)。如何保证inputStream在用户使用时是只读的,当用户或后续逻辑多次获取body时,是我们的优化目标。
对于答案,我们继续从源码中寻找。既然我们的数据在 inputStream 中,我们就跟着源码看看是怎么读取的。在servlet规范中,inputStream被封装成ServletInputStream,ServletInputStream提供了readLine方法。往里面看,可以看到它们都调用了inputStream中的read方法,如下图:
既然read方法是一个统一的入口,那我们只要自定义一个ServletInputStream,重写里面的read()方法,就可以修改所有的read方法吗?答案是肯定的。只要用户调用了read方法,我们就悄悄地把我们关心的内容复制一份,这样我们只在用户使用body的时候才去采集。
下一步是如何确保用户调用 read 多次,我们总是只读取一次。在这里,我们需要使用一个 AtomicBoolean 标志,当执行完整读取时将其设置为 true,否则设置为 false。最终效果如下:
举一反三
在这里,我们使用 servlet 规范中的过滤器和包装器机制来获取进入我们容器(tomcat)的所有 http 请求的主体和标头。这个能力在我们实际生产中可以进一步扩展,比如:我们需要在客户端加密一些敏感数据然后在服务端进行统一解密,格式化客户端发送的数据格式等等。可以限制你的是你的想象力。希望本次技术分享对您以后的工作和生活有所帮助。
总结
读完这篇文章,读者应该可以在不影响原代码的情况下,通过简单的代码获取所有进入容器的http请求的body和header。虽然可能需要适配一些特殊的技术栈,比如如果项目中使用了jersey,参数等信息以application/x-www-form-urlencoded的形式传递,而服务端不使用@ FormParam注解获取参数,那么我们获取body后,用户将无法获取参数;例如,如何区分媒体类型,如果是图像,则不会被提取。但我们已经验证,这条路是可行的,而且是成功的一半。