在阿里云的服务器上登录淘宝提示 访问被拒绝
提示出错是:
亲,访问被拒绝
可能因为:
请检查是否使用了代理软件或 VPN 哦~
只能说阿里的工程师够懒的(la ji),一刀切,粗暴简单省事.
亲,访问被拒绝
可能因为:
请检查是否使用了代理软件或 VPN 哦~
只能说阿里的工程师够懒的(la ji),一刀切,粗暴简单省事.
导出python自带关键字 keyword
居然还自带这个库
import keyword收起阅读 »
keyword.kwlist
Out[3]:
['False',
'None',
'True',
'and',
'as',
'assert',
'async',
'await',
'break',
'class',
'continue',
'def',
'del',
'elif',
'else',
'except',
'finally',
'for',
'from',
'global',
'if',
'import',
'in',
'is',
'lambda',
'nonlocal',
'not',
'or',
'pass',
'raise',
'return',
'try',
'while',
'with',
'yield']
len(keyword.kwlist)
Out[4]: 35
微信公众号后台的签名校验的官方教程在python3下不兼容
感觉写这个文档的人是个菜鸡。
首先文档用的python2代码写的,但文中没有标明。
python2旧就算了,而且那么多框架不用,还要用一个老掉牙的web.py来写,也是醉了。
django下的签名校验:
原创文章,转载请注明出处http://30daydo.com/article/44121
收起阅读 »
首先文档用的python2代码写的,但文中没有标明。
python2旧就算了,而且那么多框架不用,还要用一个老掉牙的web.py来写,也是醉了。
django下的签名校验:
token = '123456789'
def Services(request):
print(request.method)
if request.method=='GET':
signature = request.GET.get('signature')
echostr = request.GET.get('echostr')
timestamp = request.GET.get('timestamp')
nonce = request.GET.get('nonce')
list_ = [token, timestamp, nonce]
list_.sort()
list_str = ''.join(list_)
sha1 = hashlib.sha1(list_str.encode('utf8'))
hashcode = sha1.hexdigest()
if hashcode==signature:
return HttpResponse(echostr)
else:
return HttpResponse('')
原创文章,转载请注明出处http://30daydo.com/article/44121
收起阅读 »
今晚看了一晚段永平老师的雪球上的问答,颇有感慨
不仅仅是投资,更多的是人生理念。
行字之间,看到一位智者在将他的人生哲学侃侃而谈。 受益匪浅。
可惜的是段老师要关闭问答了,而且就是在上周末,来不及在问答里说一声问候,祝安康。
进度:第6页。
行字之间,看到一位智者在将他的人生哲学侃侃而谈。 受益匪浅。
可惜的是段老师要关闭问答了,而且就是在上周末,来不及在问答里说一声问候,祝安康。
进度:第6页。
不用一行代码 下载雪球嘉年华视频
最近一年一度的雪球嘉年华在深圳举行,曾经去过一次,后来觉得里面都是卖基金,卖私募,后面就没有再去了。
听说今年着重分享一些观念,抱着好奇心,就打算下载几部来看看。
雪球网站很简单,只要找到下载链接就可以下载了。
第一步。打开一个视频播放的页面,比如大金链的
11737544 粉丝主会场 | 巅峰对谈:金牛双子星主动VS量化
https://xueqiu.com/video/5285890810945319765
右键,查看源码,然后在源码里面试着查找 mp4,flv,webp等流媒体字样。
在这里找到一个了:
但是这个视频下载地址有很多转义字符:
直接在浏览器是无法直接打开的。
可以直接替换\u002f 为一个斜杠 \ 就可以了。
如果嫌麻烦,可以在浏览器里面,按下F12,在console页面里面输入上面的地址,前后加个双引号,然后回车,就可以得到完整的地址了。
原创文章,转载请注明出处
http://30daydo.com/article/44119
收起阅读 »
听说今年着重分享一些观念,抱着好奇心,就打算下载几部来看看。
雪球网站很简单,只要找到下载链接就可以下载了。
第一步。打开一个视频播放的页面,比如大金链的
11737544 粉丝主会场 | 巅峰对谈:金牛双子星主动VS量化
https://xueqiu.com/video/5285890810945319765
右键,查看源码,然后在源码里面试着查找 mp4,flv,webp等流媒体字样。
在这里找到一个了:
但是这个视频下载地址有很多转义字符:
http:\u002F\u002F1256122120.vod2.myqcloud.com\u002F53ad1740vodtranscq1256122120\u002F17ebe5145285890810945319765\u002Fv.f20.mp4
直接在浏览器是无法直接打开的。
可以直接替换\u002f 为一个斜杠 \ 就可以了。
如果嫌麻烦,可以在浏览器里面,按下F12,在console页面里面输入上面的地址,前后加个双引号,然后回车,就可以得到完整的地址了。
原创文章,转载请注明出处
http://30daydo.com/article/44119
收起阅读 »
P站 视频下载 JS加密URL 【JS逆向】
P站,你懂的网站,黄黑风格的。
它的真实下载地址是隐藏在JS加密当中的。
接下来我们看看如何找到它的真实地址。
首先随便打开一个视频:
我就找一个python学习的视频(什么鬼,上面还有python学习? 是的有的,还有很多数学题目在上面讲解的呢)
然后按F12
找到一个疑似的下载地址
试下拷贝直接去打开,发现无法打开,显示403 fobiden。
但是看url,应该就是最终的下载url的格式,通过最后的随机数控制播放权限。
然后打开页面的源码
在里面找下有没有一些mp4等的字符, 然后发现有个720p,1080p不同分辨率格式的字段,我们把这个JavaScript的代码扣下来,然后保存为p_hub.js
用vs code 或者其他编辑器打开
看到了他们生成过程了吗?
然后尝试用nodejs运行一下。
什么都没有输出。
因为上面代码并没有任何输出语句,我们在最后加一个 console.log(quality_720p); 就会有输出的了。
看到了吗?
然后拿这个地址去试试,看能否播放和下载。
果然,浏览器里面出现了一个, 额, python学习的页面,一个单独的视频页面,所以可以直接右键,弹出一个保存视频的菜单,然后可以直接下载了。
用代码requesets.get(url) 保存text.content 写入文件,就可以把视频保存到本地了。
源码:
[i]原创文章,
转载请注明出处:
http://30daydo.com/article/44115
[/i]
[i] [/i] 收起阅读 »
它的真实下载地址是隐藏在JS加密当中的。
接下来我们看看如何找到它的真实地址。
首先随便打开一个视频:
我就找一个python学习的视频(什么鬼,上面还有python学习? 是的有的,还有很多数学题目在上面讲解的呢)
然后按F12
找到一个疑似的下载地址
试下拷贝直接去打开,发现无法打开,显示403 fobiden。
但是看url,应该就是最终的下载url的格式,通过最后的随机数控制播放权限。
然后打开页面的源码
在里面找下有没有一些mp4等的字符, 然后发现有个720p,1080p不同分辨率格式的字段,我们把这个JavaScript的代码扣下来,然后保存为p_hub.js
用vs code 或者其他编辑器打开
看到了他们生成过程了吗?
然后尝试用nodejs运行一下。
什么都没有输出。
因为上面代码并没有任何输出语句,我们在最后加一个 console.log(quality_720p); 就会有输出的了。
看到了吗?
然后拿这个地址去试试,看能否播放和下载。
果然,浏览器里面出现了一个, 额, python学习的页面,一个单独的视频页面,所以可以直接右键,弹出一个保存视频的菜单,然后可以直接下载了。
用代码requesets.get(url) 保存text.content 写入文件,就可以把视频保存到本地了。
源码:
#!/usr/bin/env python
# http://30daydo.com
import os
import re
import js2py
import requests
from lxml import etree
from clint.textui import progress
import fire
from loguru import logger
file='crawler'
logger.add(
"logs/%s.log" % file,
format="{time:MM-DD HH:mm:ss} {level} {message}",
)
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
}
proxies = {}
# 如果代理不稳定,不推荐使用
# local proxy service
# proxies example:
# proxies = {
# "http": "socks5://127.0.0.1:1080",
# "https": "socks5://127.0.0.1:1080",
# }
def list_page(url):
logger.info("crawling : %s" % url)
resp = requests.get(url, headers=headers, proxies=proxies, verify=False)
html = etree.HTML(resp.text)
buff = '//*[@class="phimage"]/a/'
names = html.xpath(f"{buff}@href")
urls = html.xpath(f"{buff}img/@data-mediabook")
for i in range(len(urls)):
try:
url = urls
[i] name = re.findall("=ph(\w+)", names[i])[-1]
logger.info(f"{url} {name}")
download(url, name, "webm")
except Exception as err:
logger.error(err)
def detail_page(url):
s = requests.Session()
resp = s.get(url, headers=headers, proxies=proxies, verify=False)
html = etree.HTML(resp.content)
title = "".join(html.xpath("//h1//text()")).strip()
logger.info(title)
js_temp = html.xpath("//script/text()")
for j in js_temp:
if "flashvars" in j:
videoUrl = exeJs(j)
download(videoUrl, title, "mp4")
continue
def exeJs(js):
flashvars = re.findall("flashvars_\d+", js)[0]
js = "\n\t".join(js.split("\n\t")[:-5]).strip()
js = js.replace("// var nextVideoObject = flashvars_['nextVideo'];",'')
js+=flashvars
res = js2py.eval_js(js)
if res.quality_720p:
return res.quality_720p
elif res.quality_480p:
return res.quality_480p
elif res.quality_240p:
return res.quality_240p
else:
logger.error("parse url error")
def download(url, name, filetype):
logger.info(f"{url} {name} {filetype}")
filepath = "%s/%s.%s" % (filetype, name, filetype)
if os.path.exists(filepath):
logger.info("this file had been downloaded :: %s" % filepath)
return
else:
response = requests.get(url, headers=headers, proxies=proxies, stream=True)
with open(filepath, "wb") as file:
total_length = int(response.headers.get("content-length"))
for ch in progress.bar(
response.iter_content(chunk_size=2391975),
expected_size=(total_length / 1024) + 1,
):
if ch:
file.write(ch)
logger.info("download success :: %s" % filepath)
def run(_arg=None):
paths = ["webm", "mp4"]
for path in paths:
if not os.path.exists(path):
os.mkdir(path)
if _arg == "webm":
# https://www.pornhub.com/categories
urls = [
# "https://www.pornhub.com/video?o=tr",
# "https://www.pornhub.com/video?o=ht",
# "https://www.pornhub.com/video?o=mv",
"https://www.pornhub.com/video",
]
for url in urls:
list_page(url)
elif _arg == "mp4":
with open("download.txt", "r") as file:
keys = list(set(file.readlines()))
logger.info(keys)
keys += [d.strip(".webm") for d in os.listdir("webm/")]
for key in keys:
if not key.strip():
continue
url = "https://www.pornhub.com/view_v ... ot%3B % key.strip()
logger.info("url: {}", url)
detail_page(url)
else:
_str = """
tips:
python crawler.py webm
- 下载热门页面的缩略图,路径为webm文件夹下
python crawler.py mp4
- 该命令会下载webm文件下对应的mp4文件
- 也可以将目标地址写入download.txt中
"""
logger.info(_str)
return
logger.info("finish !")
if __name__ == "__main__":
fire.Fire(run)
[/i][/i]
[i]原创文章,
转载请注明出处:
http://30daydo.com/article/44115
[/i]
[i] [/i] 收起阅读 »
python执行js语句,无函数返回值
有时候在JS代码里面抠出部分语句,但是不是一个函数。
如下面的一段JS
做了很多的运算,掩人耳目,虽然看多几下,用python写也简单,或者把它放入一个function里面也可以。
比如实时网络上下载获取一段js,然后再在头部和尾部组装为function。
function getValue(){
xxxxxx
xxxxxx
return flashvars_324075351
}
然后执行这一段JS,call返回函数 getValue() 就可以拿到返回值了。
不过今天我们用其他的方法直接获取flashvars_324075351
使用jsp库即可。
把上面的JS语句
后面加一个返回值,但不需要加return
比如
然后直接调用jspy
res = js2py.eval_js(js)
执行后print(res) , 显示的值就是flashvars_324075351
原创文章,转载请注明出处
http://30daydo.com/article/44112
收起阅读 »
如下面的一段JS
var radra27radra27 = "D";
var ra72419ra91ra72419ra91 = "7.241.9" + ".";
var raurst500ra63raurst500ra63 = "urst=500";
var ravalidtora49ravalidtora49 = "validto=";
var raevphncdra57raevphncdra57 = "ev.ph" + "ncd";
var ra16067161ra17ra16067161ra17 = "16067161";
var radeos202ra16radeos202ra16 = "deos/20" + "2";
var ra1080p4ra73ra1080p4ra73 = "/1080P_4";
var ra209hashra72ra209hashra72 = "209&hash";
var ra2bmkdz7nra36ra2bmkdz7nra36 = "2BMKd" + "z7N";
var ra6708909ra29ra6708909ra29 = "6708909" + "&";
var ra00kip4ra41ra00kip4ra41 = "00k&i" + "p=4";
var ra006163ra73ra006163ra73 = "006/16/" + "3";
var raro7upu3ra66raro7upu3ra66 = "Ro7UPU%3";
var raroiu6qra26raroiu6qra26 = "=rOiU6q%";
var ra075351mra26ra075351mra26 = "075351." + "m";
var ramgdmctbvra11ramgdmctbvra11 = "MgdmCtbV";
var rap4validra25rap4validra25 = "p4?valid";
var ra09ratera79ra09ratera79 = "09&rate=";
var rancomvira35rancomvira35 = "n.com/vi";
var ra24075351ra94ra24075351ra94 = "24075" + "351";
var ra000k324ra70ra000k324ra70 = "000K_324";
var ra50000kbra49ra50000kbra49 = "50000k&" + "b";
var rahttpsra83rahttpsra83 = "https://";
var rafrom160ra56rafrom160ra56 = "from=16" + "0";
var quality_1080p =/* + radra27radra27 + */rahttpsra83rahttpsra83 + /* + rancomvira35rancomvira35 + */raevphncdra57raevphncdra57 + /* + radra27radra27 + */rancomvira35rancomvira35 + /* + ra006163ra73ra006163ra73 + */radeos202ra16radeos202ra16 + /* + ra09ratera79ra09ratera79 + */ra006163ra73ra006163ra73 + /* + ra1080p4ra73ra1080p4ra73 + */ra24075351ra94ra24075351ra94 + /* + raroiu6qra26raroiu6qra26 + */ra1080p4ra73ra1080p4ra73 + /* + ra000k324ra70ra000k324ra70 + */ra000k324ra70ra000k324ra70 + /* + rancomvira35rancomvira35 + */ra075351mra26ra075351mra26 + /* + ravalidtora49ravalidtora49 + */rap4validra25rap4validra25 + /* + ra209hashra72ra209hashra72 + */rafrom160ra56rafrom160ra56 + /* + ra1080p4ra73ra1080p4ra73 + */ra6708909ra29ra6708909ra29 + /* + ra209hashra72ra209hashra72 + */ravalidtora49ravalidtora49 + /* + ramgdmctbvra11ramgdmctbvra11 + */ra16067161ra17ra16067161ra17 + /* + ra24075351ra94ra24075351ra94 + */ra09ratera79ra09ratera79 + /* + ra50000kbra49ra50000kbra49 + */ra50000kbra49ra50000kbra49 + /* + ramgdmctbvra11ramgdmctbvra11 + */raurst500ra63raurst500ra63 + /* + ra209hashra72ra209hashra72 + */ra00kip4ra41ra00kip4ra41 + /* + raroiu6qra26raroiu6qra26 + */ra72419ra91ra72419ra91 + /* + ra09ratera79ra09ratera79 + */ra209hashra72ra209hashra72 + /* + raro7upu3ra66raro7upu3ra66 + */raroiu6qra26raroiu6qra26 + /* + ra075351mra26ra075351mra26 + */ra2bmkdz7nra36ra2bmkdz7nra36 + /* + ra50000kbra49ra50000kbra49 + */ramgdmctbvra11ramgdmctbvra11 + /* + radeos202ra16radeos202ra16 + */raro7upu3ra66raro7upu3ra66 + /* + ra075351mra26ra075351mra26 + */radra27radra27;
flashvars_324075351["quality_1080p"] = quality_1080p;
做了很多的运算,掩人耳目,虽然看多几下,用python写也简单,或者把它放入一个function里面也可以。
比如实时网络上下载获取一段js,然后再在头部和尾部组装为function。
function getValue(){
xxxxxx
xxxxxx
return flashvars_324075351
}
然后执行这一段JS,call返回函数 getValue() 就可以拿到返回值了。
不过今天我们用其他的方法直接获取flashvars_324075351
使用jsp库即可。
把上面的JS语句
var radra27radra27 = "D";
var ra72419ra91ra72419ra91 = "7.241.9" + ".";
var raurst500ra63raurst500ra63 = "urst=500";
var ravalidtora49ravalidtora49 = "validto=";
var raevphncdra57raevphncdra57 = "ev.ph" + "ncd";
var ra16067161ra17ra16067161ra17 = "16067161";
var radeos202ra16radeos202ra16 = "deos/20" + "2";
var ra1080p4ra73ra1080p4ra73 = "/1080P_4";
var ra209hashra72ra209hashra72 = "209&hash";
var ra2bmkdz7nra36ra2bmkdz7nra36 = "2BMKd" + "z7N";
var ra6708909ra29ra6708909ra29 = "6708909" + "&";
var ra00kip4ra41ra00kip4ra41 = "00k&i" + "p=4";
var ra006163ra73ra006163ra73 = "006/16/" + "3";
var raro7upu3ra66raro7upu3ra66 = "Ro7UPU%3";
var raroiu6qra26raroiu6qra26 = "=rOiU6q%";
var ra075351mra26ra075351mra26 = "075351." + "m";
var ramgdmctbvra11ramgdmctbvra11 = "MgdmCtbV";
var rap4validra25rap4validra25 = "p4?valid";
var ra09ratera79ra09ratera79 = "09&rate=";
var rancomvira35rancomvira35 = "n.com/vi";
var ra24075351ra94ra24075351ra94 = "24075" + "351";
var ra000k324ra70ra000k324ra70 = "000K_324";
var ra50000kbra49ra50000kbra49 = "50000k&" + "b";
var rahttpsra83rahttpsra83 = "https://";
var rafrom160ra56rafrom160ra56 = "from=16" + "0";
var quality_1080p =/* + radra27radra27 + */rahttpsra83rahttpsra83 + /* + rancomvira35rancomvira35 + */raevphncdra57raevphncdra57 + /* + radra27radra27 + */rancomvira35rancomvira35 + /* + ra006163ra73ra006163ra73 + */radeos202ra16radeos202ra16 + /* + ra09ratera79ra09ratera79 + */ra006163ra73ra006163ra73 + /* + ra1080p4ra73ra1080p4ra73 + */ra24075351ra94ra24075351ra94 + /* + raroiu6qra26raroiu6qra26 + */ra1080p4ra73ra1080p4ra73 + /* + ra000k324ra70ra000k324ra70 + */ra000k324ra70ra000k324ra70 + /* + rancomvira35rancomvira35 + */ra075351mra26ra075351mra26 + /* + ravalidtora49ravalidtora49 + */rap4validra25rap4validra25 + /* + ra209hashra72ra209hashra72 + */rafrom160ra56rafrom160ra56 + /* + ra1080p4ra73ra1080p4ra73 + */ra6708909ra29ra6708909ra29 + /* + ra209hashra72ra209hashra72 + */ravalidtora49ravalidtora49 + /* + ramgdmctbvra11ramgdmctbvra11 + */ra16067161ra17ra16067161ra17 + /* + ra24075351ra94ra24075351ra94 + */ra09ratera79ra09ratera79 + /* + ra50000kbra49ra50000kbra49 + */ra50000kbra49ra50000kbra49 + /* + ramgdmctbvra11ramgdmctbvra11 + */raurst500ra63raurst500ra63 + /* + ra209hashra72ra209hashra72 + */ra00kip4ra41ra00kip4ra41 + /* + raroiu6qra26raroiu6qra26 + */ra72419ra91ra72419ra91 + /* + ra09ratera79ra09ratera79 + */ra209hashra72ra209hashra72 + /* + raro7upu3ra66raro7upu3ra66 + */raroiu6qra26raroiu6qra26 + /* + ra075351mra26ra075351mra26 + */ra2bmkdz7nra36ra2bmkdz7nra36 + /* + ra50000kbra49ra50000kbra49 + */ramgdmctbvra11ramgdmctbvra11 + /* + radeos202ra16radeos202ra16 + */raro7upu3ra66raro7upu3ra66 + /* + ra075351mra26ra075351mra26 + */radra27radra27;
flashvars_324075351["quality_1080p"] = quality_1080p;
后面加一个返回值,但不需要加return
比如
....
ra50000kbra49ra50000kbra49 + */ramgdmctbvra11ramgdmctbvra11 + /* + radeos202ra16radeos202ra16 + */raro7upu3ra66raro7upu3ra66 + /* + ra075351mra26ra075351mra26 + */radra27radra27;
flashvars_324075351["quality_1080p"] = quality_1080p;
flashvars_324075351;
然后直接调用jspy
res = js2py.eval_js(js)
执行后print(res) , 显示的值就是flashvars_324075351
原创文章,转载请注明出处
http://30daydo.com/article/44112
收起阅读 »
简单快速下载知乎视频
现在的知乎也有视频内容,目前看来没有任何反爬措施。可以简单通过以下方式用浏览器下载:
1. 打开视频前按F12
2. 播放视频
3. 查看F12的网络选项
4. 找到 https://vdn3.vzuu.com 的url
5. 对应的整个url链接就是视频的真实下载地址。把url复制到浏览器打开,然后右键另存为本地视频就可以了
收起阅读 »
1. 打开视频前按F12
2. 播放视频
3. 查看F12的网络选项
4. 找到 https://vdn3.vzuu.com 的url
5. 对应的整个url链接就是视频的真实下载地址。把url复制到浏览器打开,然后右键另存为本地视频就可以了
收起阅读 »
集思录用户名密码JS加密流程解密 【JS加密破解教程一】
之前帮他人部署的一个集思录爬取的程序,忽然获取的数据不一样了。 查看日志后发现,现在的登录用户名和密码做了一层加密后再post提交。
而且提交的内容每次都固定,第一种最傻的方式就是每次提交就把加密的用户名和密码提交上去。
当然,对于有钻研的读者,可能想看看其具体的加密方式。
那么就按照流程,通过断点与搜索,找到其加密方法。
首先在上面的截图中很明显就知道,这个字符加密应该是aes,因为它的提交字段中aes:1
按F12,走完整个登录流程。
然后搜索password字样的地方。
在index.html首页中找到一处:
然后在该password的地方打个断点,然后跳转到jslencode 的地方。
跳转到的地方是这里。
然后我们浏览一下这个JS页面,尝试把整个JS代码抠出来。
放到我们的调试软件中,比较常用的是鬼鬼JS调试器。(有需要的可以关注wx公众号下载:回复 鬼鬼JS 即可)
这个调试器的好处是,可以很方便格式化JS代码,然后输入你要调试的字符,然后点击运行,可以当场拿到结果,等到结果ok了的话,就可以用python 的pyexecjs执行。
先点击代码格式化,然后在输入框里找到函数的入口:
jslencode(text, aes_key),好了,现在就把我们的密码 XXXXXX,和aes_key 放进去就可以了。
aes_key 在之前的index.html就能找到。
var A397151C04723421F = '397151C04723421F';
jslencode(‘jisilupassword’, '397151C04723421F')
右下角有个系统引擎运行。
得到结果:
1d1bd2b22b8cc5c09ad8ce8f1e69b87f
对比一下第一张图里面的的post请求,发现是一样的。那么现在的JS解密就成功了一大半了。 接着我们就写python代码执行这段JS脚本。
尝试直接把JS放到一个文件,然后编写python代码
然后发现报错: 说CryptoJS没有定义,那么我们看看代码。
发现这一行此时CryptoJS的定义
var CryptoJS = CryptoJS || (function(Math, undefined) { var create = Object.create || (function() {
那么我们把这一行上面的全部删除。最后的调试后,能够执行的JS代码如下,并保存为 集思录.js 文件,调用上面的python文件。
集思录.js
源文件地址:
对比一下鬼鬼JS调试器的结果,一样的。
OK,手工。
这里汇聚了平时整理的JS破解工作流,大家可以参考参考。
https://github.com/Rockyzsu/JS-Reverse
原创文章,转载请注明出处:
http://30daydo.com/article/44109
喜欢的朋友可以加入星球探讨:
收起阅读 »
而且提交的内容每次都固定,第一种最傻的方式就是每次提交就把加密的用户名和密码提交上去。
当然,对于有钻研的读者,可能想看看其具体的加密方式。
那么就按照流程,通过断点与搜索,找到其加密方法。
首先在上面的截图中很明显就知道,这个字符加密应该是aes,因为它的提交字段中aes:1
按F12,走完整个登录流程。
然后搜索password字样的地方。
在index.html首页中找到一处:
然后在该password的地方打个断点,然后跳转到jslencode 的地方。
跳转到的地方是这里。
然后我们浏览一下这个JS页面,尝试把整个JS代码抠出来。
放到我们的调试软件中,比较常用的是鬼鬼JS调试器。(有需要的可以关注wx公众号下载:回复 鬼鬼JS 即可)
这个调试器的好处是,可以很方便格式化JS代码,然后输入你要调试的字符,然后点击运行,可以当场拿到结果,等到结果ok了的话,就可以用python 的pyexecjs执行。
先点击代码格式化,然后在输入框里找到函数的入口:
jslencode(text, aes_key),好了,现在就把我们的密码 XXXXXX,和aes_key 放进去就可以了。
aes_key 在之前的index.html就能找到。
var A397151C04723421F = '397151C04723421F';
function doLogin(){
var data = $('#login_form').serializeObjectToJson();
data['_post_type'] = 'ajax';
data['aes'] = 1;
data['user_name'] = jslencode(data['user_name'], A397151C04723421F);
data['password'] = jslencode(data['password'], A397151C04723421F);
$.post('/account/ajax/login_process/', data, function(rst){
on_login_error_processer(rst);
}, 'json');
var A397151C04723421F = '397151C04723421F';
jslencode(‘jisilupassword’, '397151C04723421F')
右下角有个系统引擎运行。
得到结果:
1d1bd2b22b8cc5c09ad8ce8f1e69b87f
对比一下第一张图里面的的post请求,发现是一样的。那么现在的JS解密就成功了一大半了。 接着我们就写python代码执行这段JS脚本。
尝试直接把JS放到一个文件,然后编写python代码
# -*- coding: utf-8 -*-
# @Time : 2020/11/27 12:15
# @File : js_executor.py
# @Author : Rocky C@www.30daydo.com
import execjs
def main():
encode_user = ctx.call('jslencode', user, key)
encode_password = ctx.call('jslencode', password, key)
print(encode_user)
print(encode_password)
if __name__ == '__main__':
main()
然后发现报错: 说CryptoJS没有定义,那么我们看看代码。
(function(root, factory) {
if (typeof exports === "object") {
module.exports = exports = factory()
} else {
if (typeof define === "function" && define.amd) {
define(, factory)
} else {
root.CryptoJS = factory()
}
}
}(this, function() {
var CryptoJS = CryptoJS || (function(Math, undefined) {
var create = Object.create || (function() {
发现这一行此时CryptoJS的定义
var CryptoJS = CryptoJS || (function(Math, undefined) { var create = Object.create || (function() {
那么我们把这一行上面的全部删除。最后的调试后,能够执行的JS代码如下,并保存为 集思录.js 文件,调用上面的python文件。
集思录.js
var CryptoJS = CryptoJS || (function(Math, undefined) {下面的就跟上面的一模一样了:
var create = Object.create || (function() {
function F() {}
return function(obj) {
var subtype;
F.prototype = obj;
subtype = new F();
F.prototype = null;
return subtype
}
}());
var C = {};
var C_lib = C.lib = {};
var Base = C_lib.Base = (function() {
源文件地址:
https://www.jisilu.cn/static/js/crypto-js-3.3.0-min.js然后python运行后得到加密后的aes数据。
对比一下鬼鬼JS调试器的结果,一样的。
OK,手工。
这里汇聚了平时整理的JS破解工作流,大家可以参考参考。
https://github.com/Rockyzsu/JS-Reverse
原创文章,转载请注明出处:
http://30daydo.com/article/44109
喜欢的朋友可以加入星球探讨:
收起阅读 »
效率流工具 推荐
首先一点,在很多场合下,使用键盘的效率要远远高于鼠标。 所以最快的工作流是使用键盘去控制。
如果没有体会,说明你没有用过vim。 操控+控制使用键盘操作,浑然天成。 虽然有位大佬推荐我用emacs,可是学习成本过于高昂,一直学不会。
那么在windows平台下推荐几款 工作流 软件。
1. vimium
啥,又是vim ? 不, 这是一款在浏览器上模拟vim操作的软件。 比如滚动到底部,GG, 滚动到顶部 gg,
上下左右移动hjkl,如果不是经常用vim的朋友可能会觉得特别别扭。
大写的JK 前后滚动tab
b 打开书签,打开常用的网站
2. listary + everything
打开程序+搜索文件
可以按2下ctrl,然后输入程序的快捷方式名称,就马上可以启动程序
3.
收起阅读 »
如果没有体会,说明你没有用过vim。 操控+控制使用键盘操作,浑然天成。 虽然有位大佬推荐我用emacs,可是学习成本过于高昂,一直学不会。
那么在windows平台下推荐几款 工作流 软件。
1. vimium
啥,又是vim ? 不, 这是一款在浏览器上模拟vim操作的软件。 比如滚动到底部,GG, 滚动到顶部 gg,
上下左右移动hjkl,如果不是经常用vim的朋友可能会觉得特别别扭。
大写的JK 前后滚动tab
b 打开书签,打开常用的网站
2. listary + everything
打开程序+搜索文件
可以按2下ctrl,然后输入程序的快捷方式名称,就马上可以启动程序
3.
收起阅读 »
python多重继承的super调用父类的兄弟类
先看一段代码:
看输出的是什么:
为什么不输出C init ?
那么这个药从super的函数实现说起:
super函数中,mro_list得到的是类的mro列表,mro列表就是类的继承有序关系图
比如上面代码中
C, B, A 在D中的mro是下面这样的。
你提供的类名class传入来后,比如是C,那么找到C所在的index,然后加1后的class,也就是B,所以super(C,self).__init__()
实际调用的是B.__init__()
另外,如果在多重继承中,要调用父类的父类的父类。。。。,
可以直接用改类的类名就可以
结果:
其实super和父类子类没什么关系, super关系的是mro里面的顺序。
原文链接:http://30daydo.com/article/44107
转载请注明出处
收起阅读 »
class A:
def __init__(self):
print('A init')
print(self)
class B:
def __init__(self):
print('B init')
print(self)
class C:
def __init__(self):
print('C init')
print(self)
class D(C, B, A):
def __init__(self):
super(A, self).__init__()
super(C, self).__init__()
super(B, self).__init__()
print('D ')
def main():
d = D()
看输出的是什么:
B init
<__main__.D object at 0x00000000026365B0>
A init
<__main__.D object at 0x00000000026365B0>
D init-
为什么不输出C init ?
那么这个药从super的函数实现说起:
def super(class, obj):
mro_list = obj.__class__.mro()
next_parent_class = mro_list[mro_list.index(class)+1]
return next_parent_class
super函数中,mro_list得到的是类的mro列表,mro列表就是类的继承有序关系图
比如上面代码中
C, B, A 在D中的mro是下面这样的。
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
你提供的类名class传入来后,比如是C,那么找到C所在的index,然后加1后的class,也就是B,所以super(C,self).__init__()
实际调用的是B.__init__()
另外,如果在多重继承中,要调用父类的父类的父类。。。。,
可以直接用改类的类名就可以
# 多重继承
class A:
def __init__(self):
print('A init')
print(self)
def fun(self):
print('A',self)
class B(A):
def __init__(self):
print('B init')
print(self)
def fun(self):
print('B', self)
class C(B):
def __init__(self):
print('C init')
print(self)
def fun(self):
print('C', self)
class X:
def fun(self):
print('X',self)
class D(C):
def __init__(self):
# super(B, self).__init__() # super(D) -> 指向了C
print('D init')
def fun(self):
C.fun(self)
B.fun(self)
A.fun(self)
X.fun(self)
def main():
d = D()
print(d.__class__.mro())
d.fun()
if __name__ == '__main__':
main()
结果:
D init
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
C <__main__.D object at 0x00000000025F6700>
B <__main__.D object at 0x00000000025F6700>
A <__main__.D object at 0x00000000025F6700>
X <__main__.D object at 0x00000000025F6700>
其实super和父类子类没什么关系, super关系的是mro里面的顺序。
原文链接:http://30daydo.com/article/44107
转载请注明出处
收起阅读 »
python pathspec 库的作用
作为路径匹配用的。
看以下实例:
gitignore文件里面的内容就会被匹配到
看以下实例:
def get_ignore_matches():
# 排除文件
global ignore_matches
ignore_file = os.path.join(os.path.abspath(os.curdir), '.gitignore')
if not os.path.exists(ignore_file):
return None
if ignore_matches is not None:
return ignore_matches
with open(ignore_file, 'r') as fh:
spec = pathspec.PathSpec.from_lines('gitwildmatch', fh)
ignore_matches = spec
return ignore_matches
def is_ignored(file_name: str) -> bool:
# 匹配就ignore
matches = get_ignore_matches()
if matches is None:
return False
return matches.match_file(file_name)
gitignore文件里面的内容就会被匹配到
.idea/收起阅读 »
build/
dist/
venv/
*.pyc
__pycache__/
*.egg-info/
tmp/
asyncio 异步爬取vs requests同步爬取 性能对比
首先是异步爬取:
爬完并且入库,用时大约为35s
使用requests爬取
所以单从网络IO性能上来说,异步是比纯同步要快很多。
但是,async的生态做得不是太好,第三方的异步框架做得也不够完善。
因为如果系统中引入了异步,很多耗时的地方也是需要使用异步的写法和框架,不然会导致系统的控制权没有被正确转移。
水文一篇。
完毕
收起阅读 »
import sys
sys.path.append('..')
import asyncio
import datetime
import aiohttp
import re
import time
from parsel import Selector
from configure.settings import DBSelector
from common.BaseService import BaseService
SLEEP = 2
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}
URL_MAP = {'home_page': 'https://holdle.com/stocks/industry', 'base': 'https://holdle.com'}
class AsyncMongo():
def __init__(self):
self.DB = DBSelector()
self.client = self.DB.mongo(location_type='qq', async_type=True)
self.db = self.client['db_stock']
async def update(self, table,data):
self.doc= self.db[table]
await self.doc.insert_many(data)
class Holdle(BaseService):
def __init__(self):
super(Holdle, self).__init__()
self.data_processor = AsyncMongo()
self.tables_list =['ROE','Cash_Ratio','Gross_Margin','Operation_Margin','Net_Profit_Ratio','Dividend_ratio']
async def home_page(self):
start = time.time()
async with aiohttp.ClientSession() as session:
async with session.get(url=URL_MAP['home_page'], headers=headers) as response:
html = await response.text() # 这个阻塞
resp = Selector(text=html)
industries = resp.xpath('//ul[@class="list-unstyled"]/a')
task_list = []
for industry in industries:
json_data = {}
industry_url = industry.xpath('.//@href').extract_first()
industry_name = industry.xpath('.//li/text()').extract_first()
industry_name = industry_name.replace('-', '').strip()
json_data['industry_url'] = industry_url
json_data['industry_name'] = industry_name
task = asyncio.ensure_future(self.detail_list(session, industry_url, json_data))
task_list.append(task)
await asyncio.gather(*task_list)
end = time.time()
print(f'time used {end - start}')
async def detail_list(self, session, url, json_data):
async with session.get(URL_MAP['base'] + url, headers=headers) as response:
response = await response.text()
await self.parse_detail(response, json_data)
async def parse_detail(self, html, json_data=None):
resp = Selector(text=html)
industry=json_data['industry_name']
tables = resp.xpath('//table[@class="table table-bordered"]')
if len(tables)!=6:
raise ValueError
for index,table in enumerate(self.tables_list):
rows = tables[index].xpath('.//tr')
result = []
for row in rows[1:]:
stock_name = row.xpath('.//td[1]/text()').extract_first()
value = row.xpath('.//td[2]/text()').extract_first()
value = float(value)
d={'industry':industry,'name':stock_name,'value':value,'crawltime':datetime.datetime.now()}
result.append(d)
await self.data_processor.update(table,result)
app = Holdle()
loop = asyncio.get_event_loop()
loop.run_until_complete(app.home_page())
爬完并且入库,用时大约为35s
使用requests爬取
# -*- coding: utf-8 -*-用时约160s,而且这里还省略了mongo入库的时间。上面异步爬取里面包含了异步存入mongo。
# @Time : 2020/11/24 21:42
# @File : sync_spider.py
# @Author : Rocky C@www.30daydo.com
import requests
import sys
sys.path.append('..')
import asyncio
import datetime
import aiohttp
import re
import time
from parsel import Selector
from configure.settings import DBSelector
from common.BaseService import BaseService
SLEEP = 2
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}
URL_MAP = {'home_page': 'https://holdle.com/stocks/industry', 'base': 'https://holdle.com'}
class Holdle(BaseService):
def __init__(self):
super(Holdle, self).__init__()
self.DB = DBSelector()
self.client = self.DB.mongo(location_type='qq', async_type=True)
self.session = requests.Session()
def run(self):
start = time.time()
response = self.session.get(url=URL_MAP['home_page'], headers=headers)
html = response.text # 这个阻塞
resp = Selector(text=html)
industries = resp.xpath('//ul[@class="list-unstyled"]/a')
for industry in industries:
json_data = {}
industry_url = industry.xpath('.//@href').extract_first()
industry_name = industry.xpath('.//li/text()').extract_first()
json_data['industry_url'] = industry_url
json_data['industry_name'] = industry_name
self.detail_list(industry_url, json_data)
end = time.time()
print(f'time used {end-start}')
def detail_list(self, url, json_data):
response = self.session.get(URL_MAP['base']+url, headers=headers)
response =response.text
self.parse_detail(response, json_data)
def parse_detail(self, html, json_data=None):
resp = Selector(text=html)
title =resp.xpath('//title/text()').extract_first()
print(title)
app = Holdle()
app.run()
所以单从网络IO性能上来说,异步是比纯同步要快很多。
但是,async的生态做得不是太好,第三方的异步框架做得也不够完善。
因为如果系统中引入了异步,很多耗时的地方也是需要使用异步的写法和框架,不然会导致系统的控制权没有被正确转移。
水文一篇。
完毕
收起阅读 »
【转载】现在都 2020 年了,普通人想好好维个权,太难了。
原文:
https://www.v2ex.com/t/728599#reply0
这几天在 v2 里看到租房子被商机割韭菜的,健身房跑路的,还有近期发生在自己身上的一些事情,发现维权真的太难了。当真有事情发生你自己在头上时,你连去哪里投诉解决这个事情的渠道都没有。
为了以后会有更多人上当受骗,我把自己案例写上来,希望大家别重蹈覆辙。哪怕增加一个 SEO 也 OK 了。
这家机构叫:环球网校 公司主体 北京环球兴学科技发展有限公司 地址北京海淀区中关村南大街甲 18 号
我 11 月在这家机构缴费健康管理师,说报名 4 月考试,说的时候就告知这个是报名费,没有告知是课程费。
第二天我打客服要求退书费,我问客服 4 月份我是不是已经报上名了,客服说这个不是报名费是课程的费用,我想着 4 月份还不一定能报上,也没时间学习就跟销售申请退费了,销售说帮我申请了,后来我打客服,客服这边根本没有退费申请,现在给我开通的课程已经给我关闭了,我的课程也无法正常上课的,也不给退费,如果需要上课就需要签署协议,对于甲方来说是非常不利的协议,我不同意要求退费,这家公司就是不愿意退款,这家公司的销售就是最大的骗子,两个工号都不给的,问他工号,还问你上午中午下午,难道上中下的工号还是不一样的,最后还是不给工号。这家公司就是骗子公司,千万不要报名。
我现在的状态就是课程无法进去,一定要我签署协议,我不同意协议,客服和销售就说反正钱已经交了,你要上课协议就点同意,不想上钱也退不了。找客服,找销售,都是敷衍你。
第一承诺 4 月的名已经报上了,后来说这个是课程费,不是报名费。
第二,销售人员连工号都不给,无法保障消费者的利益。
第三,班主任现在也找不到人。第四多次联系客服,客服人员的说法不一致。
第五综合以上所有问题,我被坑了,无法信任次公司,绝对要求退款。
如果报了名的赶紧打客服要求退费,在打 010-12345 市长反应。
转载程序员的一个贴。
收起阅读 »
https://www.v2ex.com/t/728599#reply0
这几天在 v2 里看到租房子被商机割韭菜的,健身房跑路的,还有近期发生在自己身上的一些事情,发现维权真的太难了。当真有事情发生你自己在头上时,你连去哪里投诉解决这个事情的渠道都没有。
为了以后会有更多人上当受骗,我把自己案例写上来,希望大家别重蹈覆辙。哪怕增加一个 SEO 也 OK 了。
这家机构叫:环球网校 公司主体 北京环球兴学科技发展有限公司 地址北京海淀区中关村南大街甲 18 号
我 11 月在这家机构缴费健康管理师,说报名 4 月考试,说的时候就告知这个是报名费,没有告知是课程费。
第二天我打客服要求退书费,我问客服 4 月份我是不是已经报上名了,客服说这个不是报名费是课程的费用,我想着 4 月份还不一定能报上,也没时间学习就跟销售申请退费了,销售说帮我申请了,后来我打客服,客服这边根本没有退费申请,现在给我开通的课程已经给我关闭了,我的课程也无法正常上课的,也不给退费,如果需要上课就需要签署协议,对于甲方来说是非常不利的协议,我不同意要求退费,这家公司就是不愿意退款,这家公司的销售就是最大的骗子,两个工号都不给的,问他工号,还问你上午中午下午,难道上中下的工号还是不一样的,最后还是不给工号。这家公司就是骗子公司,千万不要报名。
我现在的状态就是课程无法进去,一定要我签署协议,我不同意协议,客服和销售就说反正钱已经交了,你要上课协议就点同意,不想上钱也退不了。找客服,找销售,都是敷衍你。
第一承诺 4 月的名已经报上了,后来说这个是课程费,不是报名费。
第二,销售人员连工号都不给,无法保障消费者的利益。
第三,班主任现在也找不到人。第四多次联系客服,客服人员的说法不一致。
第五综合以上所有问题,我被坑了,无法信任次公司,绝对要求退款。
如果报了名的赶紧打客服要求退费,在打 010-12345 市长反应。
转载程序员的一个贴。
收起阅读 »
网站恢复,图片要等dns缓存一段时间才会正常出来
被人插入广告,导致网站停止运行1天。现在恢复正常。
待会逆向一下看看是哪位。
待会逆向一下看看是哪位。
vs code流畅是流畅,只是面对pycharm的调试与代码提示
还是用回了pycharm。
vs code只能是一个用来写简单应用的文本编辑器。
vs code只能是一个用来写简单应用的文本编辑器。
阿里系纯粹是自己做死 不注重用户体验的结果
手机里除了支付宝,阿里系的软件基本不会再装。
大概几年前吧,装了淘宝,闲鱼,支付宝,天猫等app,启动其中一个app后就在后期偷偷启动其他几个阿里系的app。 这个在后台app或者在日志(adb logcat -v time) 里面可以看到。
正常启动也就算了关键这几个app实在太占用内存,基本占据了手机内存排行榜的前几年,所以只好把上面的app全部卸载了,留一个平时要的支付宝。
最近几年的双十一,大伙玩的叠猫猫,我基本都没打开过,支付宝老让提示下载天猫,淘宝,说送多少多少红包,呵呵,懒得鸟了。 而且,支付宝永久了,存储空间会达到1.5GB,所以也要定期把app卸载干净,再重新装一次。
双十一每天就是刷猴,身边的老用户知道套路,基本也没人玩,直接pdd下单,又快又便宜。 反正平时买的日用的日用品,用来收纳的,假货也不影响使用。
收起阅读 »
大概几年前吧,装了淘宝,闲鱼,支付宝,天猫等app,启动其中一个app后就在后期偷偷启动其他几个阿里系的app。 这个在后台app或者在日志(adb logcat -v time) 里面可以看到。
正常启动也就算了关键这几个app实在太占用内存,基本占据了手机内存排行榜的前几年,所以只好把上面的app全部卸载了,留一个平时要的支付宝。
最近几年的双十一,大伙玩的叠猫猫,我基本都没打开过,支付宝老让提示下载天猫,淘宝,说送多少多少红包,呵呵,懒得鸟了。 而且,支付宝永久了,存储空间会达到1.5GB,所以也要定期把app卸载干净,再重新装一次。
双十一每天就是刷猴,身边的老用户知道套路,基本也没人玩,直接pdd下单,又快又便宜。 反正平时买的日用的日用品,用来收纳的,假货也不影响使用。
收起阅读 »
夜深了,你们还在吗?
夜深了,你们还在吗???????????????????
大家好啊,日常报道,关照关照
大家好啊,日常报道,关照关照。。。。。。。。。。。。
异步asyncio加锁 的正确用法
对于全局变量count进行统计加锁
1. 如果不加入锁,每次运行的结果可能不一样。
2. 不能用多线程的threading 锁,得到的每次运行结果也有可能不一样
3. 用asyncio的锁要 加关键字 async
收起阅读 »
import aiohttp
import asyncio
import execjs
import threading
global pages
global count
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-US,en;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "dcfm.eastmoney.com",
"Pragma": "no-cache",
"Referer": "http://data.eastmoney.com/xg/xg/default.html",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/69.0.3497.81 Chrome/69.0.3497.81 Safari/537.36",
}
home_url = 'http://dcfm.eastmoney.com/em_mutisvcexpandinterface/api/js/get?type=XGSG_LB&token=70f12f2f4f091e459a279469fe49eca5&st=purchasedate,securitycode&sr=-1&p={}&ps=50&js=var%20hsEnHLwG={{pages:(tp),data:(x)}}&rt=53512217'
loop = asyncio.get_event_loop()
# lock = threading.Lock()
lock = asyncio.Lock()
def parse_json(content):
content += ';function getV(){return hsEnHLwG;}'
ctx = execjs.compile(content)
result = ctx.call('getV')
return result
async def fetch(session,page):
global pages
global count
async with session.get(home_url.format(page),headers=headers) as resp:
# print(f'here:: {page}')
content = await resp.text()
try:
js_content = parse_json(content)
for stock_info in js_content['data']:
securityshortname = stock_info['securityshortname']
# print(securityshortname)
except Exception as e:
print(e)
async with lock:
count=count+1
print(f'count:{count}')
if count == pages:
print('End of loop')
loop.stop()
async def main():
global pages
global count
count=0
async with aiohttp.ClientSession() as session:
async with session.get(home_url.format(1), headers=headers) as resp:
content = await resp.text()
js_data = parse_json(content)
pages = js_data['pages']
print(f'pages: {pages}')
for page in range(1,pages+1):
task = asyncio.ensure_future(fetch(session,page))
await asyncio.sleep(1)
asyncio.ensure_future(main())
loop.run_forever()
1. 如果不加入锁,每次运行的结果可能不一样。
2. 不能用多线程的threading 锁,得到的每次运行结果也有可能不一样
3. 用asyncio的锁要 加关键字 async
收起阅读 »