def check_login(cookie, token, username): """进行登录验证, 主要是在服务器上验证这个帐户的状态. 如果帐户不存在, 或者帐户异常, 就不需要再进行最后一步的登录操作了. 这一步有可能需要输入验证码. @return 返回errInfo.no, 如果为0, 表示一切正常, 可以登录. """ url = "".join( [ const.PASSPORT_URL, "?logincheck", "&token=", token, "&tpl=mm&apiver=v3", "&tt=", util.timestamp(), "&username="******"&isphone=false", ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: return json.loads(req.data.decode()) else: return None
def list_share(cookie, tokens, path='/', page=1, num=100): '''获取用户已经共享的文件的信息 path - 哪个目录的信息, 默认为根目录. page - 页数, 默认为第一页. num - 一次性获取的共享文件的数量, 默认为100个. ''' url = ''.join([ const.PAN_URL, 'share/record?channel=chunlei&clienttype=0&web=1', '&num=', str(num), '&t=', util.timestamp(), '&page=', str(page), '&dir=', encoder.encode_uri_component(path), '&t=', util.latency(), '&order=tme&desc=1', '&_=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Referer': const.SHARE_REFERER, }) if req: content = req.data return json.loads(content.decode()) else: return None
def refresh_sigin_vcode(cookie, token, vcodetype): """刷新验证码. vcodetype - 在调用check_login()时返回的vcodetype. """ url = "".join( [ const.PASSPORT_BASE, "v2/?reggetcodestr", "&token=", token, "&tpl=netdisk&apiver=v3", "&tt=", util.timestamp(), "&fr=ligin", "&vcodetype=", vcodetype, ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: try: return json.loads(req.data.decode("gb18030")) except ValueError as e: print(e) return None
def cloud_add_link_task(cookie, tokens, source_url, save_path): '''新建离线下载任务. source_url - 可以是http/https/ftp等一般的链接 可以是eMule这样的链接 path - 要保存到哪个目录, 比如 /Music/, 以/开头, 以/结尾的绝对路径. ''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) type_ = '' if source_url.startswith('ed2k'): type_ = '&type=3' if not save_path.endswith('/'): save_path = save_path + '/' data = ''.join([ 'method=add_task&app_id=250528', '&source_url=', encoder.encode_uri_component(source_url), '&save_path=', encoder.encode_uri_component(save_path), '&type=', type_, ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def list_share_path(cookie, tokens, uk, path, share_id, page): '''列举出用户共享的某一个目录中的文件信息 uk - user key path - 共享目录 share_id - 共享文件的ID值 ''' url = ''.join([ const.PAN_URL, 'share/list?channel=chunlei&clienttype=0&web=1&num=100', '&t=', util.timestamp(), '&page=', str(page), '&dir=', encoder.encode_uri_component(path), '&t=', util.latency(), '&shareid=', share_id, '&order=time&desc=1', '&uk=', uk, '&_=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Referer': const.SHARE_REFERER, }) if req: content = req.data return json.loads(content.decode()) else: return None
def get_BAIDUID(): '''获取一个cookie - BAIDUID. 这里, 我们访问百度首页, 返回的response header里面有我们需要的cookie ''' req = net.urlopen(const.BAIDU_URL) return req.headers.get_all('Set-Cookie')
def get_category(cookie, tokens, category, page=1): '''获取一个分类中的所有文件信息, 比如音乐/图片 目前的有分类有: 视频 - 1 音乐 - 2 图片 - 3 文档 - 4 应用 - 5 其它 - 6 BT种子 - 7 ''' timestamp = util.timestamp() url = ''.join([ const.PAN_API_URL, 'categorylist?channel=chunlei&clienttype=0&web=1', '&category=', str(category), '&pri=-1&num=100', '&t=', timestamp, '&page=', str(page), '&order=time&desc=1', '&_=', timestamp, '&bdstoken=', cookie.get('STOKEN').value, ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def get_metas(cookie, tokens, filelist, dlink=True): '''获取多个文件的metadata. filelist - 一个list, 里面是每个文件的绝对路径. 也可以是一个字符串, 只包含一个文件的绝对路径. dlink - 是否包含下载链接, 默认为True, 包含. @return 包含了文件的下载链接dlink, 通过它可以得到最终的下载链接. ''' if isinstance(filelist, str): filelist = [filelist, ] url = ''.join([ const.PAN_API_URL, 'filemetas?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) if dlink: data = ('dlink=1&target=' + encoder.encode_uri_component(json.dumps(filelist))) else: data = ('dlink=0&target=' + encoder.encode_uri_component(json.dumps(filelist))) req = net.urlopen(url, headers={ 'Cookie': cookie.sub_output('BDUSS'), 'Content-type': const.CONTENT_FORM, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def delete_trash(cookie, tokens, fidlist): '''批量将文件从回收站中删除, 这一步不可还原!' fidlist - 待删除的目录/文件的fs_id 列表. 如果有一个文件的fs_id在回收站中不存在, 就会报错, 并返回. ''' url = ''.join([ const.PAN_API_URL, 'recycle/delete?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = 'fidlist=' + encoder.encode_uri_component(json.dumps(fidlist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def list_dir(cookie, tokens, path, page=1, num=100): '''得到一个目录中的所有文件的信息(最多100条记录).''' timestamp = util.timestamp() url = ''.join([ const.PAN_API_URL, 'list?channel=chunlei&clienttype=0&web=1', '&num=', str(num), '&t=', timestamp, '&page=', str(page), '&dir=', encoder.encode_uri_component(path), '&t=', util.latency(), '&order=time&desc=1', '&_=', timestamp, '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ 'Content-type': const.CONTENT_FORM_UTF8, 'Cookie': cookie.sub_output('BAIDUID', 'BDUSS', 'PANWEB', 'cflag'), }) if req: content = req.data return json.loads(content.decode()) else: return None
def list_trash(cookie, tokens, path='/', page=1, num=100): '''获取回收站的信息. path - 目录的绝对路径, 默认是根目录 page - 页码, 默认是第一页 num - 每页有多少个文件, 默认是100个. 回收站里面的文件会被保存10天, 10天后会自动被清空. 回收站里面的文件不占用用户的存储空间. ''' url = ''.join([ const.PAN_API_URL, 'recycle/list?channel=chunlei&clienttype=0&web=1', '&num=', str(num), '&t=', util.timestamp(), '&dir=', encoder.encode_uri_component(path), '&t=', util.latency(), '&order=time&desc=1', '&_=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def restore_trash(cookie, tokens, fidlist): '''从回收站中还原文件/目录. fildlist - 要还原的文件/目录列表, fs_id. ''' url = ''.join([ const.PAN_API_URL, 'recycle/restore?channel=chunlei&clienttype=0&web=1', '&t=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) data = 'fidlist=' + encoder.encode_uri_component(json.dumps(fidlist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def get_share_page(url): '''获取共享页面的文件信息''' req = net.urlopen(url) if req: content = req.data.decode() match = re.findall('applicationConfig,(.+)\]\);', content) share_files = {} if not match: match = re.findall('viewShareData=(.+");FileUtils.spublic', content) if not match: return None list_ = json.loads(json.loads(match[0])) else: list_ = json.loads(json.loads(match[0])) if isinstance(list_, dict): share_files['list'] = [ list_, ] else: share_files['list'] = list_ id_match = re.findall('FileUtils\.share_id="(\d+)"', content) uk_match = re.findall('/share/home\?uk=(\d+)" target=', content) sign_match = re.findall('FileUtils\.share_sign="([^"]+)"', content) if id_match and uk_match and sign_match: share_files['share_id'] = id_match[0] share_files['uk'] = uk_match[0] share_files['sign'] = sign_match[0] return share_files return None
def enable_share(cookie, tokens, fid_list): '''建立新的分享. fid_list - 是一个list, 里面的每一条都是一个文件的fs_id 一次可以分享同一个目录下的多个文件/目录, 它们会会打包为一个分享链接, 这个分享链接还有一个对应的shareid. 我们可以用uk与shareid来在百度网盘里 面定位到这个分享内容. @return - 会返回分享链接和shareid. ''' url = ''.join([ const.PAN_URL, 'share/set?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = encoder.encode_uri('fid_list=' + json.dumps(fid_list) + '&schannel=0&channel_list=[]') req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_query_task(cookie, tokens, task_ids): '''查询离线下载任务的信息, 比如进度, 是否完成下载等. 最好先用cloud_list_task() 来获取当前所有的任务, 然后调用这个函数来获取 某项任务的详细信息. task_ids - 一个list, 里面至少要有一个task_id, task_id 是一个字符串 ''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?method=query_task&app_id=250528', '&bdstoken=', tokens['bdstoken'], '&task_ids=', ','.join(task_ids), '&t=', util.timestamp(), '&channel=chunlei&clienttype=0&web=1', ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def get_bduss(cookie, token, username, password): '''获取最重要的登录cookie, 拿到这个cookie后, 就得到了最终的访问授权. token - 使用get_token()得到的token值. cookie - BAIDUID 这个cookie. username - 用户名 password - 明文密码 @return 最后会返回一个list, 里面包含了登录*.baidu.com需要的授权cookies. ''' url = const.PASSPORT_URL + '?login' data = ''.join([ 'staticpage=http%3A%2F%2Fwww.baidu.com%2Fcache%2Fuser%2Fhtml%2Fv3Jump.html', '&charset=utf-8', '&token=', token, '&tpl=mn&apiver=v3', '&tt=', util.timestamp(), '&codestring=&safeflg=0&u=https%3A%2F%2Fpassport.baidu.com%2F', '&isPhone=false&quick_user=0', #'&loginmerge=true&logintype=basicLogin', '&usernamelogin=1&spligin=rate', '&username='******'&password='******'&verifycode=&mem_pass=on', '&ppui_logintime=', get_ppui_logintime(), '&callback=parent.bd__pcbs__cb', ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM, }, data=data.encode()) return req.headers.get_all('Set-Cookie')
def mkdir(cookie, tokens, path): '''创建一个目录. path 目录名, 绝对路径. @return 返回一个dict, 里面包含了fs_id, ctime等信息. ''' url = ''.join([ const.PAN_API_URL, 'create?a=commit&channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = ''.join([ 'path=', encoder.encode_uri_component(path), '&isdir=1&size=&block_list=%5B%5D&method=post', ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_query_magnetinfo(cookie, tokens, source_url, save_path): '''获取磁链的信息. 在新建磁链任务时, 要先获取这个磁链的信息, 比如里面包含哪些文件, 文件的名 称与大小等. source_url - 磁链的url, 以magent:开头. save_path - 保存到哪个目录 ''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = ''.join([ 'method=query_magnetinfo&app_id=250528', '&source_url=', encoder.encode_uri_component(source_url), '&save_path=', encoder.encode_uri_component(save_path), '&type=4', ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def create_superfile(cookie, path, block_list): '''合并slice_upload()中产生的临时文件 path - 文件在服务器上的绝对路径 block_list - 这些文件分片的MD5列表 返回完整的文件pcs信息. ''' url = ''.join([ const.PCS_URL_C, 'file?method=createsuperfile&app_id=250528', '&path=', encoder.encode_uri_component(path), '&', cookie.sub_output('BDUSS'), ]) param = {'block_list': block_list} data = 'param=' + json.dumps(param) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }, data=data.encode()) if req: return json.loads(req.data.decode()) else: return None
def rapid_upload(cookie, tokens, source_path, path): '''快速上传''' content_length = os.path.getsize(source_path) assert content_length > RAPIDUPLOAD_THRESHOLD, 'file size is not satisfied!' dir_name, file_name = os.path.split(path) content_md5 = hasher.md5(source_path) slice_md5 = hasher.md5(source_path, 0, RAPIDUPLOAD_THRESHOLD) url = ''.join([ const.PCS_URL_C, 'file?method=rapidupload&app_id=250528', '&ondup=newcopy', '&dir=', encoder.encode_uri_component(dir_name), '&filename=', encoder.encode_uri_component(file_name), '&content-length=', str(content_length), '&content-md5=', content_md5, '&slice-md5=', slice_md5, '&path=', encoder.encode_uri_component(path), '&', cookie.sub_output('BDUSS'), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }) if req: return json.loads(req.data.decode()) else: return None
def list_share(cookie, tokens, uk, page=1): '''获取用户已经共享的所有文件的信息 uk - user key page - 页数, 默认为第一页. num - 一次性获取的共享文件的数量, 默认为100个. ''' num = 100 start = 100 * (page - 1) url = ''.join([ const.PAN_URL, 'pcloud/feed/getsharelist?', '&t=', util.timestamp(), '&categor=0&auth_type=1&request_location=share_home', '&start=', str(start), '&limit=', str(num), '&query_uk=', str(uk), '&channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Referer': const.SHARE_REFERER, }) if req: content = req.data return json.loads(content.decode()) else: return None
def copy(cookie, tokens, filelist): '''复制文件/目录到新位置. filelist 是一个list, 里面的每一项都是一个dict, 每个dict都有这几项: path - 文件/目录的当前的绝对路径, 包含文件名 dest - 要复制到的目的路径, 不包含文件名 newname - 文件/目录的新名称; 可以保持与当前名称一致. ''' url = ''.join([ const.PAN_API_URL, 'filemanager?channel=chunlei&clienttype=0&web=1&opera=copy', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def move(cookie, tokens, filelist): '''移动文件/目录到新的位置. filelist 是一个list, 里面包含至少一个dict, 每个dict都有以下几项: path - 文件的当前的绝对路径, 包括文件名. dest - 文件的目标绝对路径, 不包括文件名. newname - 文件的新名称; 可以与保持原来的文件名一致, 也可以给一个新名称. ''' url = ''.join([ const.PAN_API_URL, 'filemanager?channel=chunlei&clienttype=0&web=1&opera=move', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def search(cookie, tokens, key, path='/'): '''搜索全部文件, 根据文件名. key - 搜索的关键词 path - 如果指定目录名的话, 只搜索本目录及其子目录里的文件名. ''' url = ''.join([ const.PAN_API_URL, 'search?channel=chunlei&clienttype=0&web=1', '&dir=', path, '&key=', key, '&recursion', '&timeStamp=', util.latency(), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def list_trash(cookie, tokens, path="/", page=1, num=100): """获取回收站的信息. path - 目录的绝对路径, 默认是根目录 page - 页码, 默认是第一页 num - 每页有多少个文件, 默认是100个. 回收站里面的文件会被保存10天, 10天后会自动被清空. 回收站里面的文件不占用用户的存储空间. """ url = "".join( [ const.PAN_API_URL, "recycle/list?channel=chunlei&clienttype=0&web=1", "&num=", str(num), "&t=", util.timestamp(), "&dir=", encoder.encode_uri_component(path), "&t=", util.latency(), "&order=time&desc=1", "&_=", util.timestamp(), "&bdstoken=", tokens["bdstoken"], ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_query_task(cookie, tokens, task_ids): """查询离线下载任务的信息, 比如进度, 是否完成下载等. 最好先用cloud_list_task() 来获取当前所有的任务, 然后调用这个函数来获取 某项任务的详细信息. task_ids - 一个list, 里面至少要有一个task_id, task_id 是一个字符串 """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl?method=query_task&app_id=250528", "&bdstoken=", tokens["bdstoken"], "&task_ids=", ",".join(task_ids), "&t=", util.timestamp(), "&channel=chunlei&clienttype=0&web=1", ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_query_magnetinfo(cookie, tokens, source_url, save_path): """获取磁链的信息. 在新建磁链任务时, 要先获取这个磁链的信息, 比如里面包含哪些文件, 文件的名 称与大小等. source_url - 磁链的url, 以magent:开头. save_path - 保存到哪个目录 """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1", "&bdstoken=", tokens["bdstoken"], ] ) data = "".join( [ "method=query_magnetinfo&app_id=250528", "&source_url=", encoder.encode_uri_component(source_url), "&save_path=", encoder.encode_uri_component(save_path), "&type=4", ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_list_task(cookie, tokens, start=0): """获取当前离线下载的任务信息 start - 从哪个任务开始, 从0开始计数, 会获取这50条任务信息 """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1", "&bdstoken=", tokens["bdstoken"], "&need_task_info=1&status=255", "&start=", str(start), "&limit=50&method=list_task&app_id=250528", "&t=", util.timestamp(), ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def search(cookie, tokens, key, path="/"): """搜索全部文件, 根据文件名. key - 搜索的关键词 path - 如果指定目录名的话, 只搜索本目录及其子目录里的文件名. """ url = "".join( [ const.PAN_API_URL, "search?channel=chunlei&clienttype=0&web=1", "&dir=", path, "&key=", key, "&recursion", "&timeStamp=", util.latency(), "&bdstoken=", tokens["bdstoken"], ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_query_sinfo(cookie, tokens, source_path): """获取网盘中种子的信息, 比如里面的文件名, 文件大小等. source_path - BT种子的绝对路径. """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1", "&method=query_sinfo&app_id=250528", "&bdstoken=", tokens["bdstoken"], "&source_path=", encoder.encode_uri_component(source_path), "&type=2", "&t=", util.timestamp(), ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def rename(cookie, tokens, filelist): """批量重命名目录/文件. 只能修改文件名, 不能修改它所在的目录. filelist 是一个list, 里面的每一项都是一个dict, 每个dict包含两部分: path - 文件的绝对路径, 包含文件名. newname - 新名称. """ url = "".join( [ const.PAN_API_URL, "filemanager?channel=chunlei&clienttype=0&web=1&opera=rename", "&bdstoken=", tokens["bdstoken"], ] ) data = "filelist=" + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen( url, headers={"Content-type": const.CONTENT_FORM_UTF8, "Cookie": cookie.header_output()}, data=data.encode() ) if req: content = req.data return json.loads(content.decode()) else: return None
def move(cookie, tokens, filelist): """移动文件/目录到新的位置. filelist 是一个list, 里面包含至少一个dict, 每个dict都有以下几项: path - 文件的当前的绝对路径, 包括文件名. dest - 文件的目标绝对路径, 不包括文件名. newname - 文件的新名称; 可以与保持原来的文件名一致, 也可以给一个新名称. """ url = "".join( [ const.PAN_API_URL, "filemanager?channel=chunlei&clienttype=0&web=1&opera=move", "&bdstoken=", tokens["bdstoken"], ] ) data = "filelist=" + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen( url, headers={"Cookie": cookie.header_output(), "Content-type": const.CONTENT_FORM_UTF8}, data=data.encode() ) if req: content = req.data return json.loads(content.decode()) else: return None
def rename(cookie, tokens, filelist): '''批量重命名目录/文件. 只能修改文件名, 不能修改它所在的目录. filelist 是一个list, 里面的每一项都是一个dict, 每个dict包含两部分: path - 文件的绝对路径, 包含文件名. newname - 新名称. ''' url = ''.join([ const.PAN_API_URL, 'filemanager?channel=chunlei&clienttype=0&web=1&opera=rename', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Content-type': const.CONTENT_FORM_UTF8, 'Cookie': cookie.header_output(), }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_delete_task(cookie, tokens, task_id): """删除一个离线下载任务, 不管这个任务是否已完成下载. 同时还会把它从下载列表中删除. """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl", "?bdstoken=", tokens["bdstoken"], "&task_id=", str(task_id), "&method=delete_task&app_id=250528", "&t=", util.timestamp(), "&channel=chunlei&clienttype=0&web=1", ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_cancel_task(cookie, tokens, task_id): """取消离线下载任务. task_id - 之前建立离线下载任务时的task id, 也可以从cloud_list_task()里 获取. """ url = "".join( [ const.PAN_URL, "rest/2.0/services/cloud_dl", "?bdstoken=", tokens["bdstoken"], "&task_id=", str(task_id), "&method=cancel_task&app_id=250528", "&t=", util.timestamp(), "&channel=chunlei&clienttype=0&web=1", ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def copy(cookie, tokens, filelist): """复制文件/目录到新位置. filelist 是一个list, 里面的每一项都是一个dict, 每个dict都有这几项: path - 文件/目录的当前的绝对路径, 包含文件名 dest - 要复制到的目的路径, 不包含文件名 newname - 文件/目录的新名称; 可以保持与当前名称一致. """ url = "".join( [ const.PAN_API_URL, "filemanager?channel=chunlei&clienttype=0&web=1&opera=copy", "&bdstoken=", tokens["bdstoken"], ] ) data = "filelist=" + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen( url, headers={"Cookie": cookie.header_output(), "Content-type": const.CONTENT_FORM_UTF8}, data=data.encode() ) if req: content = req.data return json.loads(content.decode()) else: return None
def get_share_page(url): '''获取共享页面的文件信息''' req = net.urlopen(url) if req: content = req.data.decode() match = re.findall('applicationConfig,(.+)\]\);', content) share_files = {} if not match: match = re.findall('viewShareData=(.+");FileUtils.spublic', content) if not match: return None list_ = json.loads(json.loads(match[0])) else: list_ = json.loads(json.loads(match[0])) if isinstance(list_, dict): share_files['list'] = [list_, ] else: share_files['list'] = list_ id_match = re.findall('FileUtils\.share_id="(\d+)"', content) uk_match = re.findall('/share/home\?uk=(\d+)" target=', content) sign_match = re.findall('FileUtils\.share_sign="([^"]+)"', content) if id_match and uk_match and sign_match: share_files['share_id'] = id_match[0] share_files['uk'] = uk_match[0] share_files['sign'] = sign_match[0] return share_files return None
def list_share(cookie, tokens, uk, page=1): """获取用户已经共享的所有文件的信息 uk - user key page - 页数, 默认为第一页. num - 一次性获取的共享文件的数量, 默认为100个. """ num = 100 start = 100 * (page - 1) url = "".join( [ const.PAN_URL, "pcloud/feed/getsharelist?", "&t=", util.timestamp(), "&categor=0&auth_type=1&request_location=share_home", "&start=", str(start), "&limit=", str(num), "&query_uk=", str(uk), "&channel=chunlei&clienttype=0&web=1", "&bdstoken=", tokens["bdstoken"], ] ) req = net.urlopen(url, headers={"Cookie": cookie.header_output(), "Referer": const.SHARE_REFERER}) if req: content = req.data return json.loads(content.decode()) else: return None
def get_bduss(cookie, token, username, password, verifycode='', codeString=''): '''获取最重要的登录cookie, 拿到这个cookie后, 就得到了最终的访问授权. token - 使用get_token()得到的token值. cookie - BAIDUID 这个cookie. username - 用户名 password - 明文密码 verifycode - 用户根据图片输入的四位验证码, 可以为空 codeString - 获取验证码图片时用到的codeString, 可以为空 @return (status, info). 其中, status表示返回的状态: 0 - 正常, 这里, info里面存放的是auth_cookie -1 - 未知异常 4 - 密码错误 257 - 需要输入验证码, 此时info里面存放着(vcodetype, codeString)) ''' url = const.PASSPORT_URL + '?login' data = ''.join([ 'staticpage=http%3A%2F%2Fwww.baidu.com%2Fcache%2Fuser%2Fhtml%2Fv3Jump.html', '&charset=utf-8', '&token=', token, '&tpl=mn&apiver=v3', '&tt=', util.timestamp(), '&codestring=', codeString, '&safeflg=0&u=https%3A%2F%2Fpassport.baidu.com%2F', '&isPhone=false&quick_user=0', '&loginmerge=true&logintype=basicLogin&logLoginType=pc_loginBasic', '&username='******'&password='******'&verifycode=', verifycode, '&mem_pass=on', '&ppui_logintime=', get_ppui_logintime(), '&callback=parent.bd__pcbs__cb', ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM, 'Accept': const.ACCEPT_HTML, }, data=data.encode()) if req: auth_cookie = req.headers.get_all('Set-Cookie') if auth_cookie: return (0, auth_cookie) resp_content= req.data.decode() match = re.findall('"(err_no[^"]+)"', resp_content) if len(match) != 1: return (-1, None) query = dict(urllib.parse.parse_qsl(match[0])) err_no = int(query.get('err_no', '-1')) if err_no != 257: return (err_no, None) vcodetype = query.get('vcodetype', '') codeString = query.get('codeString', '') if vcodetype and codeString: return (257, (vcodetype, codeString)) return (-1, None) else: return (-1, None)
def get_bdstoken(cookie): '''从/disk/home页面获取bdstoken等token信息 这些token对于之后的请求非常重要. ''' url = 'http://pan.baidu.com/disk/home' req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) return parse_bdstoken(req.data.decode())
def get_quota(cookie, tokens): """获取当前的存储空间的容量信息.""" url = "".join([const.PAN_API_URL, "quota?channel=chunlei&clienttype=0&web=1", "&t=", util.timestamp()]) req = net.urlopen(url, headers={"Cookie": cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def get_user_uk(cookie, tokens): '''获取用户的uk''' url = 'http://yun.baidu.com' req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data.decode() match = re.findall('/share/home\?uk=(\d+)" target=', content) if len(match) == 1: return match[0] return None
def cloud_add_bt_task(cookie, tokens, source_url, save_path, selected_idx, file_sha1='', vcode='', vcode_input=''): '''新建一个BT类的离线下载任务, 包括magent磁链. source_path - BT种子所在的绝对路径 save_path - 下载的文件要存放到的目录 selected_idx - BT种子中, 包含若干个文件, 这里, 来指定要下载哪些文件, 从1开始计数. file_sha1 - BT种子的sha1值, 如果是magent的话, 这个sha1值可以为空 vcode - 验证码的vcode vcode_input - 用户输入的四位验证码 ''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) type_ = '2' url_type = 'source_path' if source_url.startswith('magnet:'): type_ = '4' url_type = 'source_url' if not save_path.endswith('/'): save_path = save_path + '/' data = [ 'method=add_task&app_id=250528', '&file_sha1=', file_sha1, '&save_path=', encoder.encode_uri_component(save_path), '&selected_idx=', ','.join(str(i) for i in selected_idx), '&task_from=1', '&t=', util.timestamp(), '&', url_type, '=', encoder.encode_uri_component(source_url), '&type=', type_ ] if vcode: data.append('&input=') data.append(vcode_input) data.append('&vcode=') data.append(vcode) data = ''.join(data) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def get_bdstoken(cookie): '''从/disk/home页面获取bdstoken等token信息 这些token对于之后的请求非常重要. ''' url = 'http://pan.baidu.com/disk/home' req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: return parse_bdstoken(req.data.decode()) else: return None
def get_wap_passport(): '''WAP登录. 返回cookie和登录form''' url = 'http://wappass.baidu.com/passport' req = net.urlopen(url) if req: return (req.headers.get_all('Set-Cookie'), parse_wap_passport(req.data.decode())) else: return None, None
def get_bdstoken(cookie): '''从/disk/home页面获取bdstoken等token信息 这些token对于之后的请求非常重要. ''' url = const.PAN_REFERER req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: return parse_bdstoken(req.data.decode()) else: return None
def get_wap_signin_vcode(cookie, codeString): '''获取wap登录时的验证码''' url = 'http://wappass.baidu.com/cgi-bin/genimage?' + codeString req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Referer': 'http://wappass.badu.com', }) if req: return req.data else: return None
def get_quota(cookie, tokens): '''获取当前的存储空间的容量信息.''' url = ''.join([ const.PAN_API_URL, 'quota?channel=chunlei&clienttype=0&web=1', '&t=', util.timestamp(), ]) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_clear_task(cookie, tokens): '''清空离线下载的历史(已经完成或者取消的).''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?method=clear_task&app_id=250528', '&channel=chunlei&clienttype=0&web=1', '&t=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: content = req.data return json.loads(content.decode()) else: return None
def cloud_add_link_task(cookie, tokens, source_url, save_path, vcode='', vcode_input=''): '''新建离线下载任务. source_url - 可以是http/https/ftp等一般的链接 可以是eMule这样的链接 path - 要保存到哪个目录, 比如 /Music/, 以/开头, 以/结尾的绝对路径. ''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', '&bdstoken=', tokens['bdstoken'], ]) type_ = '' if source_url.startswith('ed2k'): type_ = '&type=3' if not save_path.endswith('/'): save_path = save_path + '/' data = [ 'method=add_task&app_id=250528', '&source_url=', encoder.encode_uri_component(source_url), '&save_path=', encoder.encode_uri_component(save_path), '&type=', type_, ] if vcode: data.append('&input=') data.append(vcode_input) data.append('&vcode=') data.append(vcode) data = ''.join(data) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None
def get_signin_vcode(cookie, codeString): '''获取登录时的验证码图片. codeString - 调用check_login()时返回的codeString. ''' url = ''.join([ const.PASSPORT_BASE, 'cgi-bin/genimage?', codeString, ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: return req.data else: return None