使用python实现带密码的百度云资源自动保存以及文件夹创建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/madonghyu/article/details/80602185

实现功能

将网盘的密码自动输入,得到真实的链接页面,并得到参数将文件自动保存到指定的文件夹,文件夹可以自己创建
只需要提供网盘的链接和密码,以及自己登陆百度网盘后得到的两个cookie
可以在云主机上运行


python的版本为3.6.5。
使用selenium进行浏览器模拟。
使用了谷歌的浏览器驱动(Handless Chrome,即不调用GUI的驱动)。
参考的教程
实际上有了上文的解析后,对网盘操作就简单多了,博主使用的是IE的开发者模式来进行网页的解析,在清楚了诸如保存,创建文件的操作对应的链接后,之后就是观察是否有是动态变量参数,或者是cookie
事实上一开始想要检验一下环境有没有搭建错误的话,可以直接把请求的header以及url整个复制下来,使用python自带的urllib库进行测试。


使用的库

import json
import re
import smtplib
import time
import requests

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys

实现流程

通过对浏览器环境的模拟,可以得到百度网盘的的异步调用加载的有用信息,从而实现对资源的自动保存,具体信息的解析上面的博客说的比较详细,这里就不多赘述。
而获得信息后,所要进行的就是通过模拟HTTP请求,通过POST请求将创建文件夹以及保存文件的动作实现
而所需要注意的就是POST的链接的参数,HTTP的header以及要提交的请求正文(以上信息可在浏览器开发者模式下查看),如果链接的参数或者请求正文的内容出错则会返回错误码errno:2,如果header里面的cookie缺失了,并且该网盘链接需要密码,则可能会返回错误码errno:-9,这里附上网友整理的常见错误码


header构建以及初始化

    def init_head(self, bdclnd):
        self.headers = {
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'zh-CN,zh;q=0.8',
            'Connection': 'keep-alive',
            'Content-Length': '161',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            #这里如果是链接需要密码,则需要多加一个叫BDCLND的cookie,不需要密码则不用
            #STOKEN,BDUSS都可以直接用浏览器里面的cookie
            'Cookie': 'BDCLND=%s;BDUSS=%s;STOKEN=%s' % (bdclnd, self.bduss, self.stoken),
            'Host': 'pan.baidu.com',
            'Origin': 'https://pan.baidu.com',
            'Referer': 'https://pan.baidu.com/s/1mjI3AEs',
            #可以直接在浏览器的开发者模式下找自己User-Agent
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
                          ' (KHTML, like Gecko) Chrome/64.0.3282.140 '
                          'Safari/537.36 Edge/17.17134',
            'X-Requested-With': 'XMLHttpRequest',
        }
    def __init__(self, bduss, stoken, bdstoken, password):
        #这里的bdstoken是url的参数,在百度云随便操作看一下就可以了
        self.bdstoken = bdstoken
        self.bduss = bduss
        self.stoken = stoken
        #网盘的密码
        self.password = password
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')
        #这里的--no-sandbox针对的是Linux的云主机,如果不加可能无法启动,至少博主启动不了
        #如果是使用windows,就安装谷歌浏览器,并找到安装路径下的启动程序
        #如果是Linux就有点麻烦,必须经过一些配置
        #两者都需要下载谷歌驱动
        chrome_options.add_argument("--no-sandbox")
        # chrome_options.binary_location = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
        # self.driver = webdriver.Chrome(chrome_options=chrome_options)
        chrome_options.binary_location = '/opt/google/chrome/chrome'
        self.driver = webdriver.Chrome(executable_path='/opt/google/chrome/chromedriver', chrome_options=chrome_options)

驱动的地址,需要翻墙,版本为ChromeDriver 2.39
驱动的地址,不需要翻墙

云主机Linux安装谷歌浏览器的小教程

2018-06-05 23:24:11 cd /etc/yum.repos.d/
2018-06-05 23:24:20 vim google-chrome.repo
2018-06-05 23:36:41 yum -y install google-chrome-stable --nogpgcheck

google-chrome.repo文件的内容

