Skip to content

Instantly share code, notes, and snippets.

@bytemain
Created February 5, 2020 09:38
Show Gist options
  • Save bytemain/6dd5b5a0abd9ddfb4980e78ff6ce3282 to your computer and use it in GitHub Desktop.
Save bytemain/6dd5b5a0abd9ddfb4980e78ff6ce3282 to your computer and use it in GitHub Desktop.
Some Python Scripts
from base64 import b64decode
from contextlib import closing
from json import loads
from random import random
import requests
# pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
DETAIL_API = 'https://bridge.51zhy.cn/transfer/Content/Detail?'
AUTHORIZE_API = 'https://bridge.51zhy.cn/transfer/content/authorize'
DEVICE_KEY = b'3uKpxtFAoOeqQQ0S'
class ProgressBar():
def __init__(self,
title,
count=0.0,
run_status=None,
fin_status=None,
total=100.0,
unit='',
sep='/',
chunk_size=1.0):
super(ProgressBar, self).__init__()
self.info = "【{}】{} {:.2f}% {:.2f} {} {} {:.2f} {}"
self.title = title
self.total = total
self.count = count
self.chunk_size = chunk_size
self.status = run_status or ""
self.fin_status = fin_status or " " * len(self.status)
self.unit = unit
self.seq = sep
def __get_info(self):
# 【名称】状态 进度 单位 分割线 总数 单位
_info = self.info.format(self.title, self.status,
(self.count / self.total) * 100,
self.count / self.chunk_size, self.unit,
self.seq, self.total / self.chunk_size,
self.unit)
return _info
def refresh(self, count=1, status=None):
self.count += count
self.status = status or self.status
end_str = "\r"
if self.count >= self.total:
end_str = '\n'
self.status = status or self.fin_status
print(self.__get_info(), end=end_str)
def do_download(url, file_name):
all_data = b""
with closing(requests.get(url, stream=True)) as response:
chunk_size = 1024 # 单次请求最大值
content_size = int(response.headers['content-length']) # 内容体总大小
progress = ProgressBar(file_name,
total=content_size,
unit="KB",
chunk_size=chunk_size,
run_status="正在下载",
fin_status="下载完成")
for data in response.iter_content(chunk_size=chunk_size):
all_data = all_data + data
progress.refresh(count=len(data))
return all_data
def get_book_aes_key(book_key):
r = AES.new(DEVICE_KEY, mode=AES.MODE_ECB).decrypt(b64decode(book_key))
return unpad(r, 16)
def decrypt_book(book, key):
r = AES.new(key, mode=AES.MODE_ECB).decrypt(book)
return unpad(r, 16)
book_id_list = [
"19572574", "64748065", "614789", "60692970", "59724259", "63275184",
"64584723"
]
for idx, book_id in enumerate(book_id_list):
print('idx, book_id: ', idx + 1, book_id)
params = {
'AccessToken': 'null',
'DeviceToken': 'ebookF32BE444AF96C3BB0E71BF02D648DD9C',
'ApiName': '/Content/Detail',
'BridgePlatformName': 'phei_yd_web',
'random': str(random()),
'AppId': '3',
'id': book_id
}
details_json = requests.get(DETAIL_API, params=params)
details = loads(details_json.text)
token = details['Data']['ExtendData']['AuthorizeToken']
book_name = details['Data']['Title']
params = {
'IsOnline': 'true',
'AccessToken': 'null',
'DeviceToken': 'ebookF32BE444AF96C3BB0E71BF02D648DD9C',
'ApiName': 'content/authorize',
'BridgePlatformName': 'phei_yd_web',
'random': str(random()),
'AppId': '3',
'id': book_id,
'authorizeToken': token
}
authorize_json = requests.post(AUTHORIZE_API, data=params)
authorize = loads(authorize_json.text)
book_key = authorize['Data']['Key']
book_url = authorize['Data']['Url']
book_aes_key = get_book_aes_key(book_key)
print("book_url", book_url)
print("book_key", book_key)
book = do_download(book_url, book_name)
decrypted_book = decrypt_book(book, book_aes_key)
with open(book_name + ".pdf", 'wb') as f:
f.write(decrypted_book)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment