Imjunjie

蜻蜓雨荷


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

机器学习常见处理方法

发表于 2019-04-24
本文字数: 1.5k | 阅读时长 ≈ 1 分钟

img_size = mnist.train.images[0].shape[0]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
import tensorflow as tf
import pickle
import matplotlib.pyplot as plt

#%matplotlib inline

print("TensorFlow Version: {}".format(tf.__version__))

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('./MNIST_data/')

i = 10
img = mnist.train.images[i]
plt.imshow(img.reshape((28, 28)), cmap='Greys_r')
print("Label: {}".format(mnist.train.labels[i]))
img_size = mnist.train.images[10].shape[0]
print(img_size)
print(img.shape)

执行上述语句返回的结果为:
Label: 0
784
(784,)

hidden1 = tf.layers.dense(noise_img, n_units)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def get_generator(noise_img, n_units, out_dim, reuse=False, alpha=0.01):
"""
生成器

noise_img: 生成器的输入
n_units: 隐层单元个数
out_dim: 生成器输出tensor的size,这里应该为32*32=784
alpha: leaky ReLU系数
"""
with tf.variable_scope("generator", reuse=reuse):
# hidden layer
hidden1 = tf.layers.dense(noise_img, n_units)
# leaky ReLU
hidden1 = tf.maximum(alpha * hidden1, hidden1)
# dropout
hidden1 = tf.layers.dropout(hidden1, rate=0.2)

# logits & outputs
logits = tf.layers.dense(hidden1, out_dim)
outputs = tf.tanh(logits)

return logits, outputs

上述代码中的”hidden1 = tf.layers.dense(noise_img, n_units)“
其中:
 noise_img-表示输入层的单元个数,这里使用了占位符表示,但要表明单元大小,个数为None
 n_units-表示第一个隐藏层中神经元个数,
这里的函数,表示是全连接,将输入层的神经元全部与第一个隐藏层的神经元,进行全连接。

------------------------ The End ------------------------

Python 批量修改文件名

发表于 2019-04-22 | 更新于 2019-04-23 | 分类于 机器学习 , 数据集处理
本文字数: 960 | 阅读时长 ≈ 1 分钟

Python 批量修改文件名

原文: Python3 OS 文件/目录方法
批量修改文件名
python 对文件进行批量改名用到的是 os 模块中的 listdir 方法和 rename 方法。

  • os.listdir(dir) : 获取指定目录下的所有子目录和文件名
  • os.rename(原文件名,新文件名): 对文件或目录改名

把混乱的文件名改成有序的文件名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
path=input('请输入文件路径(结尾加上/):')

#获取该目录下所有文件,存入列表中
f=os.listdir(path)

n=0
for i in f:

#设置旧文件名(就是路径+文件名)
oldname=path+f[n]

#设置新文件名
newname=path+'a'+str(n+1)+'.JPG'

#用os模块中的rename方法对文件改名
os.rename(oldname,newname)
print(oldname,'======>',newname)

n+=1

img1-1.png
img1-2.png

参考地址

Python 批量修改文件名
Python endswith()方法

搜索内容:img_rgb = img_bgr[…, ::-1]
opencv-python几何变换
Python中cv2库和matplotlib库色彩空间排布不一致
Python cv2.COLOR_BGR2RGB() Examples
opencv-python的格式转换 RGB与BGR互转
[opencv-python的格式转换 RGB与BGR互转]

tensorflow 加载部分变量
变量:创建、初始化、保存和加载
tensorflow 恢复部分参数、加载指定参数
TensorFlow学习笔记(9):模型存储与加载北京大学 软件工程博士在读
tensorflow 加载部分变量的实例讲解
TensorFlow中对训练后的神经网络参数(权重、偏置)提取
Keras 中构建神经网络的 5 个步骤
08-保存和载入模型,使用Google的图像识别网络inception-v3进行图像识别.md

TensorFlow-变量保存和恢复

------------------------ The End ------------------------

eclipse作为Python的开发工具

发表于 2019-04-21 | 更新于 2019-05-21 | 分类于 Machine Learning , Eclipse
本文字数: 3.1k | 阅读时长 ≈ 3 分钟

简介

Eclipse是一款基于Java的可扩展开发平台。其官方下载中包括J2EE方向版本、Java方向版本、C/C++方向版本、移动应用方向版本等诸多版本。除此之外,Eclipse还可以通过安装插件的方式进行诸如Python、Android、PHP等语言的开发。

其中PyDev是一个功能强大的 Eclipse插件,使用户可用 Eclipse 来进行 Python 应用程序的开发和调试。PyDev 插件的出现方便了众多的 Python 开发人员,它提供了一些很好的功能,如:语法错误提示、源代码编辑助手、Quick Outline、Globals Browser、Hierarchy View、运行和调试等等。

本文将介绍eclipse的pydev插件的安装与配置。

myeclipse和eclipse的区别

myeclipse与eclipse的共同点:都是用来开发java项目,且软件用法几乎完全相同
myeclipse与eclipse的区别:

  • 第一点:软件图标
  • 第二点:myeclipse是收费软件,里面既可以开发java又可以开发web项目,eclipse只可以开发java项目,如果想开发web项目,还需要额外添加eclipse web插件(当然可以去开源网站或公司官网下载,这是免费的)
  • 第三点:高手一般都用eclipse,主要是因为eclipse比myeclipse稳定,新手用myeclipse比较好上手。

安装准备

配置Python的系统环境变量PATH=D:\Python34(即python的安装目录)
显示python的版本,用来测试python的环境是否配置好 , 命令:

1
Python

安装python的第三方库

1
2
pip install pandas
pip install PyMySql


用来测试python运行时会不会出错,没报错就说明程序可以运行。

安装教程

1. 首先下载jdk,安装,配置环境变量;
2. 再下载eclipse,配置编译器;
3. 写一个helloworld;(具体过程请专门看教程。)

这样,基础环境就搭好了。下面安装PyDev,有两种安装方法,分别介绍之:

简易在线安装

这是官网安装,下载安装很方便,但可能由于网络原因用时过长或失败。

官网安装过程如下:

安装Pydev

  • Help - Install New Software

    (1)点击 - Add
    (2)输入 Name 和 Location,Name 随意,Location 为 http://pydev.org/updates ; 点击OK
    把【connect all update sites during install to find required software】的勾选去掉,否则在安装新插件时会联网寻找所有可能的更新站点搜索,导致安装时间不可预估,并可能导致安装失败。

确定后可以看到一个Pending过程,然后得到如下图所示的插件:

勾选后,点击Next进行安装。

不过,由于网络的原因,这种方法安装PyDev极有可能失败,提示网络连接错误等。需要vpn。

eclipse和python关联:

eclipse菜单 -> Windows ->Preferences -> PyDev-> Interpreters - Python Interpreter.
点击New按钮,选择python.exe的路径(第1步安装Python的路径),打开后显示出一个包含很多复选框的窗口,点OK结束!

离线安装

通常官网安装并不如人意,你懂的… 推荐离线安装,步骤如下

  1. 下载PyDev离线安装包,我的云盘地址: http://pan.baidu.com/s/1pJ1HQKb
  2. 将解压后的features和plugins两个文件夹分别拷贝到Eclipse安装目录下的features和plugins目录中

PyDev的配置

不论官网安装还是离线安装,都需要配置PyDev,步骤如下

  1. 启动Eclipse,打开window->Preferences

  2. 选择Interpreter-Python,然后选择New

  3. 点击【New】,添加一个系统里已有的Python解释器的位置。确定后会经过短暂的处理,得到它的Libraries、Buildins等。
    (我写的地址是提前安装好的annaconda。)

  4. 最后,单击Reference界面下的 OK ; 等待后即可在Eclipse中写Python了。 

例子 实战

前面就已经配置好了Python的开发环境,下面新建一个项目,来测试一下,确实可以运行。

点击【File】-【New】-【Other】,找到【PyDev】,选择【PyDev Project】,点击Next。取一个项目名称,比如helloPython,如下图所示:

点击【Finish】,完成项目创建。然后你会进入PyDev视图,进行Python开发。

右键项目的src目录,选择【New】-【PyDev Package】,创建一个Python包,此处也命名为helloPython。

再右键该package,【New】-【PyDev Module】(python的module 就是java的calss),此处也命名为helloPython。 (pydev提供了一些模板,这边暂选 Empty)

双击打开 helloPython .py,添加如下代码。

1
print'hello python!'

右键项目,选择【Run As】-【Python Run】,或Ctrl+F11运行项目。

此时,可以在下方的console窗口,看到项目的运行结果。

PyDev的注释快捷键

个人认为,PyDev是很好用的python编辑器。使用起来的确得心应手,建议初学者多尝试用用。

下面从网上整理了一些PyDev的快捷键,和大家分享分享:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ctrl+3 行注释

Ctr+\ 去行注释
Ctrl+Shift+3 去行注释

Ctrl+4 块注释
Ctrl+5 去块注释

Ctrl+9 折叠全部
Ctrl+0 展开全部

Ctrl+- 折叠
Ctrl+= 展开

Ctrl+Shift+Up 上一函数
Ctrl+Shift+Down 下一函数

Ctrl+Shift+O 整理导入顺序

tensorflow中所安装的模块

  1. Python安装cv2模块

    1
    pip install opencv-python
  2. 安装 captcha

    1
    pip install captcha

常见问题

PEP 263 — Defining Python Source Code Encodings

参考文献

  • Eclipse环境安装Python插件PyDev
  • Eclipse+PyDev的详细的安装和使用过程
  • 利用Eclipse + PyDev 开发第一个Python程序
  • 【Eclipse+PyDev】字体、颜色和背景的个性化设置

其他网址

使用captcha模块生成图形验证码
python使用captcha模块生成图形验证码

【简书】1.CNN图片单标签分类(基于TensorFlow实现基础VGG16网络)
【简书】2.CNN图片多标签分类(基于TensorFlow实现验证码识别OCR)
【CSDN】2.CNN图片多标签分类(基于TensorFlow实现验证码识别OCR)

Tensorflow制作并用CNN训练自己的数据集

------------------------ The End ------------------------

TensorFlow学习知识点总结

发表于 2019-04-19 | 更新于 2019-04-20 | 分类于 机器学习 , TensorFlow
本文字数: 11k | 阅读时长 ≈ 10 分钟

tf.equal()函数

tensorflow 中tf.equal()用法:

1
tf.equal(A, B,name=None)

  • 对于单个变量,如果A==B,则返回true,否则返回false;
  • 对于数组,会迭代的比较A[i]和B[i],对应相等的则返回true,否则返回false
      是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,否则返回False,返回的值的矩阵维度和A是一样的
      equal,相等的意思。顾名思义,就是判断,A, B 是不是相等,它的判断方法不是整体判断,
      而是逐个元素进行判断,如果相等就是True,不相等,就是False。
      由于是逐个元素判断,所以A,B 的维度要一致。
    1
    2
    3
    4
    5
    6
    7
    8
    import tensorflow as tf
    import numpy as np

    A = [[1,3,4,5,6]]
    B = [[1,3,4,3,2]]

    with tf.Session() as sess:
    print(sess.run(tf.equal(A, B)))

输出:
  [[ True True True False False]]

tf.cast()函数

tf.cast(a, dtype=tf.float32)
将a的类型转换成tf.float32

1
2
3
4
5
6
7
8
import tensorflow as tf
a = [1, 2, 3]
b = [1, 5, 3]
sess = tf.Session()
with sess.as_default():
acc = sess.run(tf.equal(a, b))
print(acc)  
print(sess.run(tf.reduce_mean(tf.cast(acc, dtype=tf.float32))))

运行结果如下图所示:

1
2
[True, False, True]
0.6666667

代码解释:
假设a是输入的y_hat, b是预测的y
  tf.equal(a, b)会比较每一个y和y_hat 是否相等
  tf.cast(acc, dtype=tf.float32)将比较的结果转换成tf.float32类型
  tf.reduce_mean()求所有tf.float32类型结果的均值

tf.argmax()函数

tf.argmax(vector, 1)

  返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值,如果是一个矩阵,那就返回一个向量,这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号。

1
2
3
4
5
6
7
8
9
import tensorflow as tf
import numpy as np

A = [[1,3,4,5,6]]
B = [[1,3,4], [2,4,1]]

with tf.Session() as sess:
print(sess.run(tf.argmax(A, 1)))
print(sess.run(tf.argmax(B, 1)))

运行结果:

1
2
3
(tf14) zhangkf@Ubuntu2:~/lenet5$ python one.py 
[4]
[2 1]

tf.equal()

tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,否则返回False,返回的值的矩阵维度和A是一样的

1
2
3
4
5
6
7
8
import tensorflow as tf
import numpy as np

A = [[1,3,4,5,6]]
B = [[1,3,4,3,2]]

with tf.Session() as sess:
print(sess.run(tf.equal(A, B)))

运行结果:

1
2
(tf14) zhangkf@Ubuntu2:~/lenet5$ python one.py 
[[ True True True False False]]

1
2
3
4
5
6
7
8
import tensorflow as tf
import numpy as np

A = [[1,3,4,5,6],[1,2,3,4,5]]
B = [[1,3,4,3,2],[2,2,3,4,3]]

with tf.Session() as sess:
print(sess.run(tf.equal(A, B)))

运行结果:

1
2
3
(tf14) zhangkf@Ubuntu2:~/lenet5$ python one.py 
[[ True True True False False]
[False True True True False]]

二者结合起来

在测试模型的准确率的时候,通常二者结合在一起。

1
2
correct_prediction=tf.equal(tf.getmax(y,1),tf.getmax(y_,1))
accuracy=tf.reduce_mean(tf.cast(corrcet_prediction,tf.float32))#求平均获取准确率

tf.argmax 与 tf.arg_max

tf.argmax 与 tf.arg_max 用法相同,下面介绍 tf.argmax 用法

tf.argmax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def argmax(input,
axis=None,
name=None,
dimension=None,
output_type=dtypes.int64)
numpy.argmax(a, axis=None, out=None)
返回沿轴axis最大值的索引。

Parameters:
input: array_like,数组
axis : int, 可选,默认情况下,索引的是平铺的数组,否则沿指定的轴。
out : array, 可选 如果提供,结果以合适的形状和类型被插入到此数组中。

Returns:
index_array : ndarray of ints
索引数组。它具有与a.shape相同的形状,其中axis被移除。

tf.argmax() 与 numpy.argmax() 方法的用法是一致的

axis = 0 的时候返回每一列最大值的位置索引
axis = 1 的时候返回每一行最大值的位置索引
axis = 2、3、4 …,即为多维张量时,同理推断

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> a = np.arange(6).reshape(2,3)
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> np.argmax(a)
5
>>> np.argmax(a, axis=0) #0代表列
array([1, 1, 1])
>>> np.argmax(a, axis=1) #1代表行
array([2, 2])
>>>
>>> b = np.arange(6)
>>> b[1] = 5
>>> b
array([0, 5, 2, 3, 4, 5])
>>> np.argmax(b) #只返回第一次出现的最大值的索引
1

tf.arg_max()

  The following is the source code of argmax
  (from https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/math_ops.py).

1
2
3
4
5
6
7
8
9
10
# pylint: disable=redefined-builtin
# TODO(aselle): deprecate arg_max
def argmax(input, axis=None, name=None, dimension=None):
if dimension is not None:
if axis is not None:
raise ValueError("Cannot specify both 'axis' and 'dimension'")
axis = dimension
elif axis is None:
axis = 0
return gen_math_ops.arg_max(input, axis, name)

  As you can see, argmax is using arg_max inside. Also from the code, I recommend using argmax because arg_max could be deprecated soon.

Python获取文件夹下的文件和子文件夹
笔者小白在写代码的时候遇到的这样的问题,就是说需要根据文件夹的路径获取该文件夹下面的所有的文件和子文件夹。这里就介绍python的os模块中的两个函数:os.walk() 、os.listdir()。

os.walk()

该函数的原型是:

1
os.walk(top, topdown=Ture, onerror=None, followlinks=False)

该函数没有返回值。

1
2
3
4
5
参数
1. top -- 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名】。
2. topdown --可选,为True或者没有指定, 一个目录的的3-元组将比它的任何子文件夹的3-元组先产生 (目录自上而下)。如果topdown为 False, 一个目录的3-元组将比它的任何子文件夹的3-元组后产生 (目录自下而上)。
3. onerror -- 可选,是一个函数; 它调用时有一个参数, 一个OSError实例。报告这错误后,继续walk,或者抛出exception终止walk。
4. followlinks -- 设置为 true,则通过软链接访问目录。