[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl.google.com/linux/linux_signing_key.pub

文件保存所需信息的获取

    def get_file_info(self, url):
        # 使用sleep是因为ajax是异步加载,防止页面没有完全加载
        self.driver.get(url)
        time.sleep(1)
        self.driver.get(url)
        # 输入网盘密码框,这个参数隔一段时间可能会改变,如果出现异常的话可以直接检查元素得到最新的值
        elem = self.driver.find_element_by_id('xfspgN3b')
        # 模拟输入
        elem.send_keys(self.password)
        #模拟回车
        elem.send_keys(Keys.ENTER)
        time.sleep(3)
        # 初始化header,并得到'BDCLND'这个cookie
        self.init_head(self.driver.get_cookie('BDCLND')['value'])

        #元素解析,代码全部来自于他人
        script_list = self.driver.find_elements_by_xpath("//body/script")
        inner_html = script_list[-1].get_attribute("innerHTML")

        pattern = 'yunData.SHARE_ID = "(.*?)"[\s\S]*yunData.SHARE_UK = "(.*?)"[\s\S]*yunData.FILEINFO = (.*?);[\s\S]*'
        # [\s\S]*可以匹配包括换行的所有字符,\s表示空格,\S表示非空格字符
        srch_ob = re.search(pattern, inner_html)

        share_id = srch_ob.group(1)
        share_uk = srch_ob.group(2)

        file_info_jsls = json.loads(srch_ob.group(3))
        path_list_str = u'['
        for file_info in file_info_jsls:
            path_list_str += u'"' + file_info['path'] + u'",'

        path_list_str = path_list_str[:-1]
        path_list_str += u']'

        return share_id, share_uk, path_list_str

文件夹创建以及文件保存

    def transfer(self, share_id, uk, filelist_str, path_t_save):
        #share_id和uk都要通过解析得到, filelist_str为自己一开始设置的保存位置
        #注意,这里由于可以自动创建文件夹,所以保证了文件夹一定存在
        #如果文件夹不存在,直接保存汇报errno:2的错误
        # 通用参数
        ondup = "newcopy"
        async = "1"
        channel = "chunlei"
        clienttype = "0"
        web = "1"
        app_id = "250528"
        #博主使用自己浏览器上的好像没什么影响
        logid = "MTUyODI4ODUxNjk0NjAuODAxMTA1MDc2ODE4Njg0Mw=="
        # 保存文件的链接
        url_trans = "https://pan.baidu.com/share/transfer?shareid=%s" \
                    "&from=%s" \
                    "&ondup=%s" \
                    "&async=%s" \
                    "&bdstoken=%s" \
                    "&channel=%s" \
                    "&clienttype=%s" \
                    "&web=%s" \
                    "&app_id=%s" \
                    "&logid=%s&clienttype=0" % (
                        share_id, uk, ondup, async, self.bdstoken, channel, clienttype, web, app_id, logid)

        #创建文件夹得请求正文
        #注意在浏览器看到得是url编码格式
        create_floder = {
            # 不知道是什么,大部分情况为空
            'block_list': '[]',
            'isdir': '1',
            # 保存的位置,创建文件夹
            'path': path_t_save
        }
        # 创建文件夹的链接
        url_create = 'https://pan.baidu.com/api/create?a=commit' \
                     '&channel=chunlei' \
                     '&web=1' \
                     '&app_id=250528' \
                     '&bdstoken=%s' \
                     '&logid=%s' \
                     '&clienttype=0' % (self.bdstoken, logid)
        response = requests.post(url_create, data=create_floder, headers=self.headers)
        print(response.content)

        # 保存文件的请求正文
        form_data = {
            'filelist': filelist_str,
            'path': path_t_save,
        }
        response = requests.post(url_trans, data=form_data, headers=self.headers)
        print(response.content)

        jsob = json.loads(response.content)

        if "errno" in jsob:
            return jsob["errno"]
        else:
            return None

以上就是python对百度网盘的操作了,具体的代码我找时间上传到GitHub,。,

猜你喜欢

转载自blog.csdn.net/madonghyu/article/details/80602185
今日推荐