MENU

分享一个蓝奏云批量下载工具

June 9, 2020 • Read: 736 • 学习记录

分享一个蓝奏云批量下载工具

前言


​ 自己平时找电子书看的时候,有些分享链接是蓝奏云的,下载文件只能一个一个的点进去后下载(这点我想吐槽下),然后我就开始实施我的想法了。自己还是比较喜欢看日本的轻小说的,有相同兴趣的可以交流一波。嘿嘿::quyin:heng::

效果展示


在浏览器中打开链接


image-20200609164326270.png

控制台界面


image-20200609164551012.png

下载文件


image-20200609164656345.png

代码思路


​ 由于网上也是有很多人写过,自己就不再写了(其实主要是懒)。具体可以直接参考链接里面的第一个Python爬取蓝奏云直链(获取真实文件地址),可以看到详细的过程,还有代码里面也有相应的注释,可以很轻易的看懂。

代码


获取单个文件下载链接的类,是入口

LanZouYunMain.py

# 批量下载蓝奏云的文件,
from bs4 import BeautifulSoup
from LanZouYun import LanZouYun
import os
from time import sleep
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 定义URL的地方
url = "https://www.lanzoux.com/b015g57ni"
# if re.match(r'https://lanzous.com/([\w]+?)', url):
#     print("请输入正确的链接")
if url.__contains__("https://") == 0:
    url = "https://" + url
# 验证码
auth_code = 'dibb'
bro = webdriver.Chrome(executable_path="chromedriver.exe", options=chrome_options)
bro.get(url)
# 等待加载2秒
sleep(1)
auth_input = bro.find_element_by_id('pwd')
# 输入验证码
auth_input.send_keys(auth_code)
# sleep(1)
# 根据xpath定位,点击确认按钮
btn = bro.find_element_by_xpath("//input[@id='sub']")
btn.click()
# 等待点击确认后的异步加载完成
sleep(0.5)
res_mes = bro.find_element_by_xpath("//*[@id='pwderr']")
# print(res_mes.text)
if res_mes.text == '密码不正确':
    print("密码不正确")
else:
    # 休眠两秒,等待加载
    sleep(2)
    page_text = bro.page_source
    soup = BeautifulSoup(page_text, "lxml")
    # 文件目录名
    dirName = soup.select("#sp_name")[0].string
    dir_name = "./" + dirName
    # print(dir_name)
    if not os.path.exists(dir_name):
        os.mkdir(dir_name)

    # 得到所有的文件的链接和文件名
    file_list = soup.select("#ready")
    # 获取链接前缀
    link = url[:url.index(".com/")+5]
    print(" --- 下载开始 ---")
    for file in file_list:
        # 获取单个文件名
        fileName = file.select("#name > a")[0].string
        # 获取单个文件的链接
        fileLink = link + file.select("#name > a")[0]["href"]
        LZY = LanZouYun(fileLink, dir_name, fileName, link)
        LZY.download()
        # break
        print(fileName + " =====> 下载完成")
    print(dirName + " =====> 下载完毕")
    bro.quit()

直接下载单个文件的类

LanZouYun.py

# 下载蓝奏云的文件,下载单个文件
from bs4 import BeautifulSoup
import requests as req
import re
import json
from time import sleep


class LanZouYun(object):
    def __init__(self, url, dir_name, fileName, link):
        self.url = url
        self.dir_name = dir_name
        self.fileName = fileName
        self.link = link
    def download(self):
        #蓝奏云分享文件链接地址
        # url = "https://www.lanzous.com/i3xcmaf"
        #header头,注意那个referer必须要与上面文件分享地址url相同
        headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
        'referer': self.url
        }
        # 获取分享页面html文件
        res = req.get(self.url, headers=headers)
        # 引入BeautifulSoup库对html进行处理,获取iframe中的出现的js文件
        soup = BeautifulSoup(res.text, "lxml")
        # 得到伪直链
        url_2 = self.link + soup.find('iframe')['src']

        res2 = req.get(url_2, headers=headers)
        # 得到请求的参数,sign参数的值,可能直接放在cots变量后面
        params = re.findall(r"[^//]data : { 'action':'downprocess','sign':(.*?),'ves':1 }",res2.text)[0]
        # 可能出现sign参数对应的值是一个变量,所以还需查找
        if len(params) < 10:
            params = re.findall(r'var '+ params +' = \'([\w]+?)\';//',res2.text)[0]
        # 请求下载地址
        url_3 = self.link + "ajaxm.php"
        data = {
            "action": "downprocess",
            "sign": params,
            "ves": 1
        }
        res3 = req.post(url_3, headers=headers, data=data)
        res3 = json.loads(res3.content)
        # print(res3)
        # 请求最终地址
        url_4 = res3['dom']+'/file/'+res3['url']
        headers2 = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
            'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        }
        # print(url_4)
        # 重定向得到真正的下载地址
        res4 = req.head(url_4, headers=headers2)
        # 得到响应头中location的值
        url_5 = res4.headers['Location']
        # print(res4.headers['Location'])
        res5 = req.get(url_5, headers=headers2)
        with open(self.dir_name + '/' + self.fileName, 'wb') as fp:
            fp.write(res5.content)

未完

1、可能还是会写一个UI界面,但是不知道什么时候能完成。。。(无限拖......::quyin:witty::)

2、可能还会出一个不需要填提取码就能下载的功能

参考链接


Python爬取蓝奏云直链(获取真实文件地址)

蓝奏云批量下载工具的实现思路笔记


Last Modified: October 8, 2020