函数执行之后得到一个三元tupple(dirpath, dirnames, filenams。

  • dirpath:string,是当前目录的路径;
  • dirnames:list, 是当前路径下所有的子文件夹名字;
  • filenames:list, 是当前路径下所有的非目录子文件的名字。
    要获取完整的路径,dirnames和filenames是不包含路径信息的,可以使用
    1
    os.path.join(dirpath, dirnames)

获得文件的完整路径。
代码示例:

1
2
3
4
5
6
7
8
9
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print(os.path.join(root, name))

当需要特定类型的文件时,代码如下:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-   

import os

def file_name(file_dir):
L=[]
for dirpath, dirnames, filenames in os.walk(file_dir):
for file in filenames :
if os.path.splitext(file)[1] == '.jpg':
L.append(os.path.join(dirpath, file))
return L

其中os.path.splitext()函数将路径拆分为文件名+扩展名,例如os.path.splitext(“E:/lena.jpg”)将得到”E:/lena“+”.jpg”。

os.listdir()

os.listdir()函数返回指定路径下的文件和文件夹列表。
代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, sys

# 打开文件
path = "/var/www/html/"
dirs = os.listdir( path )

# 输出所有文件和文件夹
for file in dirs:
print file

python 遍历文件夹及子文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os

def EnumPathFiles(path, callback):
if not os.path.isdir(path):
print('Error:"',path,'" is not a directory or does not exist.')
return
list_dirs = os.walk(path)

for root, dirs, files in list_dirs:
for d in dirs:
EnumPathFiles(os.path.join(root, d), callback)
for f in files:
callback(root, f)

def callbakc1(path, filename):
print(path+'\\'+filename)

if __name__ == '__main__':
EnumPathFiles(r'D:\Projects\python', callbakc1)

python 遍历目录(包括子目录)下所有文件

1
2
3
4
5
6
7
8
9
10
11
def list_all_files(rootdir):
import os
_files = []
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
for i in range(0,len(list)):
path = os.path.join(rootdir,list[i])
if os.path.isdir(path):
_files.extend(list_all_files(path))
if os.path.isfile(path):
_files.append(path)
return _files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
_fs = list_all_files('./资料')
#将第一阶段的文件遍历出来
_k = filter(lambda x:re.compile(r'stage2.txt').search(x),_fs)
```

python 便利文件夹,返回所有文件夹及其子文件夹
``` python
# -*- coding: utf-8 -*-
# File Name:aa.py
# Author: biolxy
# E-mail:biolxy@aliyun.com
# Created Time:Wed 14 Mar 2018 07:06:03 PM PDT
# python getDir.py /home/user/soft 返回/home/user/soft 下所有文件夹及子文件夹名字
import os
import re
import sys

fistr_dir = os.path.abspath(sys.argv[1])
#print("fistr_dir is:\t{}".format(fistr_dir))
def get_all_dir_from_dir(dir):
# 遍历文件夹,输出文件夹及子文件夹
if os.path.exists(dir):
path_dir = os.path.abspath(dir)
for i in os.listdir(path_dir):
path_i = os.path.join(path_dir, i)
if os.path.isdir(path_i):
print(path_i)
get_all_dir_from_dir(path_i)

get_all_dir_from_dir(fistr_dir)
1
python getDir.py /home/user/soft

注意,如果你没有改文件夹的访问权限,改脚本无法显示该文件夹

来源:
从网上下载了一个听书课程,里边是按照时间顺序放在文件夹中,一级目录嵌套一级目录,具体的mp3文件放在三级目录中,通过编写py函数,实现对目录中文件的遍历并拷贝出指定的文件,此处是mp3文件。

编程思路:
人都是惰性了,刚想到这个问题,第一时间是简单的一层一层的遍历,但是问题是不知道多少层,同时希望程序有一定的健壮性。就想到了递归思想。

具体编程实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
import shutil

file = "D:/BaiduNetdiskDownload/2017-10"
todir = "C:/mp3File"

def searchMp3(path):
for item in os.listdir(path):
subFile = path+"/"+item
if os.path.isdir(subFile):
searchMp3(subFile)
else:
if os.path.splitext(subFile)[1] ==".mp3":
shutil.copy(subFile ,todir)
if __name__ == '__main__':
searchMp3(file)

假设FILE文件夹中有三个文件夹分别是file1,file2。file1中有文件夹sf1和sf2.file2中有sf3和sf4。sf1-4中分别各有一个MP3文件,分别是m1.mp3—-m4.mp3。

path是FILE路径。开始循环:

subFile = path/file1 因为subFile也是文件,此时把 subFile作为path传递给searchFile函数,记住,此时第一次循环还没有结束。此时path路径下面也有两个子文件,此时,subFile = path/file1/sf1。当然sf1也是文件,把此时的subFile当做参数传给searchMp3函数,记住,此时path/file下面还没有遍历完成。把path/file1/sf1当做path,此时,文件中有一个m1.mp3文件。不是文件夹,执行else语句,判断文件后缀是mp3则移动都指定目录。此时开始执行subFile = path/file1/sf2。同样的执行else语句。此时开始执行 subFile = path/file2同样的遍历过程。最后把所有的指定文件都遍历出来。如果还不理解,可以自己画图,更好的理解整个过程。

tf.one_hot()

tensorflow中tf.one_hot()函数的作用是将一个值化为一个概率分布的向量,一般用于分类问题。(参考地址)
具体用法以及作用见以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import tensorflow as tf

SIZE=6
CLASS=8
label1=tf.constant([0,1,2,3,4,5,6,7])
sess1=tf.Session()
print('label1:',sess1.run(label1))
b = tf.one_hot(label1,CLASS,1,0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(b)
print('after one_hot',sess.run(b))

最后的输出为:

1
2
3
4
5
6
7
8
9
10
11
label1: [0 1 2 3 4 5 6 7]
after one_hot:

 [[1 0 0 0 0 0 0 0]
 [0 1 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0]
 [0 0 0 1 0 0 0 0]
 [0 0 0 0 1 0 0 0]
 [0 0 0 0 0 1 0 0]
 [0 0 0 0 0 0 1 0]
 [0 0 0 0 0 0 0 1]]

tf.one_hot()使用
(参考地址)tf.one_hot在看conditionGAN的时候注意到label的输入要把它转换成one-hot形式,再与噪声z进行tf.concat输入,之前看的时候忽略了,现在再看才算明白为什么。

1
2
3
4
5
6
7
8
9
tf.one_hot(
indices,#输入,这里是一维的
depth,# one hot dimension.
on_value=None,#output 默认1
off_value=None,#output 默认0
axis=None,#根据我的实验,默认为1
dtype=None,
name=None
)

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import tensorflow as tf
import numpy as np
z=np.random.randint(0,10,size=[10])
y=tf.one_hot(z,10,on_value=1,off_value=None,axis=0)
with tf.Session()as sess:
print(z)
print(sess.run(y))


[5 7 7 0 5 5 2 0 0 0]
[[0 0 0 1 0 0 0 1 1 1]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 1 1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
z=np.random.randint(0,10,size=[10])
y=tf.one_hot(z,10,on_value=1,off_value=None)
y1=tf.one_hot(z,10,on_value=1,off_value=None,axis=1)
with tf.Session()as sess:
print(z)
print(sess.run(y))
print("axis=1按行排", sess.run(y1))

[6 3 4 9 6 5 5 1 2 1]
[[0 0 0 0 0 0 1 0 0 0]
[0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]]
axis=1按行排 [[0 0 0 0 0 0 1 0 0 0]
[0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]]

感觉实际用的时候可以不传入axis值。可以看到经过one-hot的处理,输入的维度变成了10×depth,值也变成了0和1.

下面说在condition GAN中要输入标签信息y,怎样处理的。
y是mnist的标签值,0和10之间的整数,尺寸为[BATCH],经过one-hot处理后维度变成了[BATCH,10]值也是0和1,此时再与噪声z按列(axis=1)连接,变成条件GAN的输入。因此one-hot操作是必须的,这个处理在infoGAN中将z,categorical latent code、continuous latent code连接在一起输入也要用到。

1
2
3
y = tf.one_hot(y, 10, name='label_onehot')
z = tf.random_uniform([BATCH, 100], -1, 1, name='z_train')
tf.concat([z, y], 1)

【参考3】tensorflow中将label索引转换成one-hot形式

1
2
3
4
5
6
7
8
import tensorflow as tf
index=[0,1,2,3]
one_hot=tf.one_hot(index,5)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

print(sess.run(one_hot))

1
2
3
4
5
[[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]
]
------------------------ The End ------------------------

基于Python的校园网自动登录

发表于 2019-04-09
本文字数: 3.4k | 阅读时长 ≈ 3 分钟

搞了几天终于把这个搞出来了,代码不到50行,要是别的网站很好模拟,但是这个稍微有点麻烦,抓包工具用了很多,httpfox没有抓全,wireshark抓的又太多不好分析,最后还是使用神器fiddle才把它搞出来。

工具

  • 火狐浏览器+firedebug插件,debug插件可在浏览器附加组件中添加,其他浏览器也可以,只要有可以监控浏览器的网络行为插件即可。(notes:这里没有使用到firedebug,而是使用火狐浏览器自带的审查工具)
  • Python+requests包

步骤

打开火狐浏览器,输入网址”http://211.85.192.115/srun_portal_pc.php?ac_id=1&“,打开校园网登录页面,如下:

登录账号和密码,显示登录成功

右键单击【审查元素】-【网络】

构造请求头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 构造头部信息 注意Cookie可能十分重要,而且Cookie会有过期时间(我们学校过期时间是1个月),过期之后,可能需要复制新的Cookie替换。
post_header = {
#'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
'Accept': '*/*',
#'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'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',
'Accept-Encoding': 'gzip, deflate',
#'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',

#'Origin': 'http://wlrz.fudan.edu.cn',
'Referer': 'http://211.85.192.115/srun_portal_pc.php?ac_id=1&',
#'Content-Length': '112',
'Content-Length': '104',
#'Cookie': 'login=YUtl4F5w2GWDfWUA8O0nj3eCm7TrrFp%252FtbchCKzbO84IQczKx%252Fyc5mYGG7s6FQxsyiZbjwUIcJ2ECcqXWO%252BzwX85KrsMq0MDW7tX1eoOzS00eusx19E0245ORqeeZHVwBzEd1DGI%253D',
'Cookie': 'login=请自己获得,这里不提供',
#'Host': 'wlrz.fudan.edu.cn',
'Host': '211.85.192.115',
'Connection': 'keep-alive',
}

构造发送数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#此处根据自己校园网Form Data中发送的数据进行更改
action = 'login'
username = '学号'
#password = '加密的密码'
password = '密码xxx'
ac_id = '1'
save_me = '0'
ajax = '1'
#user_ip = '127.131.1.1'

post_data = {
'action': action,
'username': username,
'password': password,
# 'password': base64.b64encode(password.encode()).decode(),
# 'password': base64.b64encode(password.encode()),
'ac_id': ac_id,
# 'user_ip': user_ip,
'save_me': save_me,
'ajax': ajax
}

内容有方式、学号、密码还有其他,其中密码不是明文,这密码应该是加密的,在所有js文件中搜索password,发现有一处函数,验证了是base64加密方式。(注意:以下操作是在在Chrome浏览器中进行的)
在chrome浏览器中,输入账号登录网址”http://211.85.192.115/srun_portal_pc.php?ac_id=1&“,右键【审查元素】-【网络】,然后刷新


于是开始着手写代码了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def login_request():
if not is_net_ok():
print("[03]{} whpu-wlan is offline, request now...".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
# password = base64.b64encode(password.encode()).decode() #加密
try:
# 发送post请求登录网页
result = requests.post(post_addr, data=post_data, headers=post_header)

# z.text为str类型的json数据因此先编码成byte类型再解码成unicode类型这样就可以正常输出中文
s = result.text.encode('utf-8').decode('unicode-escape')
print(s)
print("login success!")
except:
print("[00]{} request error, whpu-wlan isnto connected to WIFI...".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
else:
print("[02]{} whpu-wlan is online, login sucesss...".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

login_request()

参考文献

  • (2016.7.18)python脚本实现自动登录校园网

  • (2017.10.24)python实现校园网自动登录

  • (2018.7.13)用python写服务器校园网上网认证脚本

  • (2018.11.24)基于python实现校园网自动登录

------------------------ The End ------------------------

证件之星软件个人加密狗完美破解心得

发表于 2019-03-20 | 分类于 电脑 , 破解心得
本文字数: 1.1k | 阅读时长 ≈ 1 分钟

破解过程

由于此软件程序为Delphi 所编写,并且无壳,直接载入OD,发现有狗,第一次打狗,不容易,如下图


发现修改狗,轻松进入软件,但是通过使用软件后发现有以下四点问题:

  1. 点击"一键完成"会出现错误信息弹窗,点击确定软件关闭,如下图:

程序载入OD,右键搜索中文字符“软件遇到异常错误,即将关闭”,如下图,按图操作


这个问题解决了,一键处理已经ok了
但是还有以下三个问题没有处理。

由于此软件是Delphi编写的,利用其特征码给其按钮事件下断,载入OD,CTRL+G,转到00401000处,然后右键—-查找——-二进制字符串,输入我们的特征码740E8BD38B83????????FF93????????,在特征码的下面都会有一个call,我们就在call处下断点,之后寻找下一个(CTRL+L),直到显示为没有。为什么要下那么多断点,因为我们也不知道那一个会用上。那如果特征码的情况比较多怎么办,我的建议是使用脚本(脚本百度),能快速的下断点,程序运行起来,结果发现,断下来了,但是这三个按钮点击依然闪退,找不到真正的按钮事件地址,怎么办了呢?

由于本菜鸟是新手,用了好多办法都不是很凑效,最后发现有这款软件,Delphi 事件到地址转换工具 v2.020 汉化版——可以查看Delphi 程序软件的按钮事件真实地址,实在太好了,于是就将程序载入Delphi 事件到地址转换工具中,终于找到了以OnClick 显示的按钮事件真实地址。

如下图说明:以此处理三个问题,载入OD,Ctrl+G,输入地址,点击ok来到真是地址,然后找到图中关键跳修改即可。

  1. 点击背景处理弹窗中的“处理”按钮,软件闪退,解决办法如下图。

  2. 点击照片保存弹窗中的“保存”按钮,软件闪退,解决办法如下图。

  3. 点击照片打印,软件闪退,解决办法如下图。


    到此完美爆破,本菜鸟还需努力学习,谢谢大家!

下载地址

源程序下载

原程序下载:

  • 官网下载
  • 本地下载

爆破程序下载

爆破程序下载:

  • 百度网盘 链接:https://pan.baidu.com/s/1wOwV6tjtKZ5wI78dQJQKCA 提取码: kpsg
  • 本地下载

Delphi事件到地址转换工具 v2.020

Delphi 事件到地址转换工具 v2.020 汉化版下载,解压密码:RCFF Team:

  • 百度网盘 链接:https://pan.baidu.com/s/1Y_hgYvlcCjA_dObcrWSa4A 密码:xihj
  • 本地下载
------------------------ The End ------------------------

win10卸载或更改程序中不显示修改日期和类型

发表于 2019-03-19 | 分类于 电脑 , 常见故障
本文字数: 216 | 阅读时长 ≈ 1 分钟

Windows7 卸载或更改程序 中不显示时间和大小
急求!win10控制面板的卸载软件,都不显示安装日期了
有个软件我安装了新版本,准备按安装日期卸旧版本。上次关机前都是正常显示安装日期的,打开就成这样了,混在一起(点击日期全都变成一天的了)

问题描述

解决方法

方法1

在列表的空白处右键,在弹出的菜单中选择:“分组依据”,“更多”,勾选“安装时间”,最后点击“确定”即可。

方法2

在名称栏上右击

将“安装时间”打勾即可

如下图所示:

------------------------ The End ------------------------

BaiduPCS-Go的安装及使用[CMD]

发表于 2019-03-18 | 分类于 电脑 , 百度云下载 , BaiduPCS-Go[CMD]
本文字数: 4.1k | 阅读时长 ≈ 4 分钟

你是否经常对百度网盘非VIP的几十K下载速度而痛恨不已?没错,百度就是无赖,VIP会员下载速度可以达到2MB/s,甚至更高,普通用户不加速也就算了,还限速!不能忍!其实,我个人对于百度的产品是十分抗拒的,因此平时基本不用百度的产品,但是也有例外的时候,比如百度网盘。因为对电影的画质要求比较高,所以一些1080P的电影动辄6、7个G,所以普通的网络下载是特别慢的,而且这些资源往往以种子的形式存在,于是经过摸索终于找到一个下载很快的方法,这里推荐给大家。当然,这个方法不仅适用于下载电影,任何保存于百度网盘的文件使用这种方法都可以达到不亚于VIP的速度,甚至顶速(具体情况取决于你使用的网络速度),关键是免费!

注:这个教程里会涉及到一些非常简单的命令行操作,但是非程序员请不要抵触或者害怕,毕竟带来的便利是可观的,来个效果图感受一下:

BaiduPCS-Go是用Go语言写的一个开源的小工具,专门用于突破百度对于非VIP用户对百度网盘下载速度的限制。其项目源码地址如下:https://github.com/iikira/BaiduPCS-Go 。在其readme文件中,对于软件的使用做了很详细的介绍,有兴趣的人可以阅读一下,我这里只介绍最基本的安装和使用方法。

特色

这是一个仿Linux命令行的百度网盘客户端。(是的,不限速)

注意:
  文件名和目录名可用通配符补全(使用代替n个字符,n>=0)。

1
2
3
# 示例:
d /a_directory/b_directory/c_file.txt =
d /a*/b*/c*

特点:

  • 跨平台(Windows,macOS,Android等)
  • 支持多账户。
  • 网盘内列出文件和目录, 支持通配符匹配路径;
  • 下载网盘内文件, 支持网盘内目录 (文件夹) 下载, 支持多个文件或目录下载, 支持断点续传和高并发高速下载。
  • 离线下载,支持http/https/ftp/电驴/磁力链协议。
  • 好玩,不过没有一点Linux基础,就不怎么好玩了。

软件下载及安装

项目地址: iikira/BaiduPCS-Go
下载地址: iikira/BaiduPCS-Go releases

a. Android/macOS

Android:需要用到 Termux 或 NeoTerm 类软件。这里只提一下。
macOS:没有macOS的设备,这里属于凑字数。

b. Windows

下载地址:

  • 64位系统:BaiduPCS-Go-v3.3.3-windows-x64.zip
  • 32位系统:BaiduPCS-Go-v3.3.3-windows-x86.zip
  • GitHub地址: https://github.com/iikira/BaiduPCS-Go/releases

下载说明:

请按照上述说明下载对应的版本,我只测试了windows和linux的机器,其他系统暂时没有测试。

对于windows系统,确认系统类型的方法:右键点击“我的电脑” -> “属性” -> “系统类型”

该软件是绿色软件,下载完成后请直接解压到你的自己的软件目录即可。

软件的使用

该软件的使用方法也很简单,在Linux下和Windows下的方法一模一样,只不过程序的名字有一点差异(Windows下,软件的名字叫做“BaiduPCS-Go.exe”,Linux下,软件的名字叫做“BaiduPCS-Go”)。以下以Windows系统为例讲解软件的使用。

程序运行

下载后解压缩,双击 BaiduPCS-Go.exe。
界面如下:

1
2
3
4
5
6
----
BaiduPCS-Go - 百度网盘客户端 for windows/amd64
.......
.......
.......
BaiduPCS-Go >

界面很长,这里用省略号代替。

登录/退出/切换

1
2
3
login     # 登录
logout # 退出当前账户
su/chuser # 切换账户

在命令行窗口中输入 login ,再根据提示输入账号和密码,即可登录百度账号。

还有其他登录方式,如 login -bduss=。(获取bduss)

logout 和 su / chuser 的用法也比较简单。

在使用前,我们首先要登录百度账号,只要不手动退出账号,以后可以直接使用,而不必每次都登录。
首先,打开命令行,打开命令行的方式有两种:

  • 菜单打开
    屏幕左下角“开始” -> “所有程序” -> “附件” -> “命令提示符”

  • 快捷键打开
    按下键盘上的Win(显示微软图标的那个键)+R, 在弹出的窗口输入”cmd”,然后按下回车

接下来我们需要进入刚才解压好的软件目录,比如我的路径为:C:\Users\User\Downloads\BaiduPCS-Go-v3.5.6-windows-x64,那么在刚弹出的窗口中输入,并按下回车:

1
cd C:\Users\User\Downloads\BaiduPCS-Go-v3.5.6-windows-x64

然后开始输入命令登录百度账户,在窗口中输入:

1
BaiduPCS-Go.exe login

然后按照下图操作即可登录:

在显示成功登陆后,我们就可以关掉这个窗口了。然后双击BaiduPCS-Go.exe这个文件就可以进行下一步的操作了。
如果要退出账号,只需要在这个窗口中输入logout即可。

切换目录

1
2
3
4
5
cd -l /Path/To/File

# cd = change directory = 切换目录。
# /Path/To/File = 文件路径,绝对路径或相对路径。
# -l: 显示目标目录下的子文件及子目录。

例:cd /a/b/c/d

查看当前账户及已登录账户

1
loglist

查看文件

  • 查看文件命令ls (list)

  • 切换目录
    默认情况下,打开之后执行ls看到的文件就是你百度网盘最顶层目录,如果想切换目录的话,执行以下命令

    1
    cd xxx

其中xxx是你想切换的文件夹名。

  • 切换到上一级目录
    使用下面的命令可以切换到上一级目录:
    1
    cd ..

下载文件

下载文件的命令如下:

1
download -p 1000 xxx

其中xxx是你要下载的文件名,如下图所示:

上传文件

上传文件时,需要打开命令行来操作。上传文件的命令如下:

1
BaiduPCS-Go upload xxx yyy

其中xxx是你要上传的本地文件名,yyy是你百度网盘下的目录名,比如我要把我本地放在C:\Users\User\Downloads下的一个叫做Git-2.18.0-64-bit.exe的文件传到百度网盘的/Softwares/Tools目录下。命令如下:

1
BaiduPCS-Go.exe upload C:\Users\User\Downloads\Git-2.18.0-64-bit.exe /Softwares/Tools

然后,我们就能看到如下的结果:

1
这里要注意的是,windows系统下,本地文件的路径名书写要用\,而百度网盘路径名书写要用/.

web功能

1
web #启用web功能

输入上述命令后,在浏览器栏输入localhost:8080,就可以在本地查看你的网盘目录。

很不错的功能。

帮助菜单

1
h

输入 h ,可以看到帮助菜单。这里做成表格,以便观看

1
用法:输入 h ,可以看到帮助菜单。这里做成表格,以便观看

COMMANDS 含义
tool 工具箱
help / h Shows a list of commands or help for one command
其他:
run 执行系统命令
sumfile / sf 获取文件的秒传信息
web 启用 web 客户端 (测试中)
百度账号:
login 登录百度账号
loglist 获取当前帐号, 和所有已登录的百度帐号
logout 退出当前登录的百度帐号
su / chuser 切换已登录的百度帐号
百度网盘:
cd 切换工作目录
cp 拷贝(复制) 文件/目录
download / d 下载文件或目录
ls / l / ll 列出当前工作目录内的文件和目录 或 指定目录内的文件和目录
meta 获取单个文件/目录的元信息 (详细信息)
mkdir 创建目录
mv 移动/重命名 文件/目录
offlinedl/clouddl / od 离线下载
pwd 输出当前所在目录 (工作目录)
quota 获取配额, 即获取网盘的总储存空间, 和已使用的储存空间
rapidupload / ru 手动秒传文件
rm 删除 单个/多个 文件/目录
upload / u 上传文件或目录
配置:
config 显示和修改程序配置项
GLOBAL OPTIONS: 全局选项
–verbose 启用调试 [%BAIDUPCS_GO_VERBOSE%]
–help / -h 查看帮助
–version / -v 查看版本号

常见问题

  • 关于BaiduPCS-Go不能用问题解决,报错【获取目录下的文件列表 遇到错误, 远端服务器返回错误】
    BaiduPCS-Go不能使用报错:获取目录下的文件列表 遇到错误, 远端服务器返回错误, 代码: 4, 消息: No permissionto do this operation, 路径: /
    设置新的appid!:
    目前已知可用APP id:266719

在软件输入 config set -appid=266719。

  • 注意以下问题:错误代码403/31066 造成无法下载问题
  1. 下载路径和文件命名不带空格符号。
  2. 检查文件路径是否过于复杂(如果实在不行就直接下载整个文件夹)
  3. 如果还是不行,那就换别的账号登录吧

参考文献

  • [教程]BaiduPCS-Go
  • BaiduPCS-Go的安装及使用
------------------------ The End ------------------------

基于BaiduPCS-Go打造的Web界面

发表于 2019-03-18 | 分类于 电脑 , 百度云下载 , BaiduPCS-Go
本文字数: 1.1k | 阅读时长 ≈ 1 分钟

使用说明

github地址: https://github.com/liuzhuoling2011/baidupcs-web



腾讯视频: 地址

下载链接: https://github.com/liuzhuoling2011/baidupcs-web/releases

3.6.5 版本发布:

  • 修复由于密码访问带来的安全隐患,强烈建议更新
  • 增加只可以本地访问的模式
  • 后台增加配置下载设置的API(页面暂时还没加入)
  • 修复无法上传文件名含有 [ 字符的文件
  • 新增公众号二维码, 更方便及时交流

3.6.4 版本发布:

  • 支持设置工作目录,之后可以规避错误 “无法下载 返回“遇到错误, 远端服务器返回错误, 代码: 31326, 消息: user is not authorized, hitcode:123”
  • 参考链接 https://github.com/iikira/BaiduPCS-Go/issues/460

3.6.3 版本发布:

  • 修复了移动端页面显示异常的bug

3.6.2 版本发布:

  • 页面针对包含大量文件的文件夹处理,上传下载列表进行优化,解决页面卡死问题,打开速度提升十倍左右
  • 文件列表排序选项写入localstorage,长久有效
  • 在Windows和Mac下程序打开时调用默认浏览器打开链接 http://localhost:5299

3.6.1 版本发布:

  • 添加移动端UI
  • 新增支持BDUSS登录

3.5.9 版本发布:

  • 根据baidupcs-go的后台项目更新升级优化了下载, 上传
  • 新增回收站操作(暂时回收站删除单个文件会出问题, 不过不影响)
  • 新增重命名操作, 添加了列视图下文件删除和下载的快捷操作
  • 修复下载文件夹时文件夹任务残留的bug
  • 修复appid错误设置之后打开设置界面为空白的问题
  • 修复了设置界面输入特殊符号无效的问题

附加说明:

  • 之前如果使用过BaiduPcs软件, 可能会出现登录后加载文件列表会卡死,或者遇到错误, 远端服务器返回错误, 代码: 4, 消息:"No permission to do this operation"

  • 可以试试, 在右上角的设置里面把 PCS应用ID 设置为 266719 就可以正常使用了

  • "目前百度是针对账号进行限速,当一个非会员账号下载量达到一定阈值就会触发限速。账号被限速之后容易出现下载错误、掉连接数等问题,需要过几天或者开通会员才会恢复。"

  • 这个是需要百度云账号登陆的, 不用太担心安全什么的,相信开源的力量吧~

参考文献

  • [WEB]基于BaiduPCS-Go打造的Web界面, 让你高效的使用百度云
------------------------ The End ------------------------

爱字幕app破解VIP教程

发表于 2019-03-07 | 分类于 Android , 逆向分析
本文字数: 303 | 阅读时长 ≈ 1 分钟

这次是破解爱字母app的VIP教程
破解教程仅供研究参考,请勿用于商业用途

软件有360加固哦 自行脱壳
本次只会给出核心破解版

此次教程是用小米商店下载的最新版爱字幕1.5

  • 完美没水印
  • 解锁VIP

破解前

破解后

破解步骤

  • 首先脱壳得到dex 把除了软件的类全部删除
  • 搜索isVip
  • 全部赋值1

重命名为classes2
添加进apk
保存返回安装看效果

下载地址

成品下载地址:http://t.cn/EIu1EDR
成品本地下载地址2

参考文献

【简单】爱字幕app破解VIP教程
https://www.52pojie.cn/thread-889438-1-1.html
(出处: 吾爱破解论坛)

------------------------ The End ------------------------

爱奇艺万能播放器 绿色修改 & 高速百度云下载

发表于 2019-03-07 | 更新于 2019-03-18 | 分类于 电脑 , 百度云下载 , 爱奇艺万能播放器
本文字数: 1.9k | 阅读时长 ≈ 2 分钟

目前爱奇艺属于百度旗下,有细心的网友发现爱奇艺万能播放器竟然能不限速的下载百度网盘的资源!
启动播放器,右上角可以看见百度网盘的标志。

2018/11/18 17:00 之前下载的网友重新下载即可解决问题。
百度云高速下载速度不错:

测试效果

百度云下载功能可用,2018/11/18 17:00测试效果:

绿化步骤

使用须知,绿化步骤:

百度云功能启用

百度云功能启用:

设置图片关联功能

设置图片关联功能:(可设置为默认查看器,菜单里找)设置步骤:

修改特点:

# 去除强制更新。

# 去除多余菜单,界面搜索框。

# 禁止生成无用文件及文件夹。

# 批处理进行 绿化、卸载。

使用指南

目前爱奇艺属于百度旗下,有细心的网友发现爱奇艺万能播放器竟然能不限速的下载百度网盘的资源!
启动播放器,右上角可以看见百度网盘的标志。

然后登录你的百度网盘账号

找到你要下载的资源即可下载啦!

这个功能目前不支持同时下载多个任务,不支持下载文件夹;
如果界面右上角没出现百度网盘功能的按钮,请重启播放器!

更新日志:
5.1.55.4941 (2018.12.05)
更新日志:
1、新增暂停时逐帧快进功能
2、优化程序启动速度
3、优化播放器定时功能
4、优化看图模式图片缩放效率
5、其他各种问题修正及细节优化

官方下载地址

官方下载地址:
爱奇艺万能播放器 v5.1.55.4941
http://mbdapp.iqiyi.com/j/ot/GeePlayerSetup_onlineupdate_201812051603.exe

更新介绍及下载

2018/11/18 更新特点:
没有集成 百度云下载浏览器 ,点击 百度云图标 会自动下载!!!

2019/11/19 使用说明:
1、有网友反映,在线播放 打开URL 功能不能使用,经体验,官方版也不能使用。
2、百度云功能正常能用,不能使用的网友,确定下载的是18号更新的版本,首次打开需等待百度云加载完成。
3、看到有网友反馈限速,这个问题我解决不了。因为我这里的下载速度大家也看到了,网络是 电信网络。对于限速的网友,可以尝试换一下网络环境试试,或者 换一个 百度云账号看一下。另外,这款软件只能单个下载,无法批量下载。

2018/11/19 15:00 做最后更新:
1、修复由于之前修改过度,导致 点击 设置关联 的时候不能设置关联以及闪退问题。
2、精简一些更新有关的文件(软件已禁止更新)。

2018/11/23 14:00 完善批处理:
1、完善卸载批处理,卸载后几乎不留痕迹。

爱奇艺万能播放器 3.2.49.4280 下载链接:(2018/11/23 14:00 更新)
链接: https://pan.baidu.com/s/1pNt3Cr6WmZrukN8P-tbdpg 提取码: pyev

2018/11/18 更新到最新版:
爱奇艺万能播放器 5.1.53.4745 下载链接:(2018/11/23 14:00 更新)
链接: https://pan.baidu.com/s/1WC5pCtnmTo8F8AouufNU1Q 提取码:dqv5

两个版本比较:
1、从百度云下载来看没啥区别
2、新版貌似多着爱奇艺视频助手 功能,但是这个功能开启后,安装体积100M多点。
3、没啥特殊需求的话,两个版本随意用。

当然,想必有网友问,有没有爱奇艺视频助手 提取版,答案是:必须有。

爱奇艺视频助手

爱奇艺视频助手 7.5.3.15 修改特点:

  • 禁止检查更新
  • 去除反馈等菜单

爱奇艺视频助手 软件特色:

图片MV ,功能:

转码功能

转码功能:支持各种视频转换为mp4\mkv\flv格式

2018/11/23 14:00 完善批处理:
1、完善卸载批处理,卸载后几乎不留痕迹。
爱奇艺视频助手 7.5.3.15 下载链接:(2018/11/23 14:00 更新)
链接:https://pan.baidu.com/s/1Cj37KNN_w-WqlG9vqpDbOw 提取码: 8yki

问答

  • 对于不显示 百度云 图标的网友,尝试重新启动软件3次左右,每次在联网状态下停留1分钟左右。

参考文献

  • 参考1
    11/23(完善批处理)修复百度云 爱奇艺万能播放器 绿色修改 & 高速百度云下载
    https://www.52pojie.cn/thread-823826-1-1.html
  • 参考2
    爱奇艺万能播放器 v5.1.55.4941 支持度盘高速下载
    https://www.52pojie.cn/thread-834449-1-1.html
------------------------ The End ------------------------

chrome打开开发者工具(F12)之后看不到请求头信息

发表于 2019-03-04 | 分类于 Chrome
本文字数: 263 | 阅读时长 ≈ 1 分钟

开发者工具的network窗口能够查看浏览器的请求头以及响应头信息,但是有时打开开发者工具会遇到像下图这种情况

找不到请求信息,无法查看请求头,或响应头。

解决方法:
1.点击“Filter”按钮,也就是图中的漏斗形状的按钮。下面会多出一系列选项,如图

2.点击“All”,然后按“F5”刷新网页。之后在下方会出现资源文件,如图

3.然后在name一栏中点击资源文件,在右侧会弹出显示框,点击“Header”,就可以看见请求头了

参考文献:

  • chrome打开开发者工具(F12)之后看不到请求头信息(CSDN; Blog)
------------------------ The End ------------------------

使用Cookies登录网站

发表于 2019-03-04 | 分类于 Chrome
本文字数: 485 | 阅读时长 ≈ 1 分钟

推荐两个谷歌浏览器的插件:

1
2
3
https://chrome.google.com/webstore/detail/simple-extension/ofhbnimjijmnaigdfhhmhegnlmcbilba 

https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg

效果说明:

  1. 第一个可以自定义浏览器的信息,我多个百度云账号可以实现点击即切换。
  2. 第二个是很早之前用的一个插件,可以导入、导出、锁定cookies。

插件介绍:

  • 第一个插件的开源网址

    1
    https://github.com/gzlock/simple-extension
  • 第二个:EditThisCookie,是一个国外写的,

    1
    2
    http://www.cnplugins.com/devtool/editthiscookie/detail.html
    http://chromecj.com/productivity/2014-07/8/download.html
------------------------ The End ------------------------

离线下载Chrome crx扩展插件

发表于 2019-03-04 | 分类于 Chrome
本文字数: 1.1k | 阅读时长 ≈ 1 分钟

使用 Chrome 应用商店下载 crx 插件时,一下载完,Chrome 浏览器就会默认进行安装。如果是我们自己浏览器要安装这个插件,那么直接安装没啥问题,只是有时候我们想把这个插件下载下来分享给其它朋友,所以就会出现,如果我们使用 Chrome 浏览器直接下载 crx 拓展程序,一下载就是直接提示安装,而没办法将这个拓展程序导出来。

那么如何解决?下面以下载 Chrome 下有道词典Chrome划词插件为例,介绍如何离线下载 crx 。

Crx离线下载方法一

首先访问你要下载的插件,比如这里我要下载有道词典 Chrome 划词插件这个拓展,插件地址: https://chrome.google.com/webstore/detail/有道词典chrome划词插件/eopjamdnofihpioajgfdikhhbobonhbb 然后复制出最后 32 位的应用id,这个地址的应用id为: eopjamdnofihpioajgfdikhhbobonhbb 如下截图(如果图片模糊,点击图片查看大图):

然后使用其它浏览器(非Chrome浏览器)访问 :
https://coderschool.cn/crx/dowcrx.html

访问界面如下:

把上面的 32 位应用 id 复制到上图的文本框里面,然后点击生成,接着鼠标在步骤二的蓝色文字那边右键另存为即可:


然后就可以顺利的下载和保存插件了。

上面下载方法解析
其实真正的下载地址是这个地址: https://clients2.google.com/service/update2/crx?response=redirect&x=id%3D要下载的应用id%26uc 把上面链接的要下载的应用id替换成32位应用id,然后访问这个链接即可进行下载。上面的操作都需要你能正常访问谷歌 Chrome 应用商店。

Crx离线下载方法二

方法和上面方法一介绍的基本一致。 首先访问 https://chrome-extension-downloader.com/,访问后站点截图:

然后把你要下载插件的整个 url 地址或者应用 id 复制到文本框即可进行下载,如下:

Crx离线下载方法三

http://yurl.sinaapp.com/crx.php

参考文献

离线下载 Chrome crx 拓展插件

本文来源于:技术拉近你我!。
原文标题: 离线下载 Chrome crx 拓展插件
原文链接:https://coderschool.cn/2396.html

------------------------ The End ------------------------

逆向一个易语言DLL的加密算法

发表于 2019-03-04 | 分类于 电脑 , 逆向分析
本文字数: 1.2k | 阅读时长 ≈ 1 分钟

逆向一个易语言DLL的加密算法。关键算法逆出来了,但是没有看懂属于什么算法。

前言

这个DLL是一个授权的,填入激活码之后会访问自己的后台验证。
我也是闲来无事,拿来学习学习。如果作者看到了,并非恶意。
先来说下我如何进行逆向算法的。
因为易语言的DLL脱离不了核心支持库。核心支持库是有特征码的,不管程序怎么加密,核心支持库是加密不了的。我们可以用核心支持库的特征 来进行逆向算法。

程序和DLL的核心支持库都是独立存在的。

DLL用的是DLL编译时的核心支持库。

过程

其中的链接 我就拿 http://www.baidu.com 为例

前面的加密算法 是通过核心支持库逆出来的。

程序启动后是不会直接加载DLL的。
需要使用过DLL的函数后 才会加载。
等加载完DLL之后 我们进入DLL层


双击这个DLL 就可以进入DLL层了。

然后就是通过特征码来在DLL层下断点。这里我用的的工具 知道edebug找到核心支持库的地址。

再通过这个特征 查找特征的位置的位置。

在这里下断。

RC4和DES加密处也要下断,为了就是看看 没有没有使用易语言自带的加密

为了就是看看有没有使用核心支持库里的加密算法。
做的动作有,先获取13位时间戳 然后把最后3位改成000

解密出来的是我填入进去的激活码。

继续运行。运行几次之后 会出来二次解密。

我写着写着 居然忘了二次解密的密码是怎么找到的了。。。

密码是 sdvscv;lwe,r[xc/bvfsd/w

再用自己的激活码进行二次解密。

密文|密文的MD5|X 分割 取密文

再将解密出来的密文 进行MD5和程序计算的MD5是否一致,

关键 关键来了。

密文的长度位128位

其实这个密文是16进制的,

转到字节集后 进行倒序。
1a2b3c4d5f -> 5f4d3c2b1a

然后就是进行3次解密,

因为解密出来的是128位

就是 moc.udiab.www//:ptth +字节 {0}+ 后面的107长度字节集 (后面107位不知道是做什么用的。)

关键解密 的特征码为↓↓↓


55 8B EC 81 EC 24 00 00 00 C7 45 FC 00 00 00 00 C7 45 F8 00 00 00 00 68 05 00 00 80 6A 00 8B 5D
0C 8B 03 85 C0

最后再将倒序的链接 矫正之后 就是真正的后台授权地址。(http://www.baidu.com)

参考文献

逆向一个易语言DLL的加密算法。关键算法逆出来了,但是没有看懂属于什么算法。
https://www.52pojie.cn/thread-886009-1-1.html
(出处: 吾爱破解论坛)

相关下载

链接: Desktop.rar https://pan.baidu.com/s/1RjcYrrmNnXyY0zsR9ml_Gw 提取码: 4n7g

------------------------ The End ------------------------

安卓逆向分析笔记---002

发表于 2019-03-04 | 分类于 Android , 安卓逆向分析
本文字数: 2.2k | 阅读时长 ≈ 2 分钟

这次与上次的软件很像,不过这次里面是输入的注册码~

【所需工具】Androidkiller、Unicode工具

【用例下载链接】链接:(简单2)https://pan.baidu.com/s/1wsoKyF4HvTdfq3N2zWIlIw 提取码:bnp1

【开始操作】

与上次一致,将APK拖到AndroidKiller里面,反编译完成后点击“工程管理器”,与上次分析一样,双击打开AndroidManifest.xml,如下图

根据路径找到第一启动类,点开Java源码看代码,如下图

实际上我们已经可以看到注册码就是“写个CM都很难啊”,当然可以直接输入这个注册成功,但是我希望的是什么都不输入就能注册成功,所以我打算去改判断的内容,我在MainActivity.smali里面没有看到相关的Unicode码,所以只能搜索,我先打开Unicode工具将以下几项设置好,输入“写个CM都很难啊”,如下图

将Unicode码区的内容复制,重新返回AndroidKiller,点击左侧工程搜索,在字符框粘贴复制的内容,下面设置成如下图所示,点击搜索

emmmmmm…,换个字符串试试

搜索到一行数据,点开打开看看

可以看到左下角有解码后的翻译,向上翻,发现了这行Unicode码

为什么之前没有搜索到?emmmmmmm,比较一下

原来是“CM”没有被翻译过来,所以才会搜索不到,那就直接看这里

简单的翻译一下
const-string v1, “\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a” #将“写个CM都很难啊”的字符串赋值给V1

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z #调用equals方法比较V0与V1的值是否相等

move-result v0 #返回一个布尔值传给V0(V0、V1相等就等于1,不相等就等于0)

if-eqz v0, :cond_0 #如果V0等于0,就跳转到cond_0(cond_0后面的内容是注册失败)

【修改方法一】

1
2
3
4
5
6
7
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

if-eqz v0, :cond_0

修改为:

1
2
3
4
5
6
7
8
9
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

const\4 v0,0x1

if-eqz v0, :cond_0

【修改方法二】

1
2
3
4
5
6
7
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

if-eqz v0, :cond_0

修改为:

1
2
3
4
5
6
7
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

if-nez v0, :cond_0

【修改方法三】(分析认为可以这样修改,目前没有试过)

1
2
3
4
5
6
7
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

if-eqz v0, :cond_0

修改为:

1
2
3
4
5
6
7
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"

invoke-virtual {v1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v0

if-eqz v0, :cond_0

参考文献:
安卓逆向分析笔记—-002
https://www.52pojie.cn/thread-886046-1-1.html
(出处: 吾爱破解论坛)

问答:

  • androidkiller搜索字符串下的“搜索”按钮后的小三角点开可以直接转unicode。
------------------------ The End ------------------------

获取腾讯视频真实地址(涉及清晰度选择)

发表于 2019-03-03 | 更新于 2019-03-04 | 分类于 电脑 , 视频解析
本文字数: 8.1k | 阅读时长 ≈ 7 分钟

前言

  • 由于需要在小程序插入腾讯视频,于是在网上找了诸多方法,但基本都只能抓到低清版本的;偶然发现大神能抓到超清版(720p)的,但由于自己的视频并不都含有超清的版本,因而只能退而求其次使用480p的;这对于移动端(包括全屏)的清晰度已经足够了。毕竟也不是专门做视频的小程序。
  • 环境:linux
  • 语言:python
  • 本文原创地址:https://blog.csdn.net/Szu_IT_Man/article/details/80449751

步骤

主要api

  • http://vv.video.qq.com/getinfo
  • http://vv.video.qq.com/getkey

腾讯视频的vids

  • 当你打开一个腾讯视频的时候,比如https://v.qq.com/x/page/x0164ytbgov.html,vids=x0164ytbgov。
    这个将作为参数让我们去访问api.

访问getinfo

  • 当我们得到vids后,我们就可以访问api:
    http://vv.video.qq.com/getinfo?vids=x0164ytbgov&platform=101001&charge=0&otype=json&defn=shd
    (如果需要xml格式,就让参数中otype=xml)

  • 获取到 json1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    QZOutputJson=
    {
    "dltype":1,
    "exem":0,
    "fl":{
    "cnt":2,
    "fi":[
    {"id":100701,"name":"msd","lmt":0,"sb":1,"cname":"标清;(270P)","br":28,"profile":2,"drm":0,"video":1,"audio":1,"fs":16546732,"sl":1},
    {"id":2,"name":"mp4","lmt":0,"sb":1,"cname":"高清;(480P)","br":33,"profile":1,"drm":0,"video":1,"audio":1,"fs":34433483,"sl":0}
    ]
    },
    "hs":0,"ip":"120.36.254.197","ls":0,"preview":555,"s":"o","sfl":{"cnt":0},"tm":1527217153,

    "vl":{
    "cnt":1,
    "vi":[
    {
    "br":28,
    "ch":0,
    "cl":{"fc":0,"keyid":"x0164ytbgov.100701"},
    "ct":21600,
    "drm":0,
    "dsb":0,
    "fmd5":"99fb72a48f2a392ec88b5c17bac4ff81",
    "fn":"x0164ytbgov.m701.mp4",
    "fs":16546732,
    "fst":5,
    "fvkey":"1E327E4FE26E8B8222C226B0873DBF94C094934198E382AE2910361C29E5396237CCF814A49976A5A485F2E806CBC4C21602406034413F9896BF0972F7678D8263845FD123BA9B3604419489CD2BF4254EFD5F87D62A6F88FFF2A4E38F57C9898DD1F7C38C1F548C",
    "head":0,
    "hevc":0,
    "iflag":0,
    "level":0,
    "lnk":"x0164ytbgov",
    "logo":1,
    "mst":8,
    "pl":null,
    "share":1,
    "sp":0,
    "st":2,
    "tail":0,
    "td":"555.00",
    "ti":"World Builder (high quality)",
    "tie":0,
    "type":3,
    "ul":{
    "ui":[
    {
    "url":"http://ugcws.video.gtimg.com/",
    "vt":106,
    "dtc":0,
    "dt":2
    },
    {"url":"http://122.228.238.157/vhot2.qqvideo.tc.qq.com/AcSbzObMTmKX0kJqo8qTGhY0OAwzkw14O81CvShBXrlI/","vt":200,"dtc":0,"dt":2},
    {"url":"http://ugcdl.video.gtimg.com/","vt":116,"dtc":0,"dt":2},
    {"url":"http://video.dispatch.tc.qq.com/","vt":0,"dtc":0,"dt":2}
    ]
    },
    "vh":256,
    "vid":"x0164ytbgov",
    "videotype":0,
    "vr":0,
    "vst":2,
    "vw":480,
    "wh":1.875,
    "wl":{"wi":[]}
    }
    ]
    }
    };

拼接低清版本的视频地址

  • 到这一步,我们就可以获取低清版本的视频源地址了。
  • 我们把获取到字符串去掉QZOutputJson=和最后的分号,变成正式的json

    1
    2
    3
    4
    realVideoURLRequestPath="http://vv.video.qq.com/getinfo?vids=x0164ytbgov&platform=101001&charge=0&otype=json&defn=shd"
    videoInfo = requests.get(realVideoURLRequestPath)
    videoInfo_json = videoInfo.text[len('QZOutputJson='):-1]
    tempStr = json.loads(videoInfo_json)
  • 这样我们就可以获取到

    1
    2
    3
    4
    tempStr['vl']['vi'][0]['ul']['ui'][0]['url']
    +tempStr['vl']['vi'][0]['fn']
    +"?vkey="
    +tempStr['vl']['vi'][0]['fvkey']
  • 即:

    1
    http://ugcws.video.gtimg.com/x0164ytbgov.m701.mp4?vkey=1E327E4FE26E8B8222C226B0873DBF94C094934198E382AE2910361C29E5396237CCF814A49976A5A485F2E806CBC4C21602406034413F9896BF0972F7678D8263845FD123BA9B3604419489CD2BF4254EFD5F87D62A6F88FFF2A4E38F57C9898DD1F7C38C1F548C

http://ugcws.video.gtimg.com/x0164ytbgov.m701.mp4?vkey=1E327E4FE26E8B8222C226B0873DBF94C094934198E382AE2910361C29E5396237CCF814A49976A5A485F2E806CBC4C21602406034413F9896BF0972F7678D8263845FD123BA9B3604419489CD2BF4254EFD5F87D62A6F88FFF2A4E38F57C9898DD1F7C38C1F548C

拼接高清视频地址

  • 因为我们这个视最清晰只有高清,所以json中的fi字段

    1
    2
    3
    4
    "fi":[
    {"id":100701,"name":"msd","lmt":0,"sb":1,"cname":"标清;(270P)","br":28,"profile":2,"drm":0,"video":1,"audio":1,"fs":16546732,"sl":1},
    {"id":2,"name":"mp4","lmt":0,"sb":1,"cname":"高清;(480P)","br":33,"profile":1,"drm":0,"video":1,"audio":1,"fs":34433483,"sl":0}
    ]
  • 如果有超清清的话,一般会多一个id为10701的数组元素,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        "id":10701,
    "name":"shd",
    "lmt":0,
    "sb":1,
    "cname":"超清;(720P)",
    "br":39,
    "profile":1,
    "drm":0,
    "video":1,
    "audio":1,
    "fs":41560039,
    "sl":0
    }
  • 这时,我们就需要用到 http://vv.video.qq.com/getkey api

  • 首先我们先构造filename=[vids]+.mp4 即 filename=x0164ytbgov.mp4
  • 然后访问:
    1
    2
    http://vv.video.qq.com/getkey?format=2 
    &otype=json&vt=150&vid=x0164ytbgov&ran=0\%2E9477521511726081\\&charge=0&filename=x0164ytbgov.mp4&platform=11

http://vv.video.qq.com/getkey?format=2&otype=json&vt=150&vid=x0164ytbgov&ran=0\%2E9477521511726081\\&charge=0&filename=x0164ytbgov.mp4&platform=11

  • 返回json2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    QZOutputJson=
    {
    "br":62042.312,
    "ct":21600,
    "filename":"x0164ytbgov.mp4",
    "ip":"120.36.254.197",
    "key":"A76112B8282FBD47AE5408A46CBE73D6C3B087688864DAE1C5076726E901E76673A9884A141F398F08A0EB6E9A2C684DA23F92D9A6D0B2787CB108EF75FCD8D7A631A2D40AF2C020392BEE038A662EF1434BF157CAC87218E87A26B65375D06C",
    "keyid":"x0164ytbgov.2",
    "level":0,
    "levelvalid":1,
    "s":"o",
    "sp":0,
    "sr":0
    };
  • 根据这两个json,我们就构造新的连接:
    tempStr[‘vl’][‘vi’][0][‘ul’][‘ui’][0][‘url’]+filename+?vkey=key (key为json2的key),即:

    1
    http://ugcws.video.gtimg.com/x0164ytbgov.mp4?vkey=A76112B8282FBD47AE5408A46CBE73D6C3B087688864DAE1C5076726E901E76673A9884A141F398F08A0EB6E9A2C684DA23F92D9A6D0B2787CB108EF75FCD8D7A631A2D40AF2C020392BEE038A662EF1434BF157CAC87218E87A26B65375D06C

http://ugcws.video.gtimg.com/x0164ytbgov.mp4?vkey=A76112B8282FBD47AE5408A46CBE73D6C3B087688864DAE1C5076726E901E76673A9884A141F398F08A0EB6E9A2C684DA23F92D9A6D0B2787CB108EF75FCD8D7A631A2D40AF2C020392BEE038A662EF1434BF157CAC87218E87A26B65375D06C

  • 这样,我们就获得了高清的视频地址了

拼接超清视频地址

  • 前面说过了额,如果有超清清的话,一般会多一个id为10701的数组元素,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "id":10701,
    "name":"shd",
    "lmt":0,
    "sb":1,
    "cname":"超清;(720P)",
    "br":39,
    "profile":1,
    "drm":0,
    "video":1,
    "audio":1,
    "fs":41560039,
    "sl":0
    }
  • 这时我们构造的filename=x0164ytbgov.p701.1.mp4

  • 此时访问getkey的api就要改为:
    1
    2
    http://vv.video.qq.com/getkey?format=10701 
    &otype=json&vt=150&vid=x0164ytbgov&ran=0\%2E9477521511726081\\&charge=0&filename=x0164ytbgov.p701.1.mp4&platform=11

<http://vv.video.qq.com/getkey?format=10701 &otype=json&vt=150&vid=x0164ytbgov&ran=0\%2E9477521511726081\\&charge=0&filename=x0164ytbgov.p701.1.mp4&platform=11>

  • 聪明的你可能发现了:format={id}
  • 到最后构成真实视频的url:
    tempStr[‘vl’][‘vi’][0][‘ul’][‘ui’][0][‘url’]+filename+?vkey=key (key为json2的key,filename=x0164ytbgov.p701.1.mp4)
  • 由于测试用的视频地址无超清源,所以超清这块的测试需要使用的超清视频做测试。提示已测试可行。

参考文献

  • 腾讯视频爬虫
  • 腾讯视频的地址解析下载
  • 获取腾讯视频真实地址_20180525

答疑

  • 问题:怎么知道defn为清晰度标识并且知道可选值有sd(标清)、hd(高清)、shd(超清)、fhd(1080P)?
    回答:getinfo接口的返回结果中有这个对应关系。此外,也可以推测出来,
    defn是definition的简写;
    sd、hd、shd、fhd分别是standard definition、high definition、super high definition、full high difinition的简写。
------------------------ The End ------------------------

腾讯视频的地址解析下载

发表于 2019-03-03 | 分类于 电脑 , 视频解析
本文字数: 11k | 阅读时长 ≈ 10 分钟

以腾讯视频播放页地址http://v.qq.com/x/cover/rz4mhb6494f12co.html为例,说说如何解析得到视频的真实地址。

提取视频ID

在播放页源码中,可以找到如下视频信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var VIDEO_INFO = {
title: "咱们相爱吧 第1集",
duration: "2746",
vid: "y00221a60w7",
piantou:"0",
pianwei:"0",
showMark:"1",
showBullet:true,
showImageBullet:false,
openBulletDefault:true,
isNeedPay: false,
isTrailer: 0,
singlePrice: "undefined",
vipPrice: "undefined",
tryTime: "1306029",
isTrailer : 0,
type: "2"
};

其中,vid的值y00221a60w7即为视频ID.

请求getinfo接口

使用Chrome浏览器的开发者工具监控网络请求,发现getinfo接口的请求地址如下:

1
http://h5vv.video.qq.com/getinfo?callback=txplayerJsonpCallBack_getinfo_591513&isHLS=false&charge=0&vid=y00221a60w7&defn=hd&defnpayver=1&otype=json&guid=29a06bf3852fbe2ea6eb53829c3878fa&platform=10901&sdtfrom=v1010&host=v.qq.com&_rnd=1479010822&fhdswitch=0&show1080p=1&_qv_rmt=sNk0sWZTA17002uQa%3D&_qv_rmt2=0Qs65I9%2B149182HOQ%3D&_=1479010820769

http://h5vv.video.qq.com/getinfo?callback=txplayerJsonpCallBack_getinfo_591513&isHLS=false&charge=0&vid=y00221a60w7&defn=hd&defnpayver=1&otype=json&guid=29a06bf3852fbe2ea6eb53829c3878fa&platform=10901&sdtfrom=v1010&host=v.qq.com&_rnd=1479010822&fhdswitch=0&show1080p=1&_qv_rmt=sNk0sWZTA17002uQa%3D&_qv_rmt2=0Qs65I9%2B149182HOQ%3D&_=1479010820769
我们尝试构造各个请求参数,然后看看请求结果是什么样子的。

1
2
3
4
5
6
7
8
9
10
11
12
13
params = {
'isHLS': False,
'charge': 0,
'vid': 'y00221a60w7',
'defn': 'shd',
'defnpayver': 1,
'otype': 'json',
'platform': 10901,
'sdtfrom': 'v1010',
'host': 'v.qq.com',
'fhdswitch': 0,
'show1080p': 1,
}

参数中的defn为清晰度标识,可选值有sd(标清)、hd(高清)、shd(超清)、fhd(1080P)。请求结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
{
"dltype": 1,
"exem": 0,
"fl": {
"cnt": 4,
"fi": [
{
"br": 20000,
"cname": "高清;(480P)",
"fs": 239935872,
"id": 10412,
"lmt": 0,
"name": "hd",
"sb": 1,
"sl": 0
},
{
"br": 500000,
"cname": "蓝光;(1080P)",
"fs": 1064110139,
"id": 10409,
"lmt": 1,
"name": "fhd",
"sb": 1,
"sl": 0
},
{
"br": 64,
"cname": "标清;(270P)",
"fs": 114567499,
"id": 10403,
"lmt": 0,
"name": "sd",
"sb": 1,
"sl": 0
},
{
"br": 500000,
"cname": "超清;(720P)",
"fs": 468471925,
"id": 10401,
"lmt": 0,
"name": "shd",
"sb": 1,
"sl": 1
}
]
},
"hs": 0,
"ls": 0,
"preview": 2746,
"s": "o",
"sfl": {
"cnt": 0
},
"tm": 1479014650,
"vl": {
"cnt": 1,
"vi": [
{
"br": 166,
"ch": 0,
"cl": {
"ci": [
{
"cd": "300.032",
"cmd5": "285464ac33c56b14caa63c466d4b4ed3",
"cs": 56516869,
"idx": 1,
"keyid": "y00221a60w7.10401.1"
},
{
"cd": "299.988",
"cmd5": "6a9b0dedeb2ed7c73e5ad31418a9a6bc",
"cs": 56364414,
"idx": 2,
"keyid": "y00221a60w7.10401.2"
},
{
"cd": "299.988",
"cmd5": "2181237427075dc219de8bdaa37ae64d",
"cs": 50213590,
"idx": 3,
"keyid": "y00221a60w7.10401.3"
},
{
"cd": "299.988",
"cmd5": "ac17519a98640a1926f54bc48f5637fb",
"cs": 37593039,
"idx": 4,
"keyid": "y00221a60w7.10401.4"
},
{
"cd": "300.032",
"cmd5": "546963ed0dcb3544373e8642eb2bb166",
"cs": 54082931,
"idx": 5,
"keyid": "y00221a60w7.10401.5"
},
{
"cd": "299.988",
"cmd5": "f33ed88e9b94d4cb1c9c0fb5d3730f76",
"cs": 43686678,
"idx": 6,
"keyid": "y00221a60w7.10401.6"
},
{
"cd": "299.988",
"cmd5": "a6a298f6122de6c09080ae78639c139c",
"cs": 40800986,
"idx": 7,
"keyid": "y00221a60w7.10401.7"
},
{
"cd": "299.988",
"cmd5": "9454b637e3c913ebd1c880ac5e6cf973",
"cs": 62436368,
"idx": 8,
"keyid": "y00221a60w7.10401.8"
},
{
"cd": "346.837",
"cmd5": "0fe50a2165b1ef7860627dbaf672d493",
"cs": 68478324,
"idx": 9,
"keyid": "y00221a60w7.10401.9"
}
],
"fc": 9
},
"ct": 21600,
"drm": 0,
"dsb": 0,
"fclip": 1,
"fmd5": "18f937a9790f22a843e618fb5fd02583",
"fn": "y00221a60w7.p401.mp4",
"fs": 468471925,
"fst": 5,
"fvkey": "88980E6001844B3B7D98195D7077A1EA62310E41BD70C43F57AC6E80AFEB8E9EFD71201CBBB054F2CBFEC5EA8269BB141DB6933322FAA43AD3BB6AA62AD9FE2C2B2A321A639497AA6DF23492CF3B622E41A1C5C75F2DDEC7",
"hevc": 0,
"iflag": 0,
"level": 0,
"lnk": "y00221a60w7",
"logo": 1,
"pl": [
{
"cnt": 2,
"pd": [
{
"c": 10,
"cd": 10,
"fmt": 40001,
"fn": "q1",
"h": 45,
"r": 10,
"url": "http://video.qpic.cn/video_caps/0/",
"w": 80
},
{
"c": 5,
"cd": 10,
"fmt": 40002,
"fn": "q2",
"h": 90,
"r": 5,
"url": "http://video.qpic.cn/video_caps/0/",
"w": 160
}
]
}
],
"share": 1,
"sp": 0,
"st": 2,
"td": "2746.84",
"ti": "咱们相爱吧_01",
"type": 1136,
"ul": {
"ui": [
{
"dt": 2,
"dtc": 10,
"url": "http://124.193.165.208/vlive.qqvideo.tc.qq.com/",
"vt": 203
},
{
"dt": 2,
"dtc": 10,
"url": "http://124.193.165.209/vlive.qqvideo.tc.qq.com/",
"vt": 203
},
{
"dt": 2,
"dtc": 10,
"url": "http://124.193.165.210/vlive.qqvideo.tc.qq.com/",
"vt": 203
},
{
"dt": 2,
"dtc": 10,
"url": "http://video.dispatch.tc.qq.com/27099043/",
"vt": 0
}
]
},
"vh": 720,
"vid": "y00221a60w7",
"videotype": 2,
"vst": 2,
"vw": 1280
}
]
}
}

我们感兴趣的有三个列表:fi列表、ci列表、ui列表。

  • ui列表中的url是视频真实地址的前缀,选择ui列表第一个元素中的url即可。
  • fi列表列出了各个视频码流,每一项中的id是码流的编号,这个参数在后面会用到。
  • ci列表列出了各个分段的相关信息,各个分段信息中的keyid在后面会用到。

请求getkey接口

同样,在网络请求监测中发现getkey接口的请求是这样的:

1
http://h5vv.video.qq.com/getkey?callback=txplayerJsonpCallBack_getkey_931033&&otype=json&vid=y00221a60w7&format=10401&filename=y00221a60w7.p401.4.mp4&platform=10901&vt=203&charge=0&_rnd=1479015483148&_=1479015476641

http://h5vv.video.qq.com/getkey?callback=txplayerJsonpCallBack_getkey_931033&&otype=json&vid=y00221a60w7&format=10401&filename=y00221a60w7.p401.4.mp4&platform=10901&vt=203&charge=0&_rnd=1479015483148&_=1479015476641

构造参数如下:

1
2
3
4
5
6
7
8
9
params = {
'otype': 'json',
'vid': 'y00221a60w7',
'format': 10401,
'filename': 'y00221a60w7.p401.4.mp4',
'platform': 10901,
'vt': 217,
'charge': 0,
}

参数中的vid为视频ID,format为码流的编号,filename根据分段信息中的keyid得来。以第四个分段为例,说说如何构造filename参数。第四个分段信息中的keyid为y00221a60w7.10401.4,我们将keyid中间的.10替换为.p,然后在末尾加上.mp4即可。

getkey接口的请求结果示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"br": 125315.14,
"ct": 21600,
"filename": "y00221a60w7.p401.mp4",
"key": "AE6DC4B022C2A29C59D1A8E942787A2A54F64A5ABFCA7C99B51BD6539703D4F745DD2D77C3433ACAF1961BBFB6D84C1C717D23BEDCAF4DABC0D8BA2229F6C3464F59F0A10C5ED4CC25E355D9171DC65D411D6834BCA2DECD",
"keyid": "y00221a60w7.10401.4",
"level": 0,
"levelvalid": 1,
"s": "o",
"sp": 0,
"sr": 0
}

看!key粗来了。

构造视频真实地址

通过网络监测发现视频真实地址是像这样的:

1
http://60.206.195.15/vlive.qqvideo.tc.qq.com/y00221a60w7.p401.4.mp4?sdtfrom=v1010&guid=29a06bf3852fbe2ea6eb53829c3878fa&vkey=6C5D63159598E6D217BA73F6F3335C0B80CECE2A4E889AFCDD8A391DB9C648059731AE9AD47BDA03B016F76E8B59D9DF0C2373CA32A4ADB935AEE0FE73ECE1C460DC01F6B733A5F38035AC289C44721F606C1ADF5AED4267

http://60.206.195.15/vlive.qqvideo.tc.qq.com/y00221a60w7.p401.4.mp4?sdtfrom=v1010&guid=29a06bf3852fbe2ea6eb53829c3878fa&vkey=6C5D63159598E6D217BA73F6F3335C0B80CECE2A4E889AFCDD8A391DB9C648059731AE9AD47BDA03B016F76E8B59D9DF0C2373CA32A4ADB935AEE0FE73ECE1C460DC01F6B733A5F38035AC289C44721F606C1ADF5AED4267
分析该地址的构造,不难发现,地址前缀在前面的ui列表中已经得到了,filename也计算出来了,vkey参数就是上面得到的key.

Python代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import requests
import json

vid = 'y00221a60w7' # replace with your vid
for definition in ('shd', 'hd', 'sd'):
params = {
'isHLS': False,
'charge': 0,
'vid': vid,
'defn': definition,
'defnpayver': 1,
'otype': 'json',
'platform': 10901,
'sdtfrom': 'v1010',
'host': 'v.qq.com',
'fhdswitch': 0,
'show1080p': 1,
}
r = requests.get('http://h5vv.video.qq.com/getinfo', params=params)
data = json.loads(r.content[len('QZOutputJson='):-1])

url_prefix = data['vl']['vi'][0]['ul']['ui'][0]['url']
for stream in data['fl']['fi']:
if stream['name'] != definition:
continue
stream_id = stream['id']
urls = []
for d in data['vl']['vi'][0]['cl']['ci']:
keyid = d['keyid']
filename = keyid.replace('.10', '.p', 1) + '.mp4'
params = {
'otype': 'json',
'vid': vid,
'format': stream_id,
'filename': filename,
'platform': 10901,
'vt': 217,
'charge': 0,
}
r = requests.get('http://h5vv.video.qq.com/getkey', params=params)
data = json.loads(r.content[len('QZOutputJson='):-1])
url = '%s/%s?sdtfrom=v1010&vkey=%s' % (url_prefix, filename, data['key'])
urls.append(url)

print 'stream:', stream['name']
for url in urls:
print url

参考文献

  • 腾讯视频的地址解析下载(简书,CSDN)
------------------------ The End ------------------------
1234
Junjie Jia

Junjie Jia

生命中的每一步都必须认真对待,把握今天,成就明天!

56 日志
23 分类
30 标签
RSS
© 2019 Junjie Jia | 458k | 6:57
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Gemini v7.0.0
|
0%