├── geetest3
├── images
│ ├── click_pic_v2.jpg
│ ├── bg.jpg
│ ├── fullbg.jpg
│ └── click_pic.jpg
├── get_trace.py
├── geetest_v2.py
├── geetest.py
├── encrypt.py
├── chaojiying.py
├── test.py
└── img_locate.py
├── view
├── huya.png
├── xmly.png
├── 58city.png
├── aiqiyi.png
├── anjuke.png
├── dajie.png
├── liepin.png
├── shumei.png
├── souhu.png
├── yidun.png
├── eastmoney.png
├── geetest2.png
├── geetest3.png
├── luosimao.png
├── meituan.png
├── mogujie.png
├── tengxun.png
├── tongdun.png
├── toutiao.png
├── vaptcha.png
├── xiecheng.png
├── yunpian.png
├── yunshanfu.png
└── ztggame.png
├── huya
└── images
│ ├── big.jpg
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── small.jpg
│ └── new_image.jpg
├── mogujie
├── captcha.jpg
└── geetest.py
├── vaptcha
├── vaptcha.jpg
├── v_slider.js
├── chaojiying.py
├── get_trace.py
└── geetest.py
├── xmly
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_image.jpg
└── geetest.py
├── city58
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_image.jpg
├── img_locate.py
├── chaojiying.py
├── c58_crypt.py
└── get_trace.py
├── iqiyi
├── images
│ ├── slider.jpg
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── new_captcha.jpg
│ └── new_image.jpg
├── decode_rsa.js
├── rsa_encrypt.js
├── test.py
├── random_str.js
├── img_locate.py
└── process_trace.py
├── shumei
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_image.png
├── des.py
├── get_trace.py
├── img_locate.py
├── geetest.py
└── geetest_new.py
├── souhu
├── images
│ ├── slider.jpg
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ └── new_image.jpg
└── test.py
├── tengxun
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── slider.jpg
│ ├── captcha.jpg
│ └── new_captcha.jpg
├── get_trace.py
└── img_locate.py
├── tongdun
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── slider.jpg
│ ├── captcha.jpg
│ ├── new_image.jpg
│ └── new_captcha.jpg
├── td_crypt.py
└── img_locate.py
├── toutiao
└── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── slider.jpg
│ ├── captcha.jpg
│ └── new_image.png
├── wanmei
├── images
│ ├── all.jpg
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_image.jpg
├── trace.py
├── wm_crypt.py
├── geetest.py
└── img_locate.py
├── yidun
├── images
│ ├── slider.jpg
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ └── new_image.jpg
├── get_trace.py
├── encrypt.py
├── chaojiying.py
├── generate_fp.js
├── yd_slider.js
└── img_locate.py
├── yunpian
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── slider.jpg
│ ├── captcha.jpg
│ └── new_image.jpg
└── test.py
├── ztggame
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── slider.jpg
│ ├── captcha.jpg
│ └── new_image.png
└── geetest.py
├── dajie
├── images
│ ├── captcha.jpg
│ └── new_captcha.jpg
└── chaojiying.py
├── eastmoney
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── new_image.jpg
│ ├── slide_gap.jpg
│ ├── click_full.jpg
│ ├── click_merge.jpg
│ ├── click_words.jpg
│ └── slide_full.jpg
├── get_trace.py
├── chaojiying.py
└── geetest.py
├── jingdong
├── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_captcha.jpg
├── test.py
├── jd_slider.js
├── img_locate.py
└── geetest.py
├── liepin
├── images
│ ├── captcha.jpg
│ └── new_captcha.jpg
└── chaojiying.py
├── luosimao
├── images
│ ├── word.jpg
│ ├── captcha.jpg
│ └── new_captcha.jpg
├── lsm_crypt.py
├── chaojiying.py
├── img_locate.py
└── geetest.py
├── yushanfu
└── images
│ ├── targ.jpg
│ ├── temp.jpg
│ ├── captcha.jpg
│ ├── slider.jpg
│ └── new_image.jpg
├── anjuke
├── img_db
│ ├── anjuke_captcha.jpg
│ └── anjuke_slider.jpg
├── test.py
└── geetest.py
├── geetest2
├── __init__.py
├── test.py
└── img_locate.py
├── requirements.txt
├── xiecheng
├── get_sfp.js
├── test.py
└── xc_slider.js
└── meituan
├── geetest.py
└── test.py
/geetest3/images/click_pic_v2.jpg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/view/huya.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/huya.png
--------------------------------------------------------------------------------
/view/xmly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/xmly.png
--------------------------------------------------------------------------------
/view/58city.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/58city.png
--------------------------------------------------------------------------------
/view/aiqiyi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/aiqiyi.png
--------------------------------------------------------------------------------
/view/anjuke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/anjuke.png
--------------------------------------------------------------------------------
/view/dajie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/dajie.png
--------------------------------------------------------------------------------
/view/liepin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/liepin.png
--------------------------------------------------------------------------------
/view/shumei.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/shumei.png
--------------------------------------------------------------------------------
/view/souhu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/souhu.png
--------------------------------------------------------------------------------
/view/yidun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/yidun.png
--------------------------------------------------------------------------------
/view/eastmoney.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/eastmoney.png
--------------------------------------------------------------------------------
/view/geetest2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/geetest2.png
--------------------------------------------------------------------------------
/view/geetest3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/geetest3.png
--------------------------------------------------------------------------------
/view/luosimao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/luosimao.png
--------------------------------------------------------------------------------
/view/meituan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/meituan.png
--------------------------------------------------------------------------------
/view/mogujie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/mogujie.png
--------------------------------------------------------------------------------
/view/tengxun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/tengxun.png
--------------------------------------------------------------------------------
/view/tongdun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/tongdun.png
--------------------------------------------------------------------------------
/view/toutiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/toutiao.png
--------------------------------------------------------------------------------
/view/vaptcha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/vaptcha.png
--------------------------------------------------------------------------------
/view/xiecheng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/xiecheng.png
--------------------------------------------------------------------------------
/view/yunpian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/yunpian.png
--------------------------------------------------------------------------------
/view/yunshanfu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/yunshanfu.png
--------------------------------------------------------------------------------
/view/ztggame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/view/ztggame.png
--------------------------------------------------------------------------------
/huya/images/big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/huya/images/big.jpg
--------------------------------------------------------------------------------
/huya/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/huya/images/targ.jpg
--------------------------------------------------------------------------------
/huya/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/huya/images/temp.jpg
--------------------------------------------------------------------------------
/mogujie/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/mogujie/captcha.jpg
--------------------------------------------------------------------------------
/vaptcha/vaptcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/vaptcha/vaptcha.jpg
--------------------------------------------------------------------------------
/xmly/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/xmly/images/targ.jpg
--------------------------------------------------------------------------------
/xmly/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/xmly/images/temp.jpg
--------------------------------------------------------------------------------
/city58/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/city58/images/targ.jpg
--------------------------------------------------------------------------------
/city58/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/city58/images/temp.jpg
--------------------------------------------------------------------------------
/geetest3/images/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/geetest3/images/bg.jpg
--------------------------------------------------------------------------------
/huya/images/small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/huya/images/small.jpg
--------------------------------------------------------------------------------
/iqiyi/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/slider.jpg
--------------------------------------------------------------------------------
/iqiyi/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/targ.jpg
--------------------------------------------------------------------------------
/iqiyi/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/temp.jpg
--------------------------------------------------------------------------------
/shumei/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/shumei/images/targ.jpg
--------------------------------------------------------------------------------
/shumei/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/shumei/images/temp.jpg
--------------------------------------------------------------------------------
/souhu/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/souhu/images/slider.jpg
--------------------------------------------------------------------------------
/souhu/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/souhu/images/targ.jpg
--------------------------------------------------------------------------------
/souhu/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/souhu/images/temp.jpg
--------------------------------------------------------------------------------
/tengxun/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tengxun/images/targ.jpg
--------------------------------------------------------------------------------
/tengxun/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tengxun/images/temp.jpg
--------------------------------------------------------------------------------
/tongdun/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/targ.jpg
--------------------------------------------------------------------------------
/tongdun/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/temp.jpg
--------------------------------------------------------------------------------
/toutiao/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/toutiao/images/targ.jpg
--------------------------------------------------------------------------------
/toutiao/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/toutiao/images/temp.jpg
--------------------------------------------------------------------------------
/wanmei/images/all.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/all.jpg
--------------------------------------------------------------------------------
/wanmei/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/targ.jpg
--------------------------------------------------------------------------------
/wanmei/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/temp.jpg
--------------------------------------------------------------------------------
/xmly/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/xmly/images/captcha.jpg
--------------------------------------------------------------------------------
/xmly/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/xmly/images/slider.jpg
--------------------------------------------------------------------------------
/yidun/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yidun/images/slider.jpg
--------------------------------------------------------------------------------
/yidun/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yidun/images/targ.jpg
--------------------------------------------------------------------------------
/yidun/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yidun/images/temp.jpg
--------------------------------------------------------------------------------
/yunpian/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yunpian/images/targ.jpg
--------------------------------------------------------------------------------
/yunpian/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yunpian/images/temp.jpg
--------------------------------------------------------------------------------
/ztggame/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/ztggame/images/targ.jpg
--------------------------------------------------------------------------------
/ztggame/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/ztggame/images/temp.jpg
--------------------------------------------------------------------------------
/city58/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/city58/images/captcha.jpg
--------------------------------------------------------------------------------
/city58/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/city58/images/slider.jpg
--------------------------------------------------------------------------------
/dajie/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/dajie/images/captcha.jpg
--------------------------------------------------------------------------------
/eastmoney/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/targ.jpg
--------------------------------------------------------------------------------
/eastmoney/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/temp.jpg
--------------------------------------------------------------------------------
/huya/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/huya/images/new_image.jpg
--------------------------------------------------------------------------------
/iqiyi/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/captcha.jpg
--------------------------------------------------------------------------------
/jingdong/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/jingdong/images/targ.jpg
--------------------------------------------------------------------------------
/jingdong/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/jingdong/images/temp.jpg
--------------------------------------------------------------------------------
/liepin/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/liepin/images/captcha.jpg
--------------------------------------------------------------------------------
/luosimao/images/word.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/luosimao/images/word.jpg
--------------------------------------------------------------------------------
/shumei/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/shumei/images/captcha.jpg
--------------------------------------------------------------------------------
/shumei/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/shumei/images/slider.jpg
--------------------------------------------------------------------------------
/souhu/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/souhu/images/captcha.jpg
--------------------------------------------------------------------------------
/tengxun/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tengxun/images/slider.jpg
--------------------------------------------------------------------------------
/tongdun/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/slider.jpg
--------------------------------------------------------------------------------
/toutiao/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/toutiao/images/slider.jpg
--------------------------------------------------------------------------------
/wanmei/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/captcha.jpg
--------------------------------------------------------------------------------
/wanmei/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/slider.jpg
--------------------------------------------------------------------------------
/xmly/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/xmly/images/new_image.jpg
--------------------------------------------------------------------------------
/yidun/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yidun/images/captcha.jpg
--------------------------------------------------------------------------------
/yunpian/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yunpian/images/slider.jpg
--------------------------------------------------------------------------------
/yushanfu/images/targ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yushanfu/images/targ.jpg
--------------------------------------------------------------------------------
/yushanfu/images/temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yushanfu/images/temp.jpg
--------------------------------------------------------------------------------
/ztggame/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/ztggame/images/slider.jpg
--------------------------------------------------------------------------------
/city58/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/city58/images/new_image.jpg
--------------------------------------------------------------------------------
/dajie/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/dajie/images/new_captcha.jpg
--------------------------------------------------------------------------------
/geetest3/images/fullbg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/geetest3/images/fullbg.jpg
--------------------------------------------------------------------------------
/iqiyi/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/new_captcha.jpg
--------------------------------------------------------------------------------
/iqiyi/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/iqiyi/images/new_image.jpg
--------------------------------------------------------------------------------
/jingdong/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/jingdong/images/captcha.jpg
--------------------------------------------------------------------------------
/jingdong/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/jingdong/images/slider.jpg
--------------------------------------------------------------------------------
/luosimao/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/luosimao/images/captcha.jpg
--------------------------------------------------------------------------------
/shumei/images/new_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/shumei/images/new_image.png
--------------------------------------------------------------------------------
/souhu/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/souhu/images/new_image.jpg
--------------------------------------------------------------------------------
/tengxun/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tengxun/images/captcha.jpg
--------------------------------------------------------------------------------
/tongdun/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/captcha.jpg
--------------------------------------------------------------------------------
/tongdun/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/new_image.jpg
--------------------------------------------------------------------------------
/toutiao/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/toutiao/images/captcha.jpg
--------------------------------------------------------------------------------
/toutiao/images/new_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/toutiao/images/new_image.png
--------------------------------------------------------------------------------
/wanmei/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/wanmei/images/new_image.jpg
--------------------------------------------------------------------------------
/yidun/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yidun/images/new_image.jpg
--------------------------------------------------------------------------------
/yunpian/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yunpian/images/captcha.jpg
--------------------------------------------------------------------------------
/yunpian/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yunpian/images/new_image.jpg
--------------------------------------------------------------------------------
/yushanfu/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yushanfu/images/captcha.jpg
--------------------------------------------------------------------------------
/yushanfu/images/slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yushanfu/images/slider.jpg
--------------------------------------------------------------------------------
/ztggame/images/captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/ztggame/images/captcha.jpg
--------------------------------------------------------------------------------
/ztggame/images/new_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/ztggame/images/new_image.png
--------------------------------------------------------------------------------
/eastmoney/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/new_image.jpg
--------------------------------------------------------------------------------
/eastmoney/images/slide_gap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/slide_gap.jpg
--------------------------------------------------------------------------------
/geetest3/images/click_pic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/geetest3/images/click_pic.jpg
--------------------------------------------------------------------------------
/liepin/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/liepin/images/new_captcha.jpg
--------------------------------------------------------------------------------
/tengxun/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tengxun/images/new_captcha.jpg
--------------------------------------------------------------------------------
/tongdun/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/tongdun/images/new_captcha.jpg
--------------------------------------------------------------------------------
/yushanfu/images/new_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/yushanfu/images/new_image.jpg
--------------------------------------------------------------------------------
/anjuke/img_db/anjuke_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/anjuke/img_db/anjuke_captcha.jpg
--------------------------------------------------------------------------------
/anjuke/img_db/anjuke_slider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/anjuke/img_db/anjuke_slider.jpg
--------------------------------------------------------------------------------
/eastmoney/images/click_full.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/click_full.jpg
--------------------------------------------------------------------------------
/eastmoney/images/click_merge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/click_merge.jpg
--------------------------------------------------------------------------------
/eastmoney/images/click_words.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/click_words.jpg
--------------------------------------------------------------------------------
/eastmoney/images/slide_full.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/eastmoney/images/slide_full.jpg
--------------------------------------------------------------------------------
/jingdong/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/jingdong/images/new_captcha.jpg
--------------------------------------------------------------------------------
/luosimao/images/new_captcha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcc0lin/SliderCracker/HEAD/luosimao/images/new_captcha.jpg
--------------------------------------------------------------------------------
/geetest2/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/7 15:22
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : __init__.py
6 | # @Software: PyCharm
7 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | cryptography==2.4.2
2 | numpy==1.17.3
3 | selenium==3.141.0
4 | matplotlib==3.0.2
5 | PyExecJS==1.5.1
6 | opencv_python==4.1.0.25
7 | requests==2.21.0
8 | rsa==4.0
9 | pycryptodome=3.9.0
10 | Pillow==6.2.1
11 | beautifulsoup4==4.8.1
12 |
--------------------------------------------------------------------------------
/iqiyi/decode_rsa.js:
--------------------------------------------------------------------------------
1 | // 已删除关键 js, 请自行补全
2 |
3 | function decodeRSA(rsa_str) {
4 | return f(i.decode(rsa_str))
5 | }
6 |
7 | console.log(decodeRSA("mC0IIm7khy7OZaZrpfcVAvZuh/xlkf4Ybi3PcCPLN579hY8dF61Tw9OjWwuAOQbd6p7h6sH7U1AeWeOX87CqeFA9k7bZW7BzfI4Trp81LZO9Nzm16S3v0CayyPbPCrVRYTDso/81QfaozFVa8vTvsMdUx41E7yhpdSmpEEhy6l8="));
--------------------------------------------------------------------------------
/tengxun/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/9 23:46
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 | import random
9 |
10 |
11 | def generate_trace(distance):
12 | """
13 | 生成轨迹
14 | :param distance:
15 | :return:
16 | """
17 | return trace
18 |
--------------------------------------------------------------------------------
/xiecheng/get_sfp.js:
--------------------------------------------------------------------------------
1 |
2 | function get_sfp($0) {
3 | var stack = y.J();
4 | var a = $0;
5 | var b = 0;
6 | null !== a && void 0 !== a && 0 !== a && (b = y.q((a.length << 2) + 1),
7 | ka(a, b));
8 | $0 = b;
9 | var ret = Z._mixfp($0);
10 | ret = G(ret);
11 | y.I(stack);
12 | return encodeURIComponent(ret)
13 | }
14 |
15 | console.log(get_sfp("63538641"));
--------------------------------------------------------------------------------
/geetest3/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/28 16:09
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 |
9 | import random
10 |
11 |
12 | def generate_trace(distance):
13 | """
14 | 生成轨迹
15 | :param distance: 缺口距离
16 | :return:
17 | """
18 |
19 |
20 | if __name__ == "__main__":
21 | pass
22 |
--------------------------------------------------------------------------------
/iqiyi/rsa_encrypt.js:
--------------------------------------------------------------------------------
1 | // 已删除关键 js, RSA 加密, 请自行补全
2 |
3 | function RSAEncrypt(text) {
4 | var encrypter = new zc();
5 | var publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfyy01w1BXvMX8hc0ooyaCcXv2A0fsqDjcEXZ8AQJSHU00iG9YoYyLwmS0G9eE+dEFomOI2a+mrh9JYpw2Y26oGFZFA8Dtly5Go4nXeFT/pEeSwWINcXQ5Y9WCMTkQ+RN5WJ0UPvWt+soqP3Z5FJdMJTWA4lwIyoN3c4d9dWcpkQIDAQAB";
6 | encrypter.setPublicKey(publicKey);
7 | return encrypter.encrypt(a(text))
8 | }
9 |
--------------------------------------------------------------------------------
/yidun/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 21:59
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | import random
10 |
11 |
12 | def _generate_trace(distance, start_time):
13 | """
14 | 生成轨迹
15 | :param distance:
16 | :param start_time:
17 | :return:
18 | """
19 | trace = []
20 | for index, x in enumerate(tracks_list):
21 | trace.append([x, y_list[index], timestamp_list[index] - start_time])
22 | return trace
23 |
--------------------------------------------------------------------------------
/wanmei/trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/10 17:29
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : trace.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | import random
10 |
11 |
12 | def _generate_trace(distance, start_time):
13 | """
14 | 生成轨迹
15 | :param distance:
16 | :return:
17 | """
18 | # 轨迹删除
19 | trace = [[base_x, base_y, 1, 0]]
20 | for index, x in enumerate(tracks_list):
21 | trace.append([base_x + x, base_y + y_list[index], 3, timestamp_list[index] - start_time])
22 | return trace[:-1]
23 |
24 |
--------------------------------------------------------------------------------
/geetest3/geetest_v2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/29 13:05
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : v2.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import traceback
10 | from geetest3.img_locate import ImgProcess
11 | from geetest3.get_trace import *
12 | from geetest3.encrypt import *
13 |
14 | """
15 | 最新版极验3滑块验证, 某比特币交易网站注册: https://www.okex.me/account/register
16 | """
17 |
18 |
19 | class GeetestV3New:
20 |
21 | def __init__(self, gt):
22 | self.gt = gt
23 | self.challenge = ''
24 |
25 |
26 | if __name__ == "__main__":
27 | pass
28 |
--------------------------------------------------------------------------------
/geetest3/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/28 16:12
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import traceback
10 | from PIL import Image
11 | from geetest3.chaojiying import image_to_text
12 | from geetest3.encrypt import *
13 | from geetest3.img_locate import ImgProcess
14 | from geetest3.get_trace import *
15 |
16 |
17 | class GeetestV3:
18 |
19 | def __init__(self, gt, challenge):
20 | self.gt = gt
21 | self.challenge = challenge
22 |
23 |
24 | if __name__ == "__main__":
25 | pass
26 |
--------------------------------------------------------------------------------
/yunpian/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/28 11:56
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | from yunpian.geetest import crack
10 |
11 |
12 | def main():
13 | print('开始测试...')
14 | print('=' * 100)
15 | num = 1
16 | success = 0
17 | while num <= 20:
18 | x = crack()
19 | print(x)
20 | if x['success']:
21 | success += 1
22 | time.sleep(1)
23 | num += 1
24 | print('最后测试结果 >> %.2f%%' % success)
25 |
26 |
27 | if __name__ == '__main__':
28 | main()
29 |
--------------------------------------------------------------------------------
/iqiyi/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 16:31
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | from iqiyi.geetest import IqiyiSliderCracker
9 |
10 |
11 | def main(dfp):
12 | x = IqiyiSliderCracker(dfp).crack()
13 | print(x)
14 | if x['success']:
15 | IqiyiSliderCracker(dfp).login(x['data']['env_token'])
16 |
17 |
18 | if __name__ == '__main__':
19 | # 这个参数已过期, 请自行更换, 登录爱奇艺直至出现滑块, 从出现滑块的登录接口 login.action 中取 Form Data 参数 dfp
20 | dfp = 'a1835676114a1946afb9b57417746ac8cc1ae2ca2e797a88078f7be3ba64f4db31'
21 | main(dfp)
22 |
--------------------------------------------------------------------------------
/souhu/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/4 10:06
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 |
9 | import time
10 | import random
11 | from souhu.geetest import crack
12 |
13 |
14 | def main():
15 | print('开始测试...')
16 | print('=' * 100)
17 | num = 1
18 | success = 0
19 | while num <= 20:
20 | x = crack()
21 | print(x)
22 | if x['success']:
23 | success += 1
24 | time.sleep(random.randint(1, 3))
25 | num += 1
26 | print('最后测试结果 >> %.2f%%' % success)
27 |
28 |
29 | if __name__ == '__main__':
30 | main()
31 |
--------------------------------------------------------------------------------
/xiecheng/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/4 10:24
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | import random
10 | from xiecheng.geetest import crack
11 |
12 |
13 | def main():
14 | print('开始测试...')
15 | print('=' * 100)
16 | num = 1
17 | success = 0
18 | while num <= 20:
19 | x = crack()
20 | print(x)
21 | if x['success']:
22 | success += 1
23 | time.sleep(random.randint(1, 3))
24 | num += 1
25 | print('最后测试结果 >> %.2f%%' % success)
26 |
27 |
28 | if __name__ == '__main__':
29 | main()
30 |
--------------------------------------------------------------------------------
/eastmoney/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/24 21:28
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 |
9 | import random
10 |
11 |
12 | def generate_trace(distance):
13 | """
14 | 生成轨迹
15 | :param distance:
16 | :return:
17 | """
18 | # 轨迹删除
19 | trace = [[0, 0, 0]]
20 | for index, x in enumerate(tracks_list[:-1]):
21 | trace.append([x, y_list[index], timestamp_list[index]])
22 | trace.append([tracks_list[-1], y_list[-1], timestamp_list[-2] + random.randint(100, 200)])
23 | trace.append([distance, y_list[-1], timestamp_list[-2] + random.randint(200, 300)])
24 | return trace
25 |
26 |
--------------------------------------------------------------------------------
/geetest3/encrypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/28 16:10
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : encrypt.py
6 | # @Software: PyCharm
7 |
8 | import math
9 | import re
10 | import binascii, json, os
11 | import time
12 | import random
13 | import hashlib
14 | import rsa
15 | from Crypto.Cipher import AES
16 | from Crypto.Util.Padding import pad
17 |
18 |
19 | class Encrypter:
20 |
21 | def __init__(self):
22 | self.modulus = "00C1E3934D1614465B33053E7F48EE4EC87B14B95EF88947713D25EECBFF7E74C7977D02DC1D9451F79DD5D1C10C29ACB6A9B4D6FB7D0A0279B6719E1772565F09AF627715919221AEF91899CAE08C0D686D748B20A3603BE2318CA6BC2B59706592A9219D0BF05C9F65023A21D2330807252AE0066D59CEEFA5F2748EA80BAB81"
23 | self.pub_key = '10001'
24 |
25 |
26 |
--------------------------------------------------------------------------------
/iqiyi/random_str.js:
--------------------------------------------------------------------------------
1 | function f(h) {
2 | return (h = ((9301 * h) + 49297) % 233280) / 233280
3 | }
4 | function o(x, h) {
5 | return Math["ceil"](f(h) * x)
6 | }
7 | function getRandomStr(x) {
8 | var c = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
9 | "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
10 | "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7",
11 | "8", "9"];
12 | var c_ = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
13 | var a = c["length"];
14 | for (var _ = "", i = 0; i < x; i++) {
15 | var h = (new Date)["getTime"]() + Math.ceil((10 * Math["random"]()) * c_["length"]);
16 | var r = o(a, h) - 1;
17 | r < 0 && (r = 0);
18 | r > a && (r = a);
19 | _ += c[r]
20 | }
21 | return _;
22 | }
23 |
24 | console.log(getRandomStr(64));
25 |
--------------------------------------------------------------------------------
/luosimao/lsm_crypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/11 8:41
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : lsm_crypt.py
6 | # @Software: PyCharm
7 |
8 | import base64
9 | import hashlib
10 | from Crypto.Cipher import AES
11 |
12 |
13 | def aes_encrypt(key, iv, text):
14 | """
15 | AES 加密, CBC 模式, ZeroPadding补全
16 | :param key: 密钥
17 | :param iv: 偏移量
18 | :param text: 明文
19 | :return: 密文
20 | """
21 | length = 16
22 | count = len(text)
23 | if count < length:
24 | add = (length - count)
25 | text = text + ('\0' * add)
26 | elif count > length:
27 | add = (length - (count % length))
28 | text = text + ('\0' * add)
29 |
30 | encrypter = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
31 |
32 | cipher_text = encrypter.encrypt(text.encode())
33 | return base64.b64encode(cipher_text).decode()
34 |
35 |
36 | def md5_encrypt(text):
37 | """
38 | md5 加密
39 | :param text: 明文
40 | :return: 密文
41 | """
42 | md5 = hashlib.md5()
43 | md5.update(text.encode())
44 | return md5.hexdigest()
45 |
46 |
47 | if __name__ == '__main__':
48 | x = aes_encrypt("6aafc455d869a1eedfe55739a1a724c5", "2801003954373300", "108,225")
49 | print(x)
50 |
--------------------------------------------------------------------------------
/shumei/des.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/3 20:54
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : des.py
6 | # @Software: PyCharm
7 |
8 |
9 | from Crypto.Cipher import DES
10 | import base64
11 |
12 |
13 | def encrypt(key, text):
14 | """
15 | DES 加密
16 | :param key: 密钥, 长度必须为 16(AES-128)、24(AES-192)、32(AES-256) Bytes 长度
17 | :param text: 密文
18 | :return:
19 | """
20 | encrypter = DES.new(key.encode(), DES.MODE_ECB)
21 | length = 8
22 | count = len(text)
23 | if count < length:
24 | add = (length - count)
25 | text = text + ('\0' * add)
26 | elif count > length:
27 | add = (length - (count % length))
28 | text = text + ('\0' * add)
29 | ciphertext = encrypter.encrypt(text.encode())
30 | return base64.b64encode(ciphertext).decode()
31 |
32 |
33 | def decrypt(key, text):
34 | """
35 | DES 解密
36 | :param key: 密钥
37 | :param text: 密文
38 | :return:
39 | """
40 | decrypter = DES.new(key.encode(), DES.MODE_ECB)
41 | return decrypter.decrypt(text).decode()
42 |
43 |
44 | if __name__ == '__main__':
45 | text = base64.b64decode("+Xtt67nCLT4=")
46 | # 对解码后的 k 值进行 DES 解密(密钥: sshummei), 取前8位作为下一次加密的密钥
47 | new_key = decrypt('sshummei', text)[:8]
48 | print(new_key)
49 |
--------------------------------------------------------------------------------
/jingdong/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/28 10:59
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | import random
9 | import time
10 | import requests
11 | from jingdong.geetest import crack
12 | from bs4 import BeautifulSoup
13 |
14 |
15 | def main():
16 | # resp = requests.get(
17 | # 'https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F%3Fcu%3Dtrue%26utm_source%3Dhaosou-pinzhuan%26utm_medium%3Dcpc%26utm_campaign%3Dt_288551095_haosoupinzhuan%26utm_term%3D0a875d61c5fe47d8bc48679132932d23_0_bd3750333d254fc398ac4f9a8c5ed320',
18 | # headers={
19 | # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
20 | # })
21 | # soup = BeautifulSoup(resp.text, 'lxml')
22 | # eid = soup.select('#eid')[0]['value']
23 | result = crack()
24 | return result
25 |
26 |
27 | if __name__ == '__main__':
28 | print('开始测试...')
29 | print('=' * 100)
30 | num = 1
31 | success = 0
32 | while num <= 100:
33 | x = main()
34 | print(x)
35 | if x['success']:
36 | success += 1
37 | time.sleep(random.random())
38 | num += 1
39 | print('最后测试结果 >> %.2f%%' % success)
40 |
--------------------------------------------------------------------------------
/geetest2/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/8 15:15
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 |
9 | import execjs
10 | import json
11 | import time
12 | import requests
13 | import random
14 | from pprint import pprint
15 | from geetest2.geetest import crack
16 |
17 |
18 | def get_captcha():
19 | url = 'https://www.tianyancha.com/verify/geetest.xhtml'
20 | payload = {
21 | 'uuid': int(time.time() * 1000)
22 | }
23 | referer = 'https://www.tianyancha.com/vipintro/?jsid=SEM-360-PZ-SY-081001'
24 | headers = {
25 | 'Accept': '*/*',
26 | 'Accept-Encoding': 'gzip, deflate, br',
27 | 'Accept-Language': 'zh-CN,zh;q=0.9',
28 | 'Connection': 'keep-alive',
29 | 'Content-Type': 'application/json; charset=UTF-8',
30 | 'Referer': referer,
31 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36',
32 | 'X-Requested-With': 'XMLHttpRequest'
33 | }
34 | result = requests.post(url, data=json.dumps(payload), headers=headers).json()
35 | if result['state'] == 'ok':
36 | return result['data']['gt'], result['data']['challenge'], referer
37 | else:
38 | return None
39 |
40 |
41 | def main():
42 | while True:
43 | data = get_captcha()
44 | if data:
45 | break
46 | time.sleep(random.random())
47 | result = crack(data[0], data[1], data[2])
48 | print(result)
49 |
50 |
51 | if __name__ == '__main__':
52 | main()
53 |
--------------------------------------------------------------------------------
/jingdong/jd_slider.js:
--------------------------------------------------------------------------------
1 |
2 | var jd = {
3 | fp: function(c) {
4 | var a = [];
5 | for (var b in c) {
6 | a.push(encodeURIComponent(b) + "=" + encodeURIComponent(c[b]))
7 | }
8 | a.push(("v=" + Math.random()).replace(".", ""));
9 | return a.join("&")
10 | },
11 | st: function(d) {
12 | var c = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~".split("")
13 | , b = c.length
14 | , e = +d
15 | , a = [];
16 | do {
17 | mod = e % b;
18 | e = (e - mod) / b;
19 | a.unshift(c[mod])
20 | } while (e);return a.join("")
21 | },
22 | pi: function(a, b) {
23 | return (Array(b).join(0) + a).slice(-b)
24 | },
25 | pm: function(d, c, b) {
26 | var f = this;
27 | var e = f.st(Math.abs(d));
28 | var a = "";
29 | if (!b) {
30 | a += (d > 0 ? "1" : "0")
31 | }
32 | a += f.pi(e, c);
33 | return a
34 | },
35 | encrypt: function(c) {
36 | var g = this;
37 | var b = new Array();
38 | for (var e = 0; e < c.length; e++) {
39 | if (e == 0) {
40 | b.push(g.pm(c[e][0] < 262143 ? c[e][0] : 262143, 3, true));
41 | b.push(g.pm(c[e][1] < 16777215 ? c[e][1] : 16777215, 4, true));
42 | b.push(g.pm(c[e][2] < 4398046511103 ? c[e][2] : 4398046511103, 7, true))
43 | } else {
44 | var a = c[e][0] - c[e - 1][0];
45 | var f = c[e][1] - c[e - 1][1];
46 | var d = c[e][2] - c[e - 1][2];
47 | b.push(g.pm(a < 4095 ? a : 4095, 2, false));
48 | b.push(g.pm(f < 4095 ? f : 4095, 2, false));
49 | b.push(g.pm(d < 16777215 ? d : 16777215, 4, true))
50 | }
51 | }
52 | return b.join("")
53 | }
54 | };
55 |
56 | function encrypt_trace(trace) {
57 | return jd.encrypt(trace)
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/yidun/encrypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 21:58
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : encrypt.py
6 | # @Software: PyCharm
7 |
8 | import execjs
9 |
10 |
11 | def _reload_js():
12 | """
13 | 加载 js
14 | :return:
15 | """
16 | with open('yd_slider.js', 'rb') as f:
17 | slider_js = f.read().decode()
18 | with open('generate_fp.js', 'rb') as f:
19 | fp_js = f.read().decode()
20 | return slider_js, fp_js
21 |
22 |
23 | def _get_cb(js):
24 | """
25 | 生成 cp 参数
26 | :param js:
27 | :return:
28 | """
29 | ctx = execjs.compile(js)
30 | return ctx.call('get_cb')[:64]
31 |
32 |
33 | def _get_fp(js):
34 | """
35 | 生成指纹 fp
36 | :param js:
37 | :return:
38 | """
39 | ctx_ = execjs.compile(js)
40 | return ctx_.call('generateFingerprint')
41 |
42 |
43 | def _encrypt_slider(js, token, trace, width):
44 | """
45 | 滑块验证加密
46 | 加密轨迹
47 | :param token:
48 | :param trace:
49 | :param width
50 | :return:
51 | """
52 | ctx = execjs.compile(js)
53 | return ctx.call('slider_encrypt', token, trace, width)
54 |
55 |
56 | def _encrypt_click(js, token, trace, position):
57 | """
58 | 点选验证加密
59 | 加密轨迹与点选位置
60 | :param js:
61 | :param token:
62 | :param trace:
63 | :param position:
64 | :return:
65 | """
66 | ctx = execjs.compile(js)
67 | return ctx.call('click_encrypt', token, trace, position)
68 |
69 |
70 | def _encrypt_sense(js, token, trace, position):
71 | """
72 | 无感验证加密
73 | 加密轨迹与点击位置
74 | :param js:
75 | :param token:
76 | :param trace:
77 | :param position:
78 | :return:
79 | """
80 | ctx = execjs.compile(js)
81 | return ctx.call('sense_encrypt', token, trace, position)
82 |
83 |
84 | def _encrypt_validate(js, validate, fp):
85 | """
86 | 加密 validate
87 | :param js:
88 | :param validate: 验证码通过签名
89 | :param fp: 指纹
90 | :return:
91 | """
92 | ctx = execjs.compile(js)
93 | return ctx.call('encrypt_validate', validate, fp)
94 |
--------------------------------------------------------------------------------
/vaptcha/v_slider.js:
--------------------------------------------------------------------------------
1 | var _sample = "abcdefgh234lmntuwxyz";
2 | function _convertScale(t) {
3 | t = Math.floor(t);
4 | var e = _sample[t % 20];
5 | t = Math.floor(t / 20);
6 | var n = _sample[t % 20]
7 | , i = Math.floor(t / 20);
8 | return "" + ((i = i ? _sample[i] : "_") || "_") + (n || "_") + (e || "_")
9 | }
10 | function assemblyCoordData(trace) {;
11 | for (var e = [], n = [], i = [], r = 0, s = trace; r < s.length; r++) {
12 | var a = s[r];
13 | e.push(_convertScale(a.x)),
14 | n.push(_convertScale(a.y)),
15 | i.push(_convertScale(a.time))
16 | }
17 | return e.join("") + n.join("") + i.join("")
18 | }
19 |
20 | console.log(assemblyCoordData([{x: 148, y: 42, time: 8.114999975077808}, {x: 137, y: 43, time: 160.9900000039488}, {x: 124, y: 45, time: 168.1899999966845}, {x: 114, y: 47, time: 175.5600000033155}, {x: 103, y: 51, time: 182.79499997152016}, {x: 87, y: 57, time: 190.2000000118278}, {x: 74, y: 61, time: 197.48500001151115}, {x: 65, y: 66, time: 204.75499995518476}, {x: 57, y: 69, time: 212.18500001123175}, {x: 53, y: 70, time: 219.37000000616536}, {x: 47, y: 72, time: 226.76499997032806}, {x: 44, y: 75, time: 233.96499996306375}, {x: 41, y: 76, time: 241.32999998982996}, {x: 39, y: 76, time: 248.80499998107553}, {x: 38, y: 77, time: 256.0149999917485}, {x: 37, y: 78, time: 263.2049999665469}, {x: 36, y: 78, time: 278.05999998236075}, {x: 36, y: 79, time: 321.5900000068359}, {x: 37, y: 80, time: 336.3749999552965}, {x: 40, y: 83, time: 343.91499997582287}, {x: 46, y: 85, time: 350.7899999967776}, {x: 57, y: 89, time: 357.9949999693781}, {x: 75, y: 94, time: 365.3899999917485}, {x: 90, y: 96, time: 372.6949999690987}, {x: 101, y: 98, time: 379.929999995511}, {x: 119, y: 100, time: 387.15999998385087}, {x: 144, y: 100, time: 394.6299999952316}, {x: 157, y: 100, time: 401.8649999634363}, {x: 165, y: 101, time: 409.0999999898486}, {x: 179, y: 102, time: 416.37499997159466}, {x: 193, y: 103, time: 423.6500000115484}, {x: 205, y: 106, time: 431.0549999936484}, {x: 214, y: 108, time: 438.38000000687316}, {x: 221, y: 111, time: 445.7449999754317}, {x: 223, y: 112, time: 452.869999979157}, {x: 233, y: 117, time: 460.33999999053776}, {x: 235, y: 118, time: 467.47999999206513}]));
21 |
22 |
--------------------------------------------------------------------------------
/jingdong/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/18 15:59
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import io
9 | import os
10 | import cv2
11 | import base64
12 | import numpy as np
13 | from PIL import Image
14 |
15 |
16 | def pic_download(url, type):
17 | """
18 | 图片下载
19 | :param url:
20 | :param type:
21 | :return:
22 | """
23 | save_path = os.path.abspath('...') + '\\' + 'images'
24 | if not os.path.exists(save_path):
25 | os.mkdir(save_path)
26 | img_path = save_path + '\\' + '{}.jpg'.format(type)
27 | img_data = base64.b64decode(url)
28 | current_img = Image.open(io.BytesIO(img_data)).convert("RGB")
29 | current_img.save(img_path)
30 | return img_path
31 |
32 |
33 | def get_distance(slider_url, captcha_url):
34 | """
35 | 获取缺口距离
36 | :param slider_url:
37 | :param captcha_url:
38 | :return:
39 | """
40 | save_path = os.path.abspath('...') + '\\' + 'images'
41 | if not os.path.exists(save_path):
42 | os.mkdir(save_path)
43 | # 引用上面的图片下载
44 | slider_path = pic_download(slider_url, 'slider')
45 |
46 | # 引用上面的图片下载
47 | captcha_path = pic_download(captcha_url, 'captcha')
48 |
49 | # # 计算拼图还原距离
50 | target = cv2.imread(slider_path, 0)
51 | template = cv2.imread(captcha_path, 0)
52 | w, h = target.shape[::-1]
53 | temp = save_path + '\\' + 'temp.jpg'
54 | targ = save_path + '\\' + 'targ.jpg'
55 | cv2.imwrite(temp, template)
56 | cv2.imwrite(targ, target)
57 | target = cv2.imread(targ)
58 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
59 | target = abs(255 - target)
60 | cv2.imwrite(targ, target)
61 | target = cv2.imread(targ)
62 | template = cv2.imread(temp)
63 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
64 | x, y = np.unravel_index(result.argmax(), result.shape)
65 | # 缺口位置
66 | # print((y, x, y + w, x + h))
67 |
68 | # 调用PIL Image 做测试
69 | image = Image.open(captcha_path)
70 |
71 | xy = (y, x, y + w, x + h)
72 | # 切割
73 | imagecrop = image.crop(xy)
74 | # 保存切割的缺口
75 | imagecrop.save(save_path + '\\' + "new_captcha.jpg")
76 | # imagecrop.show()
77 | return int(round(y))
78 |
--------------------------------------------------------------------------------
/tengxun/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/10 10:26
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : pic_locate.py
6 | # @Software: PyCharm
7 |
8 | import cv2
9 | import numpy as np
10 | from PIL import Image
11 | import os
12 |
13 |
14 | def _pic_download(session, url, type):
15 | """
16 | 图片下载
17 | :param url:
18 | :param type:
19 | :return:
20 | """
21 | save_path = os.path.abspath('...') + '\\' + 'images'
22 | if not os.path.exists(save_path):
23 | os.mkdir(save_path)
24 |
25 | img_path = save_path + '\\' + '{}.jpg'.format(type)
26 | # 请求多次保证图片下载成功, 有时第一次图片下载失败
27 | for _ in range(10):
28 | session.get(url)
29 | img_data = session.get(url).content
30 | with open(img_path, 'wb') as f:
31 | f.write(img_data)
32 | return img_path
33 |
34 |
35 | def get_distance(session, slider_url, captcha_url):
36 | """
37 | 获取缺口距离
38 | :param session:
39 | :param slider_url:
40 | :param captcha_url:
41 | :return:
42 | """
43 | save_path = os.path.abspath('...') + '\\' + 'images'
44 | if not os.path.exists(save_path):
45 | os.mkdir(save_path)
46 |
47 | # 引用上面的图片下载
48 | slider_path = _pic_download(session, slider_url, 'slider')
49 | w, h = Image.open(slider_path).size
50 |
51 | # 图片还原
52 | captcha_path = _pic_download(session, captcha_url, 'captcha')
53 |
54 | # # 计算拼图还原距离
55 | target = cv2.imread(slider_path, 0)
56 | template = cv2.imread(captcha_path, 0)
57 | temp = save_path + '\\' + 'temp.jpg'
58 | targ = save_path + '\\' + 'targ.jpg'
59 | cv2.imwrite(targ, target)
60 | cv2.imwrite(temp, template)
61 |
62 | target = cv2.imread(targ)
63 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
64 | target = abs(255 - target)
65 | cv2.imwrite(targ, target)
66 |
67 | target = cv2.imread(targ)
68 | template = cv2.imread(temp)
69 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
70 | x, y = np.unravel_index(result.argmax(), result.shape)
71 |
72 | # 调用PIL Image 做测试
73 | image = Image.open(captcha_path)
74 | xy = (y + 23, x, y + w, x + h)
75 | # 切割
76 | imagecrop = image.crop(xy)
77 | # 保存切割的缺口
78 | imagecrop.convert('RGB').save(save_path + '\\' + "new_captcha.jpg")
79 | # imagecrop.show()
80 | return int(y + 23)
81 |
--------------------------------------------------------------------------------
/city58/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/18 11:17
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import requests
10 | from PIL import Image
11 | import cv2
12 | import numpy as np
13 |
14 |
15 | def _pic_download(url, type):
16 | """
17 | 图片下载
18 | :param url:
19 | :param type:
20 | :return:
21 | """
22 | save_path = os.path.abspath('...') + '\\' + 'images'
23 | if not os.path.exists(save_path):
24 | os.mkdir(save_path)
25 | img_path = save_path + '\\' + '{}.jpg'.format(type)
26 | img_data = requests.get('https://verifycode.58.com' + url).content
27 | with open(img_path, 'wb') as f:
28 | f.write(img_data)
29 | return img_path
30 |
31 |
32 | def get_distance(slider_url, captcha_url):
33 | """
34 | 获取缺口距离
35 | :param slider_url:
36 | :param captcha_url:
37 | :return:
38 | """
39 | save_path = os.path.abspath('...') + '\\' + 'images'
40 | if not os.path.exists(save_path):
41 | os.mkdir(save_path)
42 |
43 | # 引用上面的图片下载
44 | slider_path = _pic_download(slider_url, 'slider')
45 | w, h = Image.open(slider_path).size
46 |
47 | # 图片还原
48 | captcha_path = _pic_download(captcha_url, 'captcha')
49 |
50 | # # 计算拼图还原距离
51 | target = cv2.imread(slider_path, 0)
52 | template = cv2.imread(captcha_path, 0)
53 | temp = save_path + '\\' + 'temp.jpg'
54 | targ = save_path + '\\' + 'targ.jpg'
55 | cv2.imwrite(targ, target)
56 | cv2.imwrite(temp, template)
57 |
58 | target = cv2.imread(targ)
59 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
60 | target = abs(255 - target)
61 | cv2.imwrite(targ, target)
62 |
63 | target = cv2.imread(targ)
64 | template = cv2.imread(temp)
65 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
66 | x, y = np.unravel_index(result.argmax(), result.shape)
67 |
68 | # 调用PIL Image 做测试
69 | image = Image.open(captcha_path)
70 |
71 | xy = (y, x, y + w, x + h)
72 | # 切割
73 | imagecrop = image.crop(xy)
74 | # 保存切割的缺口
75 | imagecrop.convert('RGB').save(save_path + '\\' + "new_image.jpg")
76 | imagecrop.show()
77 | return int(round(y))
78 |
79 |
80 | def process_img(captcha_url, type):
81 | """
82 | 下载验证码图片并重置尺寸
83 | :param captcha_url: 验证码图片
84 | :param type: 验证码类型
85 | :return:
86 | """
87 | img_path = _pic_download(captcha_url, type)
88 | img = Image.open(img_path).resize((280, 158))
89 | img.save(img_path)
90 | with open(img_path, 'rb') as f:
91 | img_data = f.read()
92 | return img_data
93 |
--------------------------------------------------------------------------------
/shumei/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 18:48
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 | import math
9 | import numpy as np
10 | import random
11 |
12 |
13 | def _generate_trace(distance):
14 | """
15 | 生成轨迹
16 | :param distance:
17 | :return:
18 | """
19 | sy = [0, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, 0, 0, 1]
20 | # 位移/轨迹列表
21 | tracks_list = []
22 | # 当前的位移
23 | current = 0
24 | while current <= distance - 35:
25 | move = random.randint(12, 30)
26 | current += move
27 | tracks_list.append(current)
28 | # 减速慢慢滑
29 | if current < distance - 12:
30 | move = random.randint(9, 12)
31 | current += move
32 | tracks_list.append(current)
33 | for i in range(round(current) + 1, distance + 1, 3):
34 | if current < distance - 3:
35 | current += 3
36 | tracks_list.append(current)
37 | else:
38 | tracks_list.append(distance)
39 | # 生成时间戳列表
40 | timestamp_list = []
41 | start = random.randint(100, 110)
42 | timestamp = start
43 | for i in range(len(tracks_list)):
44 | t = random.randint(99, 101)
45 | timestamp += t
46 | timestamp_list.append(timestamp)
47 | i += 1
48 | yy = random.randint(5, 8)
49 | trace = [[0, yy, random.choice([0, 1])], [0, yy, start]]
50 | for index, x in enumerate(tracks_list):
51 | trace.append([x, random.choice(sy), timestamp_list[index]])
52 | trace.append([distance, random.choice(sy), timestamp_list[-1] + random.randint(99, 101)])
53 | return trace
54 |
55 |
56 | def generate_trace(space):
57 | x = [0, 0]
58 | y = [0, 0, 0]
59 | z = [0]
60 | # x
61 | count = np.linspace(-math.pi / 2, math.pi / 2, random.randrange(20, 30))
62 | # print(count)
63 | func = list(map(math.sin, count))
64 | nx = [i + 1 for i in func]
65 | add = random.randrange(10, 15)
66 | sadd = space + add
67 | x.extend(list(map(lambda x: x * (sadd / 2), nx)))
68 | # x.extend(np.linspace(sadd, space, 4 if add > 12 else 3))
69 | x.extend(np.linspace(sadd, space, 3 if add > 12 else 2))
70 | x = [math.floor(i) for i in x]
71 | # y
72 | for i in range(len(x) - 2):
73 | if y[-1] < 30:
74 | y.append(y[-1] + random.choice([0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0]))
75 | else:
76 | y.append(y[-1] + random.choice([0, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0]))
77 | # z
78 | for i in range(len(x) - 1):
79 | z.append((z[-1] // 100 * 100) + 100 + random.choice([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]))
80 | return list(map(list, zip(x, y, z)))
81 |
--------------------------------------------------------------------------------
/eastmoney/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/24 21:35
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | from hashlib import md5
10 |
11 |
12 | class ChaojiyingClient(object):
13 |
14 | def __init__(self, username, password, soft_id):
15 | self.username = username
16 | password = password.encode('utf8')
17 | self.password = md5(password).hexdigest()
18 | self.soft_id = soft_id
19 | self.base_params = {
20 | 'user': self.username,
21 | 'pass2': self.password,
22 | 'softid': self.soft_id,
23 | }
24 | self.headers = {
25 | 'Connection': 'Keep-Alive',
26 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
27 | }
28 |
29 | def PostPic(self, im, codetype):
30 | """
31 | im: 图片字节
32 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
33 | """
34 | params = {
35 | 'codetype': codetype,
36 | }
37 | params.update(self.base_params)
38 | files = {'userfile': ('ccc.jpg', im)}
39 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
40 | return r.json()
41 |
42 | def ReportError(self, im_id):
43 | """
44 | im_id:报错题目的图片ID
45 | """
46 | params = {
47 | 'id': im_id,
48 | }
49 | params.update(self.base_params)
50 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
51 | return r.json()
52 |
53 |
54 | def image_to_text(img,
55 | username='*****',
56 | password='******',
57 | soft_id='497bc231401f085df56dae7c2e3a9b86',
58 | img_kind=1902):
59 | """
60 | 将图片转化为文字
61 | :param img: 验证码二进制数据
62 | :param username:用户名
63 | :param password: 密码
64 | :param soft_id: 软件id
65 | :param img_kind: 验证码类型
66 | :return:
67 | """
68 | chaojiying = ChaojiyingClient(username, password, soft_id)
69 | result = chaojiying.PostPic(img, img_kind)
70 | if result['err_no'] == 0:
71 | return True, result['pic_str']
72 | else:
73 | chaojiying.ReportError(result['pic_id'])
74 | return False, result['err_str']
75 |
76 |
77 | if __name__ == '__main__':
78 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
79 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
80 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
81 |
--------------------------------------------------------------------------------
/liepin/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 21:40
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='*******',
57 | password='*******',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/yidun/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 21:40
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='*******',
57 | password='********',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/city58/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 21:40
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='*******',
57 | password='*********',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/geetest3/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/14 17:46
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='******',
57 | password='********',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/luosimao/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 21:40
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='******',
57 | password='********',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/vaptcha/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/19 11:20
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | from hashlib import md5
11 |
12 |
13 | class ChaojiyingClient(object):
14 |
15 | def __init__(self, username, password, soft_id):
16 | self.username = username
17 | password = password.encode('utf8')
18 | self.password = md5(password).hexdigest()
19 | self.soft_id = soft_id
20 | self.base_params = {
21 | 'user': self.username,
22 | 'pass2': self.password,
23 | 'softid': self.soft_id,
24 | }
25 | self.headers = {
26 | 'Connection': 'Keep-Alive',
27 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
28 | }
29 |
30 | def PostPic(self, im, codetype):
31 | """
32 | im: 图片字节
33 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
34 | """
35 | params = {
36 | 'codetype': codetype,
37 | }
38 | params.update(self.base_params)
39 | files = {'userfile': ('ccc.jpg', im)}
40 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
41 | return r.json()
42 |
43 | def ReportError(self, im_id):
44 | """
45 | im_id:报错题目的图片ID
46 | """
47 | params = {
48 | 'id': im_id,
49 | }
50 | params.update(self.base_params)
51 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
52 | return r.json()
53 |
54 |
55 | def image_to_text(img,
56 | username='*******',
57 | password='********',
58 | soft_id='497bc231401f085df56dae7c2e3a9b86',
59 | img_kind=1902):
60 | """
61 | 将图片转化为文字
62 | :param img: 验证码二进制数据
63 | :param username:用户名
64 | :param password: 密码
65 | :param soft_id: 软件id
66 | :param img_kind: 验证码类型
67 | :return:
68 | """
69 | chaojiying = ChaojiyingClient(username, password, soft_id)
70 | result = chaojiying.PostPic(img, img_kind)
71 | if result['err_no'] == 0:
72 | return True, result['pic_str']
73 | else:
74 | chaojiying.ReportError(result['pic_id'])
75 | return False, result['err_str']
76 |
77 |
78 | if __name__ == '__main__':
79 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
80 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
81 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
82 |
--------------------------------------------------------------------------------
/wanmei/wm_crypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 19:35
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : wm_crypt.py
6 | # @Software: PyCharm
7 |
8 | import random
9 | import base64
10 | from Crypto.Cipher import AES
11 |
12 |
13 | class AESCipher:
14 |
15 | def __init__(self, key, iv):
16 | self.key = key.encode('utf-8')
17 | self.iv = iv.encode('utf-8')
18 |
19 | @staticmethod
20 | def pad(text):
21 | """
22 | 填充方式,加密内容必须为16字节的倍数,若不足则使用self.iv进行填充
23 | :param text:
24 | :return:
25 | """
26 | text_length = len(text)
27 | amount_to_pad = AES.block_size - (text_length % AES.block_size)
28 | if amount_to_pad == 0:
29 | amount_to_pad = AES.block_size
30 | pad = chr(amount_to_pad)
31 | return text + pad * amount_to_pad
32 |
33 | @staticmethod
34 | def unpad(text):
35 | pad = ord(text[-1])
36 | return text[:-pad]
37 |
38 | def encrypt(self, text):
39 | """
40 | 加密
41 | :param text: 明文
42 | :return:
43 | """
44 | raw = self.pad(text)
45 | cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
46 | return base64.b64encode(cipher.encrypt(raw.encode('utf-8'))).decode('utf-8')
47 |
48 | def decrypt(self, text):
49 | """
50 | 解密
51 | :param text: 密文
52 | :return:
53 | """
54 | enc = base64.b64decode(text)
55 | cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
56 | return self.unpad(cipher.decrypt(enc).decode("utf-8"))
57 |
58 |
59 | def generate_aes_key(cap_key):
60 | """
61 | 根据验证码 ID 生成 AES 密钥
62 | :return:
63 | """
64 | aes_key = cap_key[1: 3] + cap_key[10: 13] + cap_key[20: 22] + cap_key[26: 31] + cap_key[21:25]
65 | return aes_key
66 |
67 |
68 | def process_trace(trace):
69 | """
70 | 处理轨迹
71 | :param trace:
72 | :return:
73 | """
74 | if len(trace) <= 100:
75 | return trace
76 | new_trace = []
77 | i = 0
78 | for r in range(len(trace)):
79 | n = (100 - i) / (len(trace) - r)
80 | if n >= random.random():
81 | i = new_trace.append(trace[r])
82 | return new_trace
83 |
84 |
85 | def encrypt(cap_key, text):
86 | aes_key = generate_aes_key(cap_key)
87 | return AESCipher(aes_key, aes_key).encrypt(text)
88 |
89 |
90 | if __name__ == '__main__':
91 | encrypter = AESCipher("439346f77a5bf74d", "439346f77a5bf74d")
92 | enc_str = encrypter.encrypt('{"validate":"246,243,184,47,124,262,250,186","time":9196}')
93 | print('加密: ' + enc_str)
94 | dec_str = encrypter.decrypt(enc_str)
95 | print('解密: ' + dec_str)
96 | x = generate_aes_key("9546c1ec19a841c49e83d9e10411fe1f")
97 | print('AES 密钥: ', x)
98 |
--------------------------------------------------------------------------------
/anjuke/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/27 15:40
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | import time
11 | import json
12 | from anjuke.geetest import crack
13 | from bs4 import BeautifulSoup
14 |
15 |
16 | headers = {
17 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
18 | 'accept-encoding': 'gzip, deflate, br',
19 | 'accept-language': 'zh-CN,zh;q=0.9',
20 | 'referer': 'https://shanghai.anjuke.com/',
21 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'
22 | }
23 |
24 |
25 | def get_sessionid():
26 | url = 'https://www.anjuke.com/captcha-verify/?callback=shield&from=antispam'
27 | resp = requests.get(url, headers=headers)
28 | bsobj = BeautifulSoup(resp.text, 'lxml')
29 | session_id = bsobj.select('#sessionId')[0]['value']
30 | return session_id
31 |
32 |
33 | def get_captcha(session_id):
34 | url = 'https://verifycode.58.com/captcha/getV3'
35 | params = {
36 | 'callback': '',
37 | 'showType': 'embed',
38 | 'sessionId': session_id,
39 | '_': int(time.time() * 1000)
40 | }
41 | resp = requests.get(url, params=params, headers=headers)
42 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
43 | if result['message'] == '成功':
44 | if '描摹' in result['data']['tip']:
45 | return {
46 | 'status': 0,
47 | 'message': result['data']['tip']
48 | }
49 | bg = 'https://verifycode.58.com' + result['data']['bgImgUrl']
50 | response_id = result['data']['responseId']
51 | return {
52 | 'status': 1,
53 | 'data': {
54 | 'captcha_url': bg,
55 | 'response_id': response_id
56 | }
57 | }
58 | return {
59 | 'status': 0,
60 | 'message': '验证码初始化失败! '
61 | }
62 |
63 |
64 | def main():
65 | session_id = get_sessionid()
66 | init_data = get_captcha(session_id)
67 | if not init_data['status']:
68 | return {
69 | 'success': 0,
70 | 'message': init_data['message'],
71 | 'data': None
72 | }
73 | result = crack(init_data['data']['captcha_url'], session_id, init_data['data']['response_id'])
74 | return result
75 |
76 |
77 | if __name__ == '__main__':
78 | print('开始测试...')
79 | print('=' * 100)
80 | num = 1
81 | success = 0
82 | while num <= 20:
83 | x = main()
84 | print(x)
85 | if x['success']:
86 | success += 1
87 | time.sleep(5)
88 | num += 1
89 | print('最后测试结果 >> %.2f%%' % success)
90 |
--------------------------------------------------------------------------------
/dajie/chaojiying.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/14 17:46
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : chaojiying.py
6 | # @Software: PyCharm
7 |
8 |
9 | # -*- coding: utf-8 -*-
10 | # @Time : 2019/10/9 21:40
11 | # @Author : Esbiya
12 | # @Email : 18829040039@163.com
13 | # @File : chaojiying.py
14 | # @Software: PyCharm
15 |
16 |
17 | import requests
18 | from hashlib import md5
19 |
20 |
21 | class ChaojiyingClient(object):
22 |
23 | def __init__(self, username, password, soft_id):
24 | self.username = username
25 | password = password.encode('utf8')
26 | self.password = md5(password).hexdigest()
27 | self.soft_id = soft_id
28 | self.base_params = {
29 | 'user': self.username,
30 | 'pass2': self.password,
31 | 'softid': self.soft_id,
32 | }
33 | self.headers = {
34 | 'Connection': 'Keep-Alive',
35 | 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
36 | }
37 |
38 | def PostPic(self, im, codetype):
39 | """
40 | im: 图片字节
41 | codetype: 题目类型 参考 http://www.chaojiying.com/price.html
42 | """
43 | params = {
44 | 'codetype': codetype,
45 | }
46 | params.update(self.base_params)
47 | files = {'userfile': ('ccc.jpg', im)}
48 | r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
49 | return r.json()
50 |
51 | def ReportError(self, im_id):
52 | """
53 | im_id:报错题目的图片ID
54 | """
55 | params = {
56 | 'id': im_id,
57 | }
58 | params.update(self.base_params)
59 | r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
60 | return r.json()
61 |
62 |
63 | def image_to_text(img,
64 | username='*******',
65 | password='*******',
66 | soft_id='497bc231401f085df56dae7c2e3a9b86',
67 | img_kind=1902):
68 | """
69 | 将图片转化为文字
70 | :param img: 验证码二进制数据
71 | :param username:用户名
72 | :param password: 密码
73 | :param soft_id: 软件id
74 | :param img_kind: 验证码类型
75 | :return:
76 | """
77 | chaojiying = ChaojiyingClient(username, password, soft_id)
78 | result = chaojiying.PostPic(img, img_kind)
79 | if result['err_no'] == 0:
80 | return True, result['pic_str']
81 | else:
82 | chaojiying.ReportError(result['pic_id'])
83 | return False, result['err_str']
84 |
85 |
86 | if __name__ == '__main__':
87 | chaojiying = ChaojiyingClient('******', '*******', '96001') # 用户中心>>软件ID 生成一个替换 96001
88 | im = open('captcha.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
89 | print(chaojiying.PostPic(im, 1902)) # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
90 |
--------------------------------------------------------------------------------
/shumei/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 18:47
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import cv2
10 | import requests
11 | import numpy as np
12 | from PIL import Image
13 |
14 |
15 | def _pic_download(url, type):
16 | """
17 | 图片下载
18 | :param url:
19 | :param type:
20 | :return:
21 | """
22 | save_path = os.path.abspath('...') + '\\' + 'images'
23 | if not os.path.exists(save_path):
24 | os.mkdir(save_path)
25 |
26 | img_path = save_path + '\\' + '{}.jpg'.format(type)
27 | img_data = requests.get(url).content
28 | with open(img_path, 'wb') as f:
29 | f.write(img_data)
30 | return img_path
31 |
32 |
33 | def get_distance(captcha_url):
34 | """
35 | 获取缺口距离
36 | :param captcha_url:
37 | :return:
38 | """
39 | save_path = os.path.abspath('...') + '\\' + 'images'
40 | if not os.path.exists(save_path):
41 | os.mkdir(save_path)
42 |
43 | # 引用上面的图片下载
44 | slider_path = save_path + '\\' + 'slider.jpg'
45 | w, h = Image.open(slider_path).size
46 |
47 | # 引用上面的图片下载
48 | captcha_path = _pic_download(captcha_url, 'captcha')
49 |
50 | # 计算拼图还原距离
51 | target = cv2.imread(slider_path, 0)
52 | template = cv2.imread(captcha_path, 0)
53 |
54 | temp = save_path + '\\' + 'temp.jpg'
55 | targ = save_path + '\\' + 'targ.jpg'
56 | cv2.imwrite(temp, template)
57 | cv2.imwrite(targ, target)
58 |
59 | target = cv2.imread(targ)
60 | template = cv2.imread(temp)
61 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
62 | x, y = np.unravel_index(result.argmax(), result.shape)
63 |
64 | # 调用PIL Image 做测试
65 | image = Image.open(captcha_path)
66 |
67 | xy = (y, x, y + w, x + h)
68 | # 切割
69 | imagecrop = image.crop(xy)
70 | # 保存切割的缺口
71 | imagecrop.save(save_path + '\\' + "new_image.png")
72 | imagecrop.show()
73 | return int(y)
74 |
75 |
76 | def _get_distance(captcha_url):
77 | """
78 | 获取缺口距离
79 | :param captcha_url: 验证码 url
80 | :return:
81 | """
82 | save_path = os.path.abspath('...') + '\\' + 'images'
83 | if not os.path.exists(save_path):
84 | os.mkdir(save_path)
85 |
86 | img_path = _pic_download(captcha_url, 'captcha')
87 | img1 = cv2.imread(img_path, 0)
88 | img2 = cv2.imread(save_path + '\\' + "slider.jpg", 0)
89 | res = cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED)
90 | loc = np.where(res >= 0.6)
91 | for pt in zip(*loc[::-1]):
92 | p = pt
93 | try:
94 | cv2.imshow('Detected', img1[p[1]:, p[0]:])
95 | cv2.waitKey(3000)
96 | except Exception as e:
97 | print(e.args)
98 | return None
99 | res = cv2.resize(img1, (255, int(300 * (255 / 600))), interpolation=cv2.INTER_CUBIC)
100 | cv2.imshow("res", res[:, int(p[0] * (255 / 600) + 15):])
101 | # cv2.waitKey(3000)
102 | return int(p[0] * (290 / 600))
103 |
--------------------------------------------------------------------------------
/yidun/generate_fp.js:
--------------------------------------------------------------------------------
1 | // 删除关键js, 请自行补全
2 |
3 | function generateFingerprint() {
4 | var e = !0
5 | , n = {
6 | v: s[180]
7 | }
8 | , p = null;
9 | p && (n[l[6]] = p),
10 | p = null,
11 | n[s[61]] = "id.163yun.com";
12 | var h = (new Date).getTime() + 900000
13 | , _ = h + t[302] * t[142] * t[142] * t[68] * t[297] * t[20];
14 | n[s[86]] = $(t[13]) + h + $(t[13]);
15 | var S = m();
16 | n[s[135]] = S.join(u[35]);
17 | var w = p = JSON.stringify(n)
18 | , n = "14731255234d414cF91356d684E4E8F5F56c8f1bc";
19 | null != w && void 0 != w || (w = u[0]);
20 | var E, S = w;
21 | E = o_(null == w ? [] : d(w));
22 | var R = d(S + E)
23 | , k = d(n);
24 | null == R && (R = []),
25 | E = [];
26 | for (var C = t[9]; C < 4; C++) {
27 | var X = Math.random() * t[295]
28 | , X = Math.floor(X);
29 | E[C] = g(X)
30 | }
31 | var I, k = r_(k), k = y(k, r_(E)), C = k = r_(k);
32 | I = f_(64);
33 | D = I;
34 | I = [];
35 | for (var F = t[9], U = D.length / 64, V = t[9]; V < U; V++) {
36 | I[V] = [];
37 | for (var W = t[9]; W < 64; W++)
38 | I[V][W] = D[F++]
39 | }
40 | F = [],
41 | j(E, t[9], F, t[9], 4);
42 | for (var K = I.length, J = t[9]; J < K; J++) {
43 | var q, Q, Z = I[J];
44 | if (null == Z)
45 | Q = null;
46 | else {
47 | for (var ee = g(t[92]), U = [], te = Z.length, ne = t[9]; ne < te; ne++)
48 | U.push(v(Z[ne], ee));
49 | Q = U
50 | }
51 | var re;
52 | if (U = Q,
53 | null == U)
54 | re = null;
55 | else {
56 | for (var je = g(t[91]), V = [], ce = U.length, ve = t[9]; ve < ce; ve++)
57 | V.push(v(U[ve], je--));
58 | re = V
59 | }
60 | if (U = re,
61 | null == U)
62 | q = null;
63 | else {
64 | for (var be = g(t[110]), V = [], _e = U.length, Se = t[9]; Se < _e; Se++)
65 | V.push(b(U[Se], be++));
66 | q = V
67 | }
68 | var Te, we = y(q, k);
69 | if (U = we,
70 | V = C,
71 | null == U)
72 | Te = null;
73 | else if (null == V)
74 | Te = U;
75 | else {
76 | for (var W = [], Ee = V.length, Re = t[9], ke = U.length; Re < ke; Re++)
77 | W[Re] = g(U[Re] + V[Re % Ee]);
78 | Te = W
79 | }
80 | var we = y(Te, C)
81 | , Ce = i_(we)
82 | , Ce = i_(Ce);
83 | j(Ce, t[9], F, J * 64 + 4, 64),
84 | C = Ce
85 | }
86 | var Xe;
87 | var Oe = t[13];
88 | for (var K = [], $e = t[9]; $e < F.length;) {
89 | if (!($e + Oe <= F.length)) {
90 | K.push(a_(F, $e, F.length - $e));
91 | break
92 | }
93 | K.push(a_(F, $e, Oe)),
94 | $e += Oe
95 | }
96 | Xe = K.join(u[0]);
97 | return Xe + s[7] + h
98 | }
99 |
100 | console.log(generateFingerprint());
101 |
--------------------------------------------------------------------------------
/luosimao/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/11 8:48
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import requests
10 | from PIL import Image
11 | from PIL import ImageFont
12 | from PIL import ImageDraw
13 |
14 |
15 | def _pic_download(url, type):
16 | """
17 | 图片下载
18 | :param url:
19 | :param type:
20 | :return:
21 | """
22 | save_path = os.path.abspath('...') + '\\' + 'images'
23 | if not os.path.exists(save_path):
24 | os.mkdir(save_path)
25 |
26 | img_path = save_path + '\\' + '{}.jpg'.format(type)
27 | img_data = requests.get(url).content
28 | with open(img_path, 'wb') as f:
29 | f.write(img_data)
30 | return img_path
31 |
32 |
33 | def make_word(text):
34 | """
35 | 制作描述图片
36 | :return:
37 | """
38 | save_path = os.path.abspath('...') + '\\' + 'images'
39 | if not os.path.exists(save_path):
40 | os.mkdir(save_path)
41 |
42 | text = text.replace('', '').replace('', '')
43 | # 初始化图片对象, (300, 30)为图片大小, (255, 255, 255) 为白色背景
44 | img = Image.new('RGB', (300, 30), (255, 255, 255))
45 | # 设置字体
46 | font = ImageFont.truetype('simsun.ttc', 15)
47 | # 初始化写入对象
48 | draw = ImageDraw.Draw(img)
49 | # 添加文字, (0, 0): 文字起始坐标, (0, 0, 0): 颜色(黑色), font: 字体
50 | draw.text((0, 0), text, (0, 0, 0), font=font)
51 | # img.show()
52 | img_path = save_path + '\\' + 'word.jpg'
53 | img.save(img_path)
54 | return img_path
55 |
56 |
57 | def reduce_image(location_list, url):
58 | """
59 | 根据还原数组还原验证码图片
60 | :param location_list: 图片位置数组
61 | :param url: 图片 url
62 | :return:
63 | """
64 | img_path = _pic_download(url, 'captcha')
65 | im = Image.open(img_path)
66 |
67 | new_im = Image.new('RGB', im.size)
68 |
69 | upper_list = location_list[:15]
70 | lower_list = location_list[15:]
71 |
72 | x_offset = 0
73 | for location in upper_list:
74 | imgcrop = im.crop((int(location[0]), int(location[1]), int(location[0]) + 20, int(location[1]) + 80))
75 | new_im.paste(imgcrop, (x_offset, 0))
76 | x_offset += 20
77 |
78 | x_offset = 0
79 | for location in lower_list:
80 | imgcrop = im.crop((int(location[0]), int(location[1]), int(location[0]) + 20, int(location[1]) + 80))
81 | new_im.paste(imgcrop, (x_offset, 80))
82 | x_offset += 20
83 |
84 | # new_im.show()
85 | new_im.save(img_path)
86 | return img_path
87 |
88 |
89 | def merge_word(img1, img2):
90 | """
91 | 将描述性文字合并到验证码图片上, 以便交给打码平台识别
92 | :return:
93 | """
94 | save_path = os.path.abspath('...') + '\\' + 'images'
95 | if not os.path.exists(save_path):
96 | os.mkdir(save_path)
97 | new_image = Image.new('RGB', (300, 190))
98 | img1 = Image.open(img1)
99 | new_image.paste(img1, (0, 0))
100 |
101 | img2 = Image.open(img2)
102 | new_image.paste(img2, (0, 160))
103 |
104 | new_image.show()
105 | img_path = save_path + '\\' + 'new_captcha.jpg'
106 | new_image.save(img_path)
107 | return img_path
108 |
109 |
--------------------------------------------------------------------------------
/xiecheng/xc_slider.js:
--------------------------------------------------------------------------------
1 |
2 | function init_encrypt(sfp) {
3 | var S = {
4 | rt: "fp=13awamm-1dc6k9j-zf90ov&vid=1563080773482.2fun2q&pageId=&r=7e44164fbc7d4f968bed98b669ae54d5&ip=223.152.39.68&rg=undefined&kpData=0_0_0&kpControl=0_0_0-0_0_0&kpEmp=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_0_0_0&screen=1366x768&tz=+8&blang=zh-CN&oslang=zh-CN&ua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F75.0.3770.80%20Safari%2F537.36&d=passport.ctrip.com&v=22",
5 | ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36",
6 | p: "pc",
7 | fp: "13awamm-1dc6k9j-zf90ov",
8 | vid: null,
9 | sfp: sfp,
10 | svid: "Rq%3D-xh%24A!%7C%400AI%25%23u%23DFB%7DXhF(",
11 | guid: null,
12 | h5_duid: null,
13 | pc_duid: null,
14 | hb_uid: null,
15 | pc_uid: null,
16 | h5_uid: null,
17 | infosec_openid: null,
18 | device_id: ib(32, 3, "_bfs"),
19 | client_id: ib(32, 0, "_bfi"),
20 | pid: ib(16, 2, "corpid"),
21 | sid: ib(16, 1, "SMBID"),
22 | login_uid: ib(10, 2, "login_uid")
23 | },
24 | Db = {
25 | resolution_width: 1366,
26 | resolution_height: 768,
27 | language: "zh-CN"
28 | };
29 | var X = I(JSON.stringify(S), 0),
30 | ea = I(JSON.stringify(Db), 0),
31 | ra = C.MD5("appid=" + 100008493 + "&business_site=" + "crm_sms_online" + "&version=" + "2.5.31" + "&dimensions=" + X + "&extend_param=" + ea);
32 | return {
33 | dimensions: X,
34 | extend_param: ea,
35 | sign: ra.toString()
36 | }
37 | }
38 |
39 | // console.log(init_encrypt());
40 |
41 | function get_verify_msg(data) {
42 | return I(data, 0)
43 | }
44 | // console.log(get_verify_msg('{"st":1570097582399,"slidingTime":426,"display":"1366x768","keykoardTrack":[],"slidingTrack":[{"x":336,"y":253},{"x":353,"y":253},{"x":378,"y":254},{"x":390,"y":255},{"x":400,"y":256},{"x":415,"y":257},{"x":426,"y":257},{"x":435,"y":258},{"x":443,"y":258},{"x":450,"y":259},{"x":456,"y":259},{"x":465,"y":261},{"x":477,"y":261},{"x":486,"y":263},{"x":496,"y":264},{"x":502,"y":265},{"x":508,"y":266},{"x":515,"y":267},{"x":521,"y":267},{"x":526,"y":268},{"x":532,"y":268},{"x":535,"y":268},{"x":538,"y":268},{"x":542,"y":268},{"x":545,"y":268},{"x":549,"y":267},{"x":553,"y":266},{"x":560,"y":265},{"x":567,"y":264},{"x":574,"y":262},{"x":581,"y":262},{"x":588,"y":262},{"x":591,"y":262},{"x":595,"y":262},{"x":598,"y":262}],"timezone":-480,"flashState":false,"language":"zh-CN","platform":"Win32","cpuClass":undefined,"hasSessStorage":true,"hasLocalStorage":true,"hasIndexedDB":true,"hasDataBase":true,"doNotTrack":false,"touchSupport":false,"mediaStreamTrack":true}'))
45 |
46 | function verify_encrypt(verify_msg, dimensions) {
47 | var ea = "iSGlZQho4OSS/KGB9EdMa4gs7/aOolEsmfreUUGCzkYnLgC1AIjYbIE3CK3ICeMvDgY8mdt4SZaP9R3sESMrKTUJI77Mw+Myw7MabSpqYmTwvU4v53bDBOiB8/V0GSZaARtsr5b5SdF7+AsEcVKKQ6/BPidZ/wyPxqDO1KovoAe7zM9T6Ib2TGojr9EfzVYQ",
48 | ra = C.MD5("appid=100008493&business_site=crm_crm_online&version=2.5.31&verify_msg=" + verify_msg + "&dimensions=" + dimensions + "&extend_param=" + ea);
49 | return ra.toString()
50 | }
51 |
--------------------------------------------------------------------------------
/yidun/yd_slider.js:
--------------------------------------------------------------------------------
1 | // 关键 js 已删除, 请自行补全
2 |
3 | function slider_encrypt(token, trace, width) {
4 | var new_trace = process_trace(token, trace),
5 | n_ = b_sample(new_trace, 50),
6 | r_ = t.eypt(t.xor_encode(token, parseInt(trace[trace.length - 1][0] - trace[0][0] + "px", 10) / width * 100 + ""));
7 | return {
8 | d: t.eypt(n_.join(":")),
9 | m: "",
10 | p: r_,
11 | ext: t.eypt(t.xor_encode(token, 1 + "," + new_trace.length))
12 | }
13 | }
14 |
15 | function RandomNum(min, max) {
16 | return Math.floor(Math.random() * (max - min)) + min + 1
17 | }
18 |
19 | function click_encrypt(token, trace, position) {
20 | var new_position = [];
21 | var new_trace = process_trace(token, trace),
22 | n_ = b_sample(new_trace, 50);
23 | var start_time = RandomNum(2000, 5000);
24 | for (var i = 0, j = position.length; i < j; i++) {
25 | var z = start_time + RandomNum(1000, 2000);
26 | var k = t.xor_encode(token, [position[i][0], position[i][1], z] + "");
27 | new_position.push(k)
28 | }
29 | return {
30 | d: "",
31 | m: t.eypt(n_.join(':')),
32 | p: t.eypt(new_position.join(':')),
33 | ext: t.eypt(t.xor_encode(token, position.length + "," + n_.length))
34 | }
35 | }
36 |
37 |
38 | function sense_encrypt(token, trace, position) {
39 | var new_trace = process_trace(token, trace);
40 | return {
41 | d: "",
42 | m: t.eypt(b_sample(new_trace, 50).join(':')),
43 | p: t.eypt(t.xor_encode(token, position)),
44 | ext: t.eypt(t.xor_encode(token, "1," + trace.length))
45 | }
46 | }
47 |
48 | // console.log(process_trace("8df1e4d682d94d14a4b62a6dda9be30f", [[1, 0, 36], [5, 0, 53], [12, 0, 64], [21, 0, 81], [33, 0, 95], [45, 0, 106], [61, 0, 117], [79, 0, 135], [104, 1, 148], [118, 0, 162], [138, 0, 176], [169, 1, 190], [201, 0, 206], [202, 0, 221], [203, 0, 235], [204, 0, 249], [205, 0, 264], [206, 0, 282], [207, 2, 297], [208, 0, 309], [209, 0, 326], [210, 0, 344], [211, 0, 355], [212, 0, 369], [213, 0, 384], [214, 0, 402], [215, 2, 417], [216, 0, 435], [217, 0, 447], [218, 0, 462], [219, 0, 479], [220, 0, 495], [221, 0, 512], [222, 0, 530], [223, 0, 546], [224, 0, 559], [225, 0, 572], [226, 0, 586], [227, 0, 603], [228, 0, 616], [229, 0, 634], [230, 0, 650], [231, 0, 665], [232, 0, 680]],));
49 | // console.log(click_encrypt(
50 | // "8df1e4d682d94d14a4b62a6dda9be30f",
51 | // [[1, 0, 36], [5, 0, 53], [12, 0, 64], [21, 0, 81], [33, 0, 95], [45, 0, 106], [61, 0, 117], [79, 0, 135], [104, 1, 148], [118, 0, 162], [138, 0, 176], [169, 1, 190], [201, 0, 206], [202, 0, 221], [203, 0, 235], [204, 0, 249], [205, 0, 264], [206, 0, 282], [207, 2, 297], [208, 0, 309], [209, 0, 326], [210, 0, 344], [211, 0, 355], [212, 0, 369], [213, 0, 384], [214, 0, 402], [215, 2, 417], [216, 0, 435], [217, 0, 447], [218, 0, 462], [219, 0, 479], [220, 0, 495], [221, 0, 512], [222, 0, 530], [223, 0, 546], [224, 0, 559], [225, 0, 572], [226, 0, 586], [227, 0, 603], [228, 0, 616], [229, 0, 634], [230, 0, 650], [231, 0, 665], [232, 0, 680]],
52 | // [[213, 62], [48, 84], [147, 40]]
53 | // ));
54 | // console.log(get_cb());
55 |
56 | function NN(e) {
57 | var t = {
58 | "\\": "-",
59 | "/": "_",
60 | "+": "."
61 | };
62 | return e.replace(/[\\\/+]/g, function (e) {
63 | return t[e]
64 | })
65 | }
66 |
67 | function encrypt_validate(validate, fp) {
68 | return NN(t.eypt(validate + "::" + fp))
69 | }
70 |
--------------------------------------------------------------------------------
/city58/c58_crypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/18 11:04
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : 58_crypt.py
6 | # @Software: PyCharm
7 |
8 |
9 | from Crypto.Cipher import AES
10 | from binascii import b2a_hex
11 |
12 |
13 | def aes_encrypt(key, iv, text):
14 | """
15 | AES CBC Pkcs7填充
16 | :param key: 密钥
17 | :param iv: 偏移量
18 | :param text: 明文
19 | :return:
20 | """
21 | bs = AES.block_size
22 | # pkcs7 填充
23 | pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
24 | encrypter = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
25 | cipher_text = encrypter.encrypt(pad(text).encode())
26 | return b2a_hex(cipher_text).decode()
27 |
28 |
29 | if __name__ == '__main__':
30 | text = '{"x":"76","track":"29,16,1|30,16,93|32,17,114|35,18,130|39,18,148|45,19,165|52,20,180|59,20,196|63,20,213|66,20,231|68,20,247|71,20,264|76,20,280|79,20,296|82,20,314|86,20,329|90,21,346|95,21,364|98,21,379|101,21,396|103,21,413|105,21,430|108,21,446|111,21,463|115,21,480|117,21,497|119,21,514|122,21,531|125,21,546|128,21,564|132,21,580|133,22,596|134,22,616|135,22,630|136,22,647|137,22,663|140,22,679|142,22,696|144,22,713|146,22,729|147,22,746|149,22,763|151,22,779|152,22,796|153,22,828|154,22,850|155,22,863|156,23,879|158,23,896|161,23,913|163,23,929|164,23,947|165,23,964|166,23,980|167,23,1013|168,23,1049|168,24,1067|169,24,1082|170,24,1216|171,24,1371|172,24,1442|173,24,1500|173,25,1513|174,25,1624|175,25,1754|176,25,1796|177,25,2821|177,25,3329|","p":"0,0","finger":"tUGrNESxtIBvCy3gqA4uX1IPaRsVRGeOY2E9NFsWZMYWxDHQtHKCll5ANR7RUCKiin35brBb//eSODvMgkQULA=="}'
31 | response_id = "93b77d6fe53b4196aec830b898bfaae6"
32 | x = aes_encrypt(response_id[0:16], response_id[0:16], text).upper()
33 | print(x)
34 | print('009B4DCD27961F6BBB20AD3EA46394E3D2AA6B6B0E9FAD272A960D47EFBDF5DC6C2E3BC153CD409F058F0723C62447EF6223B4FCBA3E429E1275AC4E9771CEF8112A3BA7C16CC31B823F2096A0A168FB79EFD24EB802EBEA38A3EC0CE1B2692AA21C6B525DCB02F8FC8E497E72DC234D951D50CDA6809E5622E5854851279635D001B42D005AA3ACD1DC35A37AADF91996E75961AD379F7089BD0BE1C1FB5BD128BC8C786E6A0708777145269BDB7608083BC1D79E37943EB260493C9B6E56D08C84D615E6D9D4FF98E7EC2D7BDD5BD57C2131CC163B0326AB6973C7424478E6CA4DE435A9B8EF95423C0F4EE9035FD82299B21F8009CEEC857F95705E9717F7A6E824A7995EC1952543818983034EDF343E5229CE23943DE0ED0530E8DE7253F2AC7FC5ECF21F6E4EC5C1A647F7B206974594EA17C6961F1C41A2F1CFD39B04F3E14D3337889EA7E5C3FC531243808F3A5D964127FFC8B613C043322E049FEEF9168C653C6DD1175436B671F71FF52A243AF99765034FCA5AE97E7E45910BD3B3432F0A88A8FFF0AF2E176E6E8161424DB17D70105413A53064C79EC854F93F5D187F9F8E8BEC2960783E28E330F44C5825331AF57B0EA874FCE99E448E249F2976D0875D6E5BD653FBF2CE4FF277189B098C6FBC4BFBB228D9E85FC4EAD1AE59D154C7AE1DE6F4B808AB7D88826C088C6C7D11C47A6C624F7FCBF0B19A43ACF4DB6808887D8DEC3C376527B0FD7E9F28A568B5BECDF0BB46B7AF17A194DA119C051B5DC0B57C4582018EF77D7C2C81ADAE63376CBDD3DE6EBB3CE408E2C7CC76E950E99EBA4F62BFAD41EF963144CA699B0ABAEB3903D9D935C14728CF1AA2B5AB8B199CEFAD04FAA320E84A8D2F28AED3D027B5048C256D3923049B6E5C7DDB71B4B4AB90CD860E336EF287CEFF83CB204BB5A1D2BF1BB590852961344F516B90C98E788CF6E511519A123DBC01561BCDC13C5C72E41BD3AA3008DE386CD4915A8CB08297001483B4E838194A60568A068049828B6B73B9652D90D6CAC54FCB4775AB13B19C3C17EEF18E1A1981A9ED4A3F72B266DEEC093C11AEA3980EA74E3952D8BC9ECCB450A70703407F8125B983701E8B9D7E338C1C69BCF07146CEE118A6A7F6903D37C5E78910E455FAAE054868FA2611C328679E7B16101A1DC41B36E0467E4B28C6F6AD3655540C86B86FDD48FE9A566F7FA737A25D95EA3530543763EF92F7B826D49C4A87DC1FAFEF')
--------------------------------------------------------------------------------
/meituan/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/26 15:23
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : crack.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import execjs
10 |
11 |
12 | def _reload_js():
13 | """
14 | 加载 js
15 | :return:
16 | """
17 | with open('./slider.js', 'rb') as f:
18 | slider_js = f.read().decode()
19 | return slider_js
20 |
21 |
22 | def _get_behavior_token(slider_js, page_data):
23 | ctx = execjs.compile(slider_js)
24 | verify_data = ctx.call('get_behavior_token', page_data)
25 | return verify_data
26 |
27 |
28 | def _init_slider(session, request_code):
29 | """
30 | 初始化滑块
31 | :param session:
32 | :param request_code:
33 | :return:
34 | """
35 | data = {
36 | 'requestCode': request_code,
37 | 'feVersion': '1.4.0',
38 | 'source': '1'
39 | }
40 | url = 'https://verify.meituan.com/v2/ext_api/page_data'
41 | result = session.post(url, data=data).json()
42 | if result['status']:
43 | return result['data']
44 | return None
45 |
46 |
47 | def _slider_verify(session, request_code, verify_data):
48 | """
49 | 滑块风控验证
50 | :param session
51 | :param request_code:
52 | :param verify_data
53 | :return:
54 | """
55 |
56 | url = 'https://verify.meituan.com/v2/ext_api/merchantlogin/verify?id=71'
57 |
58 | session.headers.update({
59 | 'Authorization': 'Bearer ' + request_code,
60 | 'Content-Type': 'application/x-www-form-urlencoded',
61 | 'Origin': 'https://epassport.meituan.com',
62 | })
63 | data = {
64 | 'request_code': request_code,
65 | 'behavior': verify_data['behavior'],
66 | 'fingerprint': '',
67 | '_token': verify_data['token'],
68 | }
69 | result = session.post(url, data=data).json()
70 | if result['status']:
71 | print('成功通过滑块验证!')
72 | return result['data']['response_code']
73 | return None
74 |
75 |
76 | def crack(request_code):
77 | session = requests.session()
78 | session.headers = {
79 | 'Referer': 'https://epassport.meituan.com/account/unitivelogin?bg_source=3&service=waimai&platform=2&continue=http://e.waimai.meituan.com/v2/epassport/entry&left_bottom_link=%2Faccount%2Funitivesignup%3Fbg_source%3D3%26service%3Dwaimai%26platform%3D2%26continue%3Dhttp%3A%2F%2Fe.waimai.meituan.com%2Fv2%2Fepassport%2FsignUp%26extChannel%3Dwaimaie%26ext_sign_up_channel%3Dwaimaie&right_bottom_link=%2Faccount%2Funitiverecover%3Fbg_source%3D3%26service%3Dwaimai%26platform%3D2%26continue%3Dhttp%3A%2F%2Fe.waimai.meituan.com%2Fv2%2Fepassport%2FchangePwd',
80 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
81 | }
82 | slider_js = _reload_js()
83 | page_data = None
84 | for _ in range(5):
85 | page_data = _init_slider(session, request_code)
86 | if page_data:
87 | break
88 | if not page_data:
89 | return None
90 | verify_data = _get_behavior_token(slider_js, page_data)
91 | response_code = _slider_verify(session, request_code, verify_data)
92 | if response_code:
93 | return {
94 | 'success': 1,
95 | 'message': '校验成功! ',
96 | 'data': {
97 | 'response_code': response_code
98 | }
99 | }
100 | return {
101 | 'success': 0,
102 | 'message': '校验失败! ',
103 | 'data': None
104 | }
105 |
106 |
107 | if __name__ == '__main__':
108 | pass
109 |
--------------------------------------------------------------------------------
/vaptcha/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/19 13:52
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 | import numpy as np
9 | from numpy import *
10 | import matplotlib.pyplot as plt
11 |
12 |
13 | def plot_line(x, y, xrange=None, yrange=None):
14 | """
15 | :param x: x list
16 | :param y: y list
17 | :param xrange: x坐标范围
18 | :param yrange: y坐标范围
19 | :return: 画出折线图
20 | """
21 | fig = plt.figure()
22 | ax = fig.add_subplot(3, 2, 1)
23 | ax.plot(np.array(x), np.array(y))
24 |
25 | ax.set_xlabel('x')
26 | ax.set_ylabel('y')
27 | if not xrange:
28 | ax.set_xlim(xrange)
29 | if not yrange:
30 | ax.set_ylim(yrange)
31 |
32 | ax.invert_yaxis()
33 | plt.show()
34 |
35 |
36 | def get_func(x, y):
37 | """
38 | 传入xlist, ylist
39 | list长度3
40 | 生成一个一元二次方程
41 | :param x:
42 | :param y:
43 | :return:
44 | """
45 | if len(x) != len(y):
46 | raise Exception("Error: len(x) != len(y)")
47 | temp_mat = mat(zeros((3, 3)))
48 | for i in range(0, 3):
49 | temp_mat[0, i] = pow(x[i], 2)
50 | temp_mat[1, i] = x[i]
51 | temp_mat[2, i] = 1
52 | temp_mat_inv = np.linalg.inv(temp_mat)
53 | temp_y = mat(array(y))
54 | parameter_abc = temp_y * temp_mat_inv
55 | list_abc = []
56 | for i in range(0, 3):
57 | list_abc.append(parameter_abc[0, i])
58 | return list_abc
59 |
60 |
61 | def generate_trace(position, size):
62 | """
63 | 生成轨迹
64 | :param position: 手势的四个坐标
65 | :param size: 验证码图片尺寸
66 | :return:
67 | """
68 | x = []
69 | y = []
70 | for i in position:
71 | x.append(int(i.split(',')[0]))
72 | y.append(int(i.split(',')[1]))
73 |
74 | trace_x = []
75 | trace_y = []
76 | for _ in range(0, 2):
77 | tepx = [x[_], x[_ + 1], x[_ + 2]]
78 | tepy = [y[_], y[_ + 1], y[_ + 2]]
79 | [a, b, c] = get_func(tepx, tepy)
80 | if _ == 0:
81 | for i in range(x[0], x[1]):
82 | trace_x.append(i)
83 | trace_y.append(a * i * i + b * i + c)
84 | for i in range(x[1], x[2]):
85 | trace_x.append(i)
86 | if random.randint(1, 5) == 1:
87 | trace_y.append((((float)(y[2] - y[1])) / (x[2] - x[1])) * (i - x[1]) + y[1] + random.randint(-1, 1))
88 | else:
89 | trace_y.append((((float)(y[2] - y[1])) / (x[2] - x[1])) * (i - x[1]) + y[1])
90 | else:
91 | for i in range(x[2], x[3]):
92 | trace_x.append(i)
93 | trace_y.append(a * i * i + b * i + c)
94 | trace_x = [int(i) for i in trace_x]
95 | trace_y = [int(i) for i in trace_y]
96 | last_trace_x = []
97 | last_trace_y = []
98 | plot_line(trace_x, trace_y, [0, size[0]], [0, size[1]])
99 | xx = 0
100 | while xx < len(trace_x) - 1:
101 | last_trace_x.append(trace_x[xx])
102 | last_trace_y.append(trace_y[xx])
103 | xx += random.randint(1, 4)
104 | last_trace_x.append(trace_x[-1])
105 | last_trace_y.append(trace_y[-1])
106 |
107 | timestamp_list = [random.randint(5, 20)]
108 | timestamp = random.randint(100, 200)
109 | for i in range(len(last_trace_x) - 1):
110 | t = random.randint(6, 18)
111 | timestamp += t
112 | timestamp_list.append(timestamp)
113 | i += 1
114 |
115 | trace = []
116 | for i in range(0, len(last_trace_x)):
117 | trace.append({
118 | 'x': last_trace_x[i],
119 | 'y': last_trace_y[i],
120 | 'time': timestamp_list[i] + int(''.join([random.choice(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) for _ in range(14)])) * 0.00000000000001
121 | })
122 |
123 | return trace
124 |
125 |
--------------------------------------------------------------------------------
/meituan/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/27 15:09
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | import random
9 | import requests
10 | import execjs
11 | import time
12 | from bs4 import BeautifulSoup
13 | from meituan.geetest import crack
14 |
15 |
16 | def set_session():
17 | session = requests.session()
18 | session.headers = {
19 | 'Referer': 'https://passport.meituan.com/account/unitivesignup?service=www&continue=https%3A%2F%2Fwww.meituan.com%2Faccount%2Fsettoken%3Fcontinue%3Dhttps%253A%252F%252Fwww.meituan.com%252F',
20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36',
21 | }
22 | return session
23 |
24 |
25 | def _get_csrf(session):
26 | """
27 | 获取认证Csrf参数
28 | :param session:
29 | :return:
30 | """
31 | url = 'https://passport.meituan.com/account/unitivelogin?service=www&continue=https%3A%2F%2Fwww.meituan.com%2Faccount%2Fsettoken%3Fcontinue%3Dhttp%253A%252F%252Fcd.meituan.com%252F'
32 |
33 | resp = session.get(url)
34 | soup = BeautifulSoup(resp.text, 'lxml')
35 | csrf = soup.select('input[name="csrf"]')[0]['value']
36 |
37 | return csrf
38 |
39 |
40 | def get_token(url):
41 | with open('token.js', 'rb') as f:
42 | js = f.read().decode()
43 | ctx = execjs.compile(js)
44 | return ctx.call('get_token', url)
45 |
46 |
47 | def _encrypt_pwd(password):
48 | """
49 | RSA加密密码
50 | :return:
51 | """
52 | with open('encrypt_pwd.js', 'rb') as f:
53 | js = f.read().decode()
54 | ctx = execjs.compile(js)
55 | pwd = ctx.call('encrypt', password)
56 | return pwd
57 |
58 |
59 | def get_phone():
60 | """
61 | 生成一个随机11位号码
62 | :return:
63 | """
64 | return '1' + ''.join(map(str, (random.sample(range(10), 10))))
65 |
66 |
67 | def test():
68 | """
69 | 模拟登录滑块测试
70 | :return:
71 | """
72 | login_api = 'https://passport.meituan.com/account/unitivelogin?risk_partner=0&risk_platform=1&risk_app=-1&uuid=ea8b149299ce4622b486.1568870998.1.0.0&service=www&continue=https%3A%2F%2Fwww.meituan.com%2Faccount%2Fsettoken%3Fcontinue%3Dhttps%253A%252F%252Fhf.meituan.com%252F'
73 |
74 | # username = get_phone()
75 | pwd = _encrypt_pwd('123456')
76 |
77 | session = set_session()
78 | csrf = _get_csrf(session)
79 | session.headers.update({
80 | 'Referer': 'https://passport.meituan.com/account/unitivelogin?service=www&continue=https%3A%2F%2Fwww.meituan.com%2Faccount%2Fsettoken%3Fcontinue%3Dhttp%253A%252F%252Fcd.meituan.com%252F',
81 | 'X-CSRF-Token': csrf,
82 | 'X-Client': 'javascript',
83 | 'X-Requested-With': 'XMLHttpRequest',
84 | })
85 | if 'Authorization' in set(session.headers.keys()):
86 | del session.headers['Authorization']
87 | data = {
88 | 'countrycode': '86',
89 | 'email': '18829040039',
90 | 'password': pwd,
91 | 'origin': 'account-login',
92 | 'csrf': csrf,
93 | 'requestCode': '',
94 | 'responseCode': '',
95 | 'h5Fingerprint': ''
96 | }
97 | resp = session.post(login_api, data=data).json()
98 | print(resp)
99 | if resp['error']['code'] == 101190:
100 | request_code = resp['error']['data']['requestCode']
101 | return request_code
102 | return None
103 |
104 |
105 | def main():
106 | num = 0
107 | while num <= 5:
108 | request_code = test()
109 | if request_code:
110 | print('Captcha load success! ')
111 | result = crack(request_code)
112 | print(result)
113 | break
114 | num += 1
115 | print('The {} verification failed! '.format(num))
116 | else:
117 | print('Captcha load failed! ')
118 | time.sleep(random.random())
119 |
120 |
121 | if __name__ == '__main__':
122 | main()
123 |
--------------------------------------------------------------------------------
/geetest3/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/28 16:24
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | import random
10 | import requests
11 | from geetest3.geetest import GeetestV3
12 | from geetest3.geetest_v2 import GeetestV3New
13 |
14 |
15 | def test1():
16 | """
17 | B站测试
18 | :return:
19 | """
20 | headers = {
21 | 'Accept-Encoding': 'gzip, deflate, br',
22 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
23 | 'User-Agent':
24 | 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
25 | 'Accept': 'application/json, text/plain, */*',
26 | 'Referer': 'https://passport.bilibili.com/login',
27 | 'Connection': 'keep-alive',
28 | }
29 | params = {'plat': '11'}
30 | response = requests.get(
31 | 'https://passport.bilibili.com/web/captcha/combine',
32 | headers=headers,
33 | params=params,
34 | )
35 | result = response.json()['data']['result']
36 | result = GeetestV3(result['gt'], result['challenge']).crack()
37 |
38 | if result:
39 | return {
40 | 'success': 1,
41 | 'message': '校验通过! ',
42 | 'data': {
43 | 'validate': result
44 | }
45 | }
46 | return {
47 | 'success': 0,
48 | 'message': '校验失败! ',
49 | 'data': None
50 | }
51 |
52 |
53 | def test2():
54 | """
55 | 简书测试
56 | :return:
57 | """
58 | url = 'https://www.jianshu.com/captchas/new?t={}-vjp'.format(int(time.time() * 1000))
59 | headers = {
60 | 'referer': 'https://www.jianshu.com/sign_in',
61 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'
62 | }
63 | resp = requests.get(url, headers=headers).json()
64 | gt = resp['gt']
65 | challenge = resp['challenge']
66 | result = GeetestV3(gt, challenge).crack()
67 | if result:
68 | return {
69 | 'success': 1,
70 | 'message': '校验通过! ',
71 | 'data': {
72 | 'validate': result
73 | }
74 | }
75 | return {
76 | 'success': 0,
77 | 'message': '校验失败! ',
78 | 'data': None
79 | }
80 |
81 |
82 | def test3():
83 | """
84 | 最新版极验3滑块验证, 测试为 OKEX 注册: https://www.okex.me/account/register, 固定 gt
85 | :return:
86 | """
87 | result = GeetestV3New('5252e05bb861c2b62105353977e43f94').crack()
88 | if result:
89 | return {
90 | 'success': 1,
91 | 'message': '校验通过! ',
92 | 'data': {
93 | 'validate': result
94 | }
95 | }
96 | return {
97 | 'success': 0,
98 | 'message': '校验失败! ',
99 | 'data': None
100 | }
101 |
102 |
103 | def test4():
104 | """
105 | 拉勾登录测试: https://passport.lagou.com/login/login.html?utm_source=m_cf_cpt_360_pc1
106 | gt 固定, 图片选择, 类似谷歌 recaptcha
107 | :return:
108 | """
109 | result = GeetestV3New('66442f2f720bfc86799932d8ad2eb6c7').crack()
110 | if result:
111 | return {
112 | 'success': 1,
113 | 'message': '校验通过! ',
114 | 'data': {
115 | 'validate': result
116 | }
117 | }
118 | return {
119 | 'success': 0,
120 | 'message': '校验失败! ',
121 | 'data': None
122 | }
123 |
124 |
125 | if __name__ == '__main__':
126 | print('开始测试...')
127 | print('=' * 100)
128 | num = 1
129 | success = 0
130 | while num <= 100:
131 | # x = test1()
132 | # x = test2()
133 | # x = test3()
134 | x = test4()
135 | print(x)
136 | print('=' * 100)
137 | if x['success']:
138 | success += 1
139 | time.sleep(random.randint(1, 3))
140 | num += 1
141 | print('最后测试结果 >> %.2f%%' % success)
142 |
--------------------------------------------------------------------------------
/jingdong/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/28 10:56
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | import json
11 | import execjs
12 | import re
13 | from jingdong.img_locate import get_distance
14 | from jingdong.get_trace import *
15 |
16 |
17 | session = requests.Session()
18 | session.headers = {
19 | 'Connection': 'keep-alive',
20 | 'Referer': 'https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fh5.m.jd.com%2Fpc%2Fdev%2F3mr2iWXgiWcZvyGYrQAoYp3KXAaq%2Findex.html%3Futm_source%3Dkong%26utm_medium%3Dzssc%26utm_campaign%3Dt_1000023384_100757%26utm_term%3D36f20e86-5b4d-4b6e-8fba-d79e6c2654a9-p_1999-pr_1646-at_100757%26jd_pop%3D36f20e86-5b4d-4b6e-8fba-d79e6c2654a9%26abt%3D0',
21 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
22 | }
23 |
24 |
25 | def get_session_id():
26 | """
27 | 获取设备指纹 _jdtdmap_sessionId
28 | :return:
29 | """
30 | response = session.get("https://seq.jd.com/jseqf.html?bizId=passport_jd_com_login_pc&platform=js&version=1")
31 | session_id = re.findall(r'_jdtdmap_sessionId="(.*?)"', response.text)[0]
32 | return session_id
33 |
34 |
35 | def _init_slider():
36 | """
37 | 初始化滑块
38 | :return:
39 | """
40 | url = 'https://iv.jd.com/slide/g.html'
41 | params = {
42 | 'appId': '1604ebb2287',
43 | 'scene': 'login',
44 | 'product': 'click-bind-suspend',
45 | 'e': 'Q2NDKJBVGRE5UMX3OJJRO6BV6UVQBMIFTJ3D2UJKVYHJMWPOMZYIUY43WWNWPEKLNC6UL62ABWCUBISUNMCQBEQUUQ',
46 | 'lang': 'zh_CN',
47 | 'callback': ''
48 | }
49 | resp = session.get(url, params=params)
50 | init_data = json.loads(resp.text.replace("(", "").replace(")", ""))
51 | return init_data
52 |
53 |
54 | def _encrypt_trace(trace):
55 | """
56 | 加密轨迹, 生成参数 d
57 | :return:
58 | """
59 | with open('jd_slider.js', 'r') as f:
60 | js = f.read()
61 |
62 | ctx = execjs.compile(js)
63 | return ctx.call('encrypt_trace', trace)
64 |
65 |
66 | def _slider_verify(d, challenge, session_id):
67 | """
68 | 滑块验证
69 | :param d: 加密轨迹
70 | :param challenge: 验证码签名
71 | :param session_id: 设备指纹
72 | :return:
73 | """
74 | url = "https://iv.jd.com/slide/s.html?"
75 | params = {
76 | "d": d,
77 | "c": challenge,
78 | "w": 278,
79 | "appId": "1604ebb2287",
80 | "scene": "login",
81 | "product": "click-bind-suspend",
82 | "e": 'Q2NDKJBVGRE5UMX3OJJRO6BV6UVQBMIFTJ3D2UJKVYHJMWPOMZYIUY43WWNWPEKLNC6UL62ABWCUBISUNMCQBEQUUQ',
83 | "s": session_id,
84 | "o": 'xxx', # 账号
85 | "lang": 'zh_CN',
86 | "callback": ''
87 | }
88 | response = session.get(url, params=params)
89 | result = json.loads(response.text.replace("(", "").replace(")", ""))
90 | print(result)
91 | return result
92 |
93 |
94 | def crack():
95 | # 获取设备指纹
96 | session_id = get_session_id()
97 | # 初始化滑块
98 | init_data = _init_slider()
99 | # 获取缺口距离
100 | distance = get_distance(init_data['patch'], init_data['bg'])
101 | # 屏幕图片尺寸比
102 | distance = round(distance * (278 / 360))
103 | # print(distance)
104 | # 伪造轨迹
105 | trace = get_trace(distance)
106 | # trace = generate_trace(distance)
107 | # print(trace)
108 | d = _encrypt_trace(trace)
109 | time.sleep(2)
110 | result = _slider_verify(d, init_data['challenge'], session_id)
111 | if "validate" not in result.keys():
112 | return {
113 | 'success': 0,
114 | 'message': '校验失败: {}'.format(result["message"]),
115 | 'data': None
116 | }
117 | return {
118 | 'success': 1,
119 | 'message': '校验成功! ',
120 | 'data': {
121 | "validate": result["validate"],
122 | "challenge": init_data["challenge"],
123 | }
124 | }
125 |
126 |
127 | if __name__ == '__main__':
128 | x = crack()
129 | print(x)
130 |
--------------------------------------------------------------------------------
/vaptcha/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/19 11:19
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import json
10 | import os
11 | import execjs
12 | import random
13 | from PIL import Image
14 | from vaptcha.get_trace import generate_trace
15 | from vaptcha.chaojiying import image_to_text
16 |
17 |
18 | headers = {
19 | 'Referer': 'https://www.vaptcha.com/demo/popup',
20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'
21 | }
22 |
23 |
24 | def get_challenge():
25 | """
26 | 获取验证码签名参数
27 | :return:
28 | """
29 | url = 'https://api.vaptcha.com/v2/config'
30 |
31 | params = {
32 | 'id': '5b4d9dfea485e5041019253f',
33 | 'type': 'popup',
34 | 'scene': '',
35 | 'callback': ''
36 | }
37 |
38 | resp = requests.get(url, headers=headers, params=params)
39 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
40 | return result['challenge']
41 |
42 |
43 | def init_vaptcha(challenge):
44 | """
45 | 初始化验证码
46 | :param challenge:
47 | :return:
48 | """
49 | url = 'https://api.vaptcha.com/v2/click'
50 |
51 | params = {
52 | 'id': '5b4d9dfea485e5041019253f',
53 | 'challenge': challenge,
54 | 'callback': ''
55 | }
56 | resp = requests.get(url, params=params, headers=headers)
57 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
58 | return result
59 |
60 |
61 | def _pic_download(url, type):
62 | """
63 | 图片下载
64 | :param url:
65 | :param type:
66 | :return:
67 | """
68 | img_path = os.path.abspath('...') + '\\' + '{}.jpg'.format(type)
69 | img_data = requests.get(url).content
70 | with open(img_path, 'wb') as f:
71 | f.write(img_data)
72 | return img_path
73 |
74 |
75 | def _slider_verify(challenge, trace):
76 | """
77 | 手势验证
78 | :param challenge:
79 | :param trace:
80 | :return:
81 | """
82 | url = 'https://api.vaptcha.com/v2/verify'
83 | with open('v_slider.js', 'rb') as f:
84 | js = f.read().decode()
85 | ctx = execjs.compile(js)
86 | params = {
87 | 'v': ctx.call('assemblyCoordData', trace),
88 | 'id': '5b4d9dfea485e5041019253f',
89 | 'challenge': challenge,
90 | 'drawtime': random.randint(1300, 2000),
91 | 'callback': ''
92 | }
93 | resp = requests.get(url, headers=headers, params=params)
94 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
95 | print(result)
96 | if result['code'] == '0103':
97 | return result['token']
98 | return None
99 |
100 |
101 | def crack():
102 | # 获取验证码 ID 签名
103 | challenge = get_challenge()
104 | # 初始化验证码
105 | init_data = init_vaptcha(challenge)
106 | # 下载验证码
107 | img_path = _pic_download('https://cdn.vaptcha.com/' + init_data['img'], 'vaptcha')
108 | img = Image.open(img_path)
109 | # img.show()
110 |
111 | # 使用超级鹰识别
112 | img_data = open(img_path, 'rb').read()
113 | ok, result = image_to_text(img_data, img_kind=9004)
114 | position = [x for x in result.split('|')]
115 | print('超级鹰识别结果: ', result)
116 | if ok and len(position) == 4:
117 | trace = generate_trace(position, img.size)
118 | # print(trace)
119 | result = _slider_verify(challenge, trace)
120 | if result:
121 | return {
122 | 'success': 1,
123 | 'message': '校验通过! ',
124 | 'data': {
125 | 'token': result
126 | }
127 | }
128 | return {
129 | 'success': 0,
130 | 'message': '校验失败! ',
131 | 'data': {
132 | 'token': None
133 | }
134 | }
135 | return {
136 | 'success': 0,
137 | 'message': '验证码识别失败! ',
138 | 'data': None
139 | }
140 |
141 |
142 | if __name__ == '__main__':
143 | x = crack()
144 | print(x)
145 |
--------------------------------------------------------------------------------
/yidun/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 21:56
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import numpy as np
10 | import requests
11 | from PIL import Image
12 | import cv2
13 | from PIL import ImageFont
14 | from PIL import ImageDraw
15 |
16 |
17 | def _pic_download(url, type):
18 | """
19 | 图片下载
20 | :param url:
21 | :param type:
22 | :return:
23 | """
24 | save_path = os.path.abspath('...') + '\\' + 'images'
25 | if not os.path.exists(save_path):
26 | os.mkdir(save_path)
27 |
28 | img_path = save_path + '\\' + '{}.jpg'.format(type)
29 | img_data = requests.get(url).content
30 | with open(img_path, 'wb') as f:
31 | f.write(img_data)
32 | return img_path
33 |
34 |
35 | def _cut_slider(path):
36 | """
37 | 滑块切割
38 | :return:
39 | """
40 | image = Image.open(path)
41 | x = []
42 | y = []
43 | for i in range(image.size[0]):
44 | for j in range(image.size[1]):
45 | pix = image.load()[i, j]
46 | if pix != 255:
47 | x.append(i)
48 | y.append(j)
49 | z = (np.min(x), np.min(y), np.max(x), np.max(y))
50 | result = image.crop(z)
51 | result.convert('RGB').save(path)
52 | # result.show()
53 | return result.size[0], result.size[1]
54 |
55 |
56 | def _get_distance(slider_url, captcha_url):
57 | """
58 | 获取缺口距离
59 | :param slider_url: 滑块图片 url
60 | :param captcha_url: 验证码图片 url
61 | :return:
62 | """
63 | save_path = os.path.abspath('...') + '\\' + 'images'
64 | if not os.path.exists(save_path):
65 | os.mkdir(save_path)
66 |
67 | # 引用上面的图片下载
68 | slider_path = _pic_download(slider_url, 'slider')
69 |
70 | # 引用上面的图片下载
71 | captcha_path = _pic_download(captcha_url, 'captcha')
72 |
73 | # 计算拼图还原距离
74 | target = cv2.imread(slider_path, 0)
75 | template = cv2.imread(captcha_path, 0)
76 | temp = save_path + '\\' + 'temp.jpg'
77 | targ = save_path + '\\' + 'targ.jpg'
78 | cv2.imwrite(targ, target)
79 | w, h = _cut_slider(slider_path)
80 | cv2.imwrite(temp, template)
81 | target = cv2.imread(targ)
82 | template = cv2.imread(temp)
83 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
84 | x, y = np.unravel_index(result.argmax(), result.shape)
85 |
86 | # 调用PIL Image 做测试
87 | image = Image.open(captcha_path)
88 |
89 | xy = (y, x, y + w, x + h)
90 | # 切割
91 | imagecrop = image.crop(xy)
92 | # 保存切割的缺口
93 | imagecrop.save(save_path + '\\' + "new_image.jpg")
94 | # imagecrop.show()
95 | return int(y + 3)
96 |
97 |
98 | def make_word(text):
99 | """
100 | 制作描述图片
101 | :return:
102 | """
103 | save_path = os.path.abspath('...') + '\\' + 'images'
104 | if not os.path.exists(save_path):
105 | os.mkdir(save_path)
106 |
107 | text = text.replace('', '').replace('', '')
108 | # 初始化图片对象, (300, 30)为图片大小, (255, 255, 255) 为白色背景
109 | img = Image.new('RGB', (300, 30), (255, 255, 255))
110 | # 设置字体
111 | font = ImageFont.truetype('simsun.ttc', 15)
112 | # 初始化写入对象
113 | draw = ImageDraw.Draw(img)
114 | # 添加文字, (0, 0): 文字起始坐标, (0, 0, 0): 颜色(黑色), font: 字体
115 | draw.text((0, 0), text, (0, 0, 0), font=font)
116 | # img.show()
117 | img_path = save_path + '\\' + 'word.jpg'
118 | img.save(img_path)
119 | return img_path
120 |
121 |
122 | def merge_word(img1, img2, width):
123 | """
124 | 将描述性文字合并到验证码图片上, 以便交给打码平台识别
125 | :return:
126 | """
127 | save_path = os.path.abspath('...') + '\\' + 'images'
128 | if not os.path.exists(save_path):
129 | os.mkdir(save_path)
130 | new_image = Image.new('RGB', (width, 190))
131 | img1 = Image.open(img1)
132 | new_image.paste(img1, (0, 0))
133 |
134 | img2 = Image.open(img2)
135 | new_image.paste(img2, (0, 160))
136 |
137 | # new_image.show()
138 | img_path = save_path + '\\' + 'new_captcha.jpg'
139 | new_image.save(img_path)
140 | return img_path
141 |
--------------------------------------------------------------------------------
/iqiyi/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 11:31
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import requests
10 | from PIL import Image
11 | import cv2
12 | import numpy as np
13 |
14 |
15 | def _pic_download(url, type):
16 | """
17 | 图片下载
18 | :param url:
19 | :param type:
20 | :return:
21 | """
22 | save_path = os.path.abspath('...') + '\\' + 'images'
23 | if not os.path.exists(save_path):
24 | os.mkdir(save_path)
25 | img_path = save_path + '\\' + '{}.jpg'.format(type)
26 | img_data = requests.get(url).content
27 | with open(img_path, 'wb') as f:
28 | f.write(img_data)
29 | return img_path
30 |
31 |
32 | def merge_captcha(init_data):
33 | """
34 | 还原验证码背景图
35 | :param init_data: 验证码初始化数据
36 | :return:
37 | """
38 | per_width = init_data['imageBlockPerWidth']
39 | per_height = init_data['imageBlockPerHeight']
40 | merge_array = init_data['imageBlockOffset']
41 | captcha_url = 'https://qcaptcha.iqiyi.com' + init_data['imageBgUrl']
42 | captcha_path = _pic_download(captcha_url, 'captcha')
43 | image = Image.open(captcha_path)
44 |
45 | new_image = Image.new('RGB', image.size)
46 | for s in range(2):
47 | for p in range(len(merge_array[0])):
48 | d = merge_array[s]
49 | h = len(d)
50 | l = d[h - 1]
51 | G = d[p]
52 | v = G['t1'] * per_width
53 | Z = G['t2'] * per_height
54 | g = per_width
55 | W = per_height
56 | if G['t1'] > l['t1']:
57 | v += 290 - per_width * h
58 | if p == h - 1:
59 | g = 290 - per_width * p
60 | if s == 1:
61 | W = 170 - per_height * s
62 | imgcrop = image.crop((v, Z, v + g, Z + W))
63 | new_image.paste(imgcrop, (p * per_width, s * per_height))
64 | new_image.save(captcha_path)
65 | # new_image.show()
66 | return captcha_path
67 |
68 |
69 | def _cut_slider(path):
70 | """
71 | 滑块切割
72 | :return:
73 | """
74 | image = Image.open(path)
75 | x = []
76 | y = []
77 | for i in range(image.size[0]):
78 | for j in range(image.size[1]):
79 | pix = image.load()[i, j]
80 | if pix != 255:
81 | x.append(i)
82 | y.append(j)
83 | z = (np.min(x), np.min(y), np.max(x), np.max(y))
84 | result = image.crop(z)
85 | result.convert('RGB').save(path)
86 | # result.show()
87 | return result.size[0], result.size[1]
88 |
89 |
90 | def get_distance(init_data):
91 | """
92 | 获取缺口距离
93 | :param init_data: 验证码初始化数据
94 | :return:
95 | """
96 | save_path = os.path.abspath('...') + '\\' + 'images'
97 | if not os.path.exists(save_path):
98 | os.mkdir(save_path)
99 | slider_url = 'https://qcaptcha.iqiyi.com' + init_data['iconUrl']
100 | slider_path = _pic_download(slider_url, 'slider')
101 |
102 | # 验证码图片还原
103 | captcha_path = merge_captcha(init_data)
104 |
105 | # # 计算拼图还原距离
106 | target = cv2.imread(slider_path, 0)
107 | template = cv2.imread(captcha_path, 0)
108 | temp = save_path + '\\' + 'temp.jpg'
109 | targ = save_path + '\\' + 'targ.jpg'
110 | cv2.imwrite(targ, target)
111 | cv2.imwrite(temp, template)
112 |
113 | template = cv2.imread(temp)
114 | template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
115 | template = abs(255 - template)
116 | cv2.imwrite(temp, template)
117 | w, h = _cut_slider(targ)
118 | target = cv2.imread(targ)
119 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
120 | target = abs(255 - target)
121 | cv2.imwrite(targ, target)
122 | target = cv2.imread(targ)
123 | template = cv2.imread(temp)
124 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
125 | x, y = np.unravel_index(result.argmax(), result.shape)
126 |
127 | # 调用PIL Image 做测试
128 | image = Image.open(captcha_path)
129 |
130 | xy = (y, x, y + w, x + h)
131 | # 切割
132 | imagecrop = image.crop(xy)
133 | # 保存切割的缺口
134 | imagecrop.convert('RGB').save(save_path + '\\' + "new_image.jpg")
135 | imagecrop.show()
136 | return int(y)
137 |
138 |
--------------------------------------------------------------------------------
/shumei/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/3 21:13
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import json
10 | import time
11 | import base64
12 | import random
13 | from shumei.img_locate import _get_distance
14 | from shumei.get_trace import generate_trace
15 | from shumei.des import encrypt, decrypt
16 |
17 | headers = {
18 | "Referer": "https://www.fengkongcloud.com/",
19 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
20 | }
21 |
22 |
23 | def _init_slider():
24 | """
25 | 初始化验证码
26 | :return:
27 | """
28 | url = 'https://captcha.fengkongcloud.com/ca/v1/register'
29 | params = {
30 | 'organization': 'TKWQ4vmgC3PJLGDTMIoJ',
31 | 'appId': 'default',
32 | 'channel': 'DEFAULT',
33 | 'lang': 'zh-cn',
34 | 'model': 'slide',
35 | 'rversion': '1.0.1',
36 | 'sdkver': '1.1.2',
37 | 'data': {},
38 | 'callback': 'sm_{}'.format(int(time.time() * 1000))
39 | }
40 | resp = requests.get(url, params=params, headers=headers)
41 | result = json.loads(resp.text.replace('{}('.format(params['callback']), '').replace(')', ''))
42 | print('初始化结果: ', result)
43 | if result['riskLevel'] == 'PASS':
44 | return {
45 | 'k': result['detail']['k'],
46 | 'captcha_url': 'https://castatic.fengkongcloud.com{}'.format(result['detail']['bg']),
47 | 'rid': result['detail']['rid']
48 | }
49 | return None
50 |
51 |
52 | def _encrypt_trace(k, trace, distance):
53 | """
54 | 加密轨迹
55 | :param k: 初始密钥
56 | :param trace: 轨迹
57 | :param distance: 距离
58 | :return:
59 | """
60 | # 对 k 值进行 base64 解码
61 | text = base64.b64decode(k)
62 | # 对解码后的 k 值进行 DES 解密(密钥: sshummei), 取前8位作为下一次加密的密钥
63 | new_key = decrypt('sshummei', text)[:8]
64 | # 构造待加密数据
65 | data = {
66 | # 滑动距离 / 300
67 | "d": distance / 300,
68 | # 轨迹
69 | "m": trace,
70 | # 滑动所用时间
71 | "c": trace[-1][-1],
72 | # 验证码图片尺寸, 宽
73 | "w": 300,
74 | # 验证码图片尺寸, 高
75 | 'h': 150,
76 | # 设备
77 | 'os': 'web_pc',
78 | # 是否 webdriver
79 | "cs": 0,
80 | "wd": 0,
81 | 'sm': -1
82 | }
83 | # 最后加密 DES
84 | return encrypt(new_key, json.dumps(data).replace(' ', ''))
85 |
86 |
87 | def _slider_verify(act, rid):
88 | """
89 | 验证
90 | :param act:
91 | :param rid:
92 | :return:
93 | """
94 | url = 'https://captcha.fengkongcloud.com/ca/v1/fverify'
95 | params = {
96 | "organization": "TKWQ4vmgC3PJLGDTMIoJ",
97 | "appId": "default",
98 | "channel": "DEFAULT",
99 | "act": act,
100 | "rid": rid,
101 | "lang": "zh-cn",
102 | "ostype": "web",
103 | "rversion": "1.0.1",
104 | "sdkver": "1.1.2",
105 | "callback": "sm_{}".format(int(time.time() * 1000)),
106 | }
107 | resp = requests.get(url, params=params, headers=headers)
108 | result = json.loads(resp.text.replace('{}('.format(params['callback']), '').replace(')', ''))
109 | return result
110 |
111 |
112 | def crack():
113 | """
114 | 滑块验证
115 | :return:
116 | """
117 | while True:
118 | _init_data = _init_slider()
119 | if _init_data:
120 | break
121 | time.sleep(random.random())
122 | distance = _get_distance(_init_data['captcha_url'])
123 | if not distance:
124 | return {
125 | 'success': 0,
126 | 'message': '缺口距离获取失败! ',
127 | 'data': None
128 | }
129 | # time.sleep(random.uniform(0.01, 0.05))
130 | trace = generate_trace(distance)
131 | act = _encrypt_trace(_init_data['k'], trace, distance)
132 | rid = _init_data['rid']
133 | result = _slider_verify(act, rid)
134 | print('校验结果: ', result)
135 | if result['riskLevel'] == 'PASS':
136 | return {
137 | 'success': 1,
138 | 'message': '校验成功! ',
139 | 'data': rid
140 | }
141 | return {
142 | 'success': 0,
143 | 'message': '校验失败! ',
144 | 'data': None
145 | }
146 |
147 |
148 | if __name__ == '__main__':
149 | x = crack()
150 | print(x)
151 |
--------------------------------------------------------------------------------
/tongdun/td_crypt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/17 8:33
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : td_crypt.py
6 | # @Software: PyCharm
7 |
8 | import math
9 | import execjs
10 | from Crypto.Cipher import AES
11 | import base64
12 |
13 |
14 | def generate_key(token):
15 | """
16 | 根据设备指纹生成自定义加密密钥
17 | :return:
18 | """
19 | return "rsp67ou9" + '-'.join(token.split('-')[1:])[2:18]
20 |
21 |
22 | def generate_aes_key(token):
23 | """
24 | 根据设备指纹生成 AES 密钥
25 | :return:
26 | """
27 | return "rsp67ou9" + '-'.join(token.split('-')[1:])[10:18]
28 |
29 |
30 | def replace_str(text, x, y):
31 | """
32 | 对指定字符串实现x、y互换
33 | :param text:
34 | :param x:
35 | :param y:
36 | :return:
37 | """
38 | chs = list(text)
39 | for i, ch in enumerate(chs):
40 | if ch == x:
41 | chs[i] = y
42 | elif ch == y:
43 | chs[i] = x
44 | return ''.join(chs)
45 |
46 |
47 | def aes_encrypt(key, text, iv="Mnz14C2tXod8AUJ5"):
48 | """
49 | AES CBC Pkcs7Padding
50 | :param key: 密钥
51 | :param text: 明文
52 | :param iv: 偏移量固定
53 | :return:
54 | """
55 | bs = AES.block_size
56 | # Pkcs7 填充
57 | pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
58 | cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
59 | cipher_text = cipher.encrypt(pad(text).encode())
60 | encrypt_str = base64.b64encode(cipher_text).decode()
61 | # 大小写转换
62 | tansfer = lambda x: x.upper() if x.islower() else x.lower()
63 | # 字符替换, p/q 互换, I/J互换
64 | result = ''.join([tansfer(i) for i in [j for j in encrypt_str]]).replace('+', '~')
65 | result = replace_str(result, 'p', 'q')
66 | result = replace_str(result, 'I', 'J')
67 | return result
68 |
69 |
70 | def et(ctx, text):
71 | return ctx.call('et', text)
72 |
73 |
74 | def Pt(ctx, text):
75 | return ctx.call('Pt', text)
76 |
77 |
78 | def ft(ctx, text, aes_key):
79 | return ctx.call('ft', text, aes_key)
80 |
81 |
82 | def int2str(num, b):
83 | """
84 | 将一个整数转化为指定进制字符
85 | :param num:
86 | :param b:
87 | :return:
88 | """
89 | num = math.ceil(num)
90 | return ((num == 0) and "0") or (int2str(num // b, b).lstrip("0") + "0123456789abcdefghijklmnopqrstuvwxyz"[num % b])
91 |
92 |
93 | def encrypt_trace(slide_y, trace, start_time):
94 | """
95 | 加密轨迹: 按照特定顺序对轨迹数值转成 36 进制字符串拼接
96 | :param slide_y: 缺口 y 值
97 | :param trace: 轨迹
98 | :param start_time: 验证码刷新时间
99 | :return:
100 | """
101 | # 优化: python 复写整数转 36 进制
102 | # js = """
103 | # function encrypt(x) {
104 | # return Math.round(x).toString(36)
105 | # }
106 | # """
107 | # ctx = execjs.compile(js)
108 | # encrypt = lambda j: ctx.call('encrypt', j) if j != '' else j
109 | # enc_slide = ','.join([encrypt(slide[m]) for m in ["left", "top"]]) + ',' + \
110 | # ','.join([encrypt(n) for n in [slide['left'] + slide['width'], slide['top'] + slide['height']]]) + \
111 | # ',' + encrypt(trace[-1]['op_x']) + ',' + encrypt(trace[-1]['op_y']) + ',0,0,' + encrypt(start_time)
112 | encrypt = lambda j: int2str(j, 36) if j != '' else j
113 | slide = {'height': 35, 'left': 506.5, 'top': 636.5, 'width': 230}
114 | enc_slide = ','.join([encrypt(slide[m]) for m in ["left", "top"]]) + ',' + \
115 | ','.join([encrypt(n) for n in [slide['left'] + 42, slide['top'] + 40]]) + \
116 | ',' + encrypt(trace[-1]['op_x']) + ',' + encrypt(trace[-1]['op_y']) + \
117 | ',' + encrypt(slide['left']) + \
118 | ',' + encrypt(440.5 + slide_y) + ",1,0," + encrypt(start_time)
119 |
120 | enc_trace = []
121 | for i in trace:
122 | enc_trace.append((encrypt(i['time'] - start_time) + ',' + ','.join(
123 | [encrypt(i[k]) for k in ['type', 'op_x', 'op_y', 'Action']])).strip(','))
124 | enc_trace.append('')
125 | return enc_slide + '%' + '|'.join(enc_trace)
126 |
127 |
128 | if __name__ == '__main__':
129 | encrypt = lambda j: int2str(j, 36) if j != '' else j
130 | slide = {'height': 35, 'left': 506.5, 'top': 636.5, 'width': 230}
131 | enc_slide = ','.join([encrypt(slide[m]) for m in ["left", "top"]]) + ',' + \
132 | ','.join([encrypt(n) for n in [slide['left'] + 42, slide['top'] + 40]]) + \
133 | ',' + encrypt(523) + ',' + encrypt(669) + \
134 | ',' + encrypt(slide['left']) + \
135 | ',' + encrypt(440.5 + 25) + ",1,0," + encrypt(1571228630478)
136 | print(enc_slide)
137 | print("e3,hp,f9,it,ej,il,e3,cy,1,0,k1t8yifi")
138 |
--------------------------------------------------------------------------------
/geetest2/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/7 15:20
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 |
9 | """
10 | 此文件代码来自 https://github.com/OSinoooO/bilibili_geetest/blob/master/bilibili_geetest_crack.py
11 | """
12 |
13 | from PIL import Image
14 |
15 |
16 | class ImgProcess:
17 | location_list = [
18 | {'y': -58, 'x': -157},
19 | {'y': -58, 'x': -145},
20 | {'y': -58, 'x': -265},
21 | {'y': -58, 'x': -277},
22 | {'y': -58, 'x': -181},
23 | {'y': -58, 'x': -169},
24 | {'y': -58, 'x': -241},
25 | {'y': -58, 'x': -253},
26 | {'y': -58, 'x': -109},
27 | {'y': -58, 'x': -97},
28 | {'y': -58, 'x': -289},
29 | {'y': -58, 'x': -301},
30 | {'y': -58, 'x': -85},
31 | {'y': -58, 'x': -73},
32 | {'y': -58, 'x': -25},
33 | {'y': -58, 'x': -37},
34 | {'y': -58, 'x': -13},
35 | {'y': -58, 'x': -1},
36 | {'y': -58, 'x': -121},
37 | {'y': -58, 'x': -133},
38 | {'y': -58, 'x': -61},
39 | {'y': -58, 'x': -49},
40 | {'y': -58, 'x': -217},
41 | {'y': -58, 'x': -229},
42 | {'y': -58, 'x': -205},
43 | {'y': -58, 'x': -193},
44 | {'y': 0, 'x': -145},
45 | {'y': 0, 'x': -157},
46 | {'y': 0, 'x': -277},
47 | {'y': 0, 'x': -265},
48 | {'y': 0, 'x': -169},
49 | {'y': 0, 'x': -181},
50 | {'y': 0, 'x': -253},
51 | {'y': 0, 'x': -241},
52 | {'y': 0, 'x': -97},
53 | {'y': 0, 'x': -109},
54 | {'y': 0, 'x': -301},
55 | {'y': 0, 'x': -289},
56 | {'y': 0, 'x': -73},
57 | {'y': 0, 'x': -85},
58 | {'y': 0, 'x': -37},
59 | {'y': 0, 'x': -25},
60 | {'y': 0, 'x': -1},
61 | {'y': 0, 'x': -13},
62 | {'y': 0, 'x': -133},
63 | {'y': 0, 'x': -121},
64 | {'y': 0, 'x': -49},
65 | {'y': 0, 'x': -61},
66 | {'y': 0, 'x': -229},
67 | {'y': 0, 'x': -217},
68 | {'y': 0, 'x': -193},
69 | {'y': 0, 'x': -205}
70 | ]
71 |
72 | def get_merge_image(self, filename):
73 | """
74 | 根据图片位置合并还原
75 | :param filename: 图片
76 | :return: 合并后的图片对象
77 | """
78 | im = Image.open(filename)
79 | width, height = im.size
80 |
81 | new_im = Image.new('RGB', (260, height))
82 | im_list_upper = []
83 | im_list_lower = []
84 |
85 | for location in self.location_list:
86 | if location['y'] == -58:
87 | im_list_upper.append(im.crop((abs(location['x']), height//2, abs(location['x']) + 10, height)))
88 | if location['y'] == 0:
89 | im_list_lower.append(im.crop((abs(location['x']), 0, abs(location['x']) + 10, height//2)))
90 |
91 | x_offset = 0
92 | for img in im_list_upper:
93 | new_im.paste(img, (x_offset, 0))
94 | x_offset += img.size[0]
95 |
96 | x_offset = 0
97 | for img in im_list_lower:
98 | new_im.paste(img, (x_offset, height//2))
99 | x_offset += img.size[0]
100 | return new_im
101 |
102 | def is_px_equal(self, img1, img2, x, y):
103 | """
104 | 判断两个像素是否相同
105 | :param img1: 图片1
106 | :param img2:图片2
107 | :param x:位置1
108 | :param y:位置2
109 | :return:像素是否相同
110 | """
111 | pix1 = img1.load()[x, y]
112 | pix2 = img2.load()[x, y]
113 | threshold = 60
114 |
115 | if abs(pix1[0] - pix2[0]) < threshold and abs(pix1[1] - pix2[1]) < threshold and abs(
116 | pix1[2] - pix2[2]) < threshold:
117 | return True
118 | else:
119 | return False
120 |
121 | def get_gap(self, img1, img2):
122 | """
123 | 获取缺口偏移量
124 | :param img1: 不带缺口图片
125 | :param img2: 带缺口图片
126 | :return:
127 | """
128 | left = 0
129 | for i in range(left, img1.size[0]):
130 | for j in range(img1.size[1]):
131 | if not self.is_px_equal(img1, img2, i, j):
132 | left = i
133 | return left
134 | return left
135 |
136 |
137 | if __name__ == '__main__':
138 | """
139 | test 图像还原
140 | """
141 | img_process = ImgProcess()
142 | img1 = img_process.get_merge_image('Image/' + "demo_fullbg" + '.jpg')
143 | img2 = img_process.get_merge_image('Image/' + "demo_bg" + '.jpg')
144 | img1.show()
145 | img2.show()
146 | distance = int(img_process.get_gap(img1, img2) - 7)
147 | print(distance)
148 |
--------------------------------------------------------------------------------
/shumei/geetest_new.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/11/1 18:52
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest_new.py
6 | # @Software: PyCharm
7 |
8 | import requests
9 | import json
10 | import time
11 | import base64
12 | import random
13 | from shumei.des import encrypt, decrypt
14 | from shumei.img_locate import get_distance
15 | from shumei.get_trace import _generate_trace
16 |
17 | session = requests.session()
18 | session.headers = {
19 | "Referer": "https://www.fengkongcloud.com/",
20 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
21 | }
22 |
23 |
24 | def _init_slider():
25 | """
26 | 初始化验证码
27 | :return:
28 | """
29 | url = 'https://captcha.fengkongcloud.com/ca/v1/register'
30 | params = {
31 | 'organization': 'RlokQwRlVjUrTUlkIqOg',
32 | 'appId': 'default',
33 | 'channel': 'DEFAULT',
34 | 'lang': 'zh-cn',
35 | 'model': 'slide',
36 | 'rversion': '1.0.1',
37 | 'sdkver': '1.1.2',
38 | 'data': {},
39 | 'callback': 'sm_{}'.format(int(time.time() * 1000))
40 | }
41 | resp = session.get(url, params=params)
42 | result = json.loads(resp.text.replace('{}('.format(params['callback']), '').replace(')', ''))
43 | print('初始化结果: ', result)
44 | if result['riskLevel'] == 'PASS':
45 | return {
46 | 'k': result['detail']['k'],
47 | 'captcha_url': 'https://castatic.fengkongcloud.com{}'.format(result['detail']['bg']),
48 | 'slider_url': 'https://castatic.fengkongcloud.com{}'.format(result['detail']['fg']),
49 | 'rid': result['detail']['rid']
50 | }
51 | return None
52 |
53 |
54 | def _encrypt_data(k, trace, distance):
55 | """
56 | 加密轨迹
57 | :param k: 初始密钥
58 | :param trace: 轨迹
59 | :param distance: 距离
60 | :return:
61 | """
62 | # 对 k 值进行 base64 解码
63 | text = base64.b64decode(k)
64 | # 对解码后的 k 值进行 DES 解密(密钥: sshummei), 取前8位作为下一次加密的密钥
65 | new_key = decrypt('sshummei', text)[:8]
66 | # 构造加密数据
67 | return {
68 | # 滑动距离 / 300
69 | "hz": encrypt(new_key, str(distance / 300)),
70 | # 轨迹
71 | "wa": encrypt(new_key, json.dumps(trace).replace(' ', '')),
72 | # 滑动所用时间
73 | "co": encrypt(new_key, str(trace[-1][-1] + random.randint(30, 70))),
74 | # 验证码图片尺寸, 宽
75 | "mn": encrypt(new_key, "300"),
76 | # 验证码图片尺寸, 高
77 | "us": encrypt(new_key, "150"),
78 | # 是否 webdriver
79 | "oq": encrypt(new_key, '0'),
80 | "et": encrypt(new_key, '0'),
81 | "bm": encrypt(new_key, '-1'),
82 | "ml": encrypt(new_key, '"default"'),
83 | "fd": encrypt(new_key, '"DEFAULT"'),
84 | "ep": encrypt(new_key, '"zh-cn"')
85 | }
86 |
87 |
88 | def _slider_verify(encrypt_data, rid):
89 | """
90 | 验证
91 | :param encrypt_data:
92 | :param rid:
93 | :return:
94 | """
95 | url = 'https://captcha.fengkongcloud.com/ca/v2/fverify'
96 | encrypt_data.update({
97 | 'organization': 'RlokQwRlVjUrTUlkIqOg',
98 | 'callback': 'sm_{}'.format(int(time.time() * 1000)),
99 | 'ostype': 'web',
100 | 'rid': rid,
101 | 'sdkver': '1.1.2',
102 | 'rversion': '1.0.1',
103 | 'protocol': 1,
104 | 'act.os': 'web_pc'
105 | })
106 | resp = session.get(url, params=encrypt_data)
107 | result = json.loads(resp.text.replace('{}('.format(encrypt_data['callback']), '').replace(')', ''))
108 | return result
109 |
110 |
111 | def crack():
112 | """
113 | 滑块验证
114 | :return:
115 | """
116 | while True:
117 | _init_data = _init_slider()
118 | if _init_data:
119 | break
120 | time.sleep(random.random())
121 | distance = get_distance(_init_data['captcha_url'])
122 | distance = int(round(distance * (300 / 600)))
123 | print('缺口距离: ', distance)
124 | if not distance:
125 | return {
126 | 'success': 0,
127 | 'message': '缺口距离获取失败! ',
128 | 'data': None
129 | }
130 | trace = _generate_trace(distance)
131 | rid = _init_data['rid']
132 | encrypt_data = _encrypt_data(_init_data['k'], trace, distance)
133 | result = _slider_verify(encrypt_data, rid)
134 | print('校验结果: ', result)
135 | if result['riskLevel'] == 'PASS':
136 | return {
137 | 'success': 1,
138 | 'message': '校验成功! ',
139 | 'data': rid
140 | }
141 | return {
142 | 'success': 0,
143 | 'message': '校验失败! ',
144 | 'data': None
145 | }
146 |
147 |
148 | if __name__ == '__main__':
149 | x = crack()
150 | print(x)
151 |
--------------------------------------------------------------------------------
/mogujie/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/12 18:16
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 |
9 | import execjs
10 | from PIL import Image
11 | import requests
12 | import random
13 | import json
14 | import time
15 |
16 |
17 | headers = {
18 | 'Content-Type': 'application/x-www-form-urlencoded;',
19 | 'Origin': 'https://portal.mogu.com',
20 | 'Referer': 'https://portal.mogu.com/user/newlogin?redirect_url=https%3A%2F%2Fwww.mogu.com%2F&ptp=31.v5mL0b.0.0.sjRcapVp',
21 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'
22 | }
23 |
24 |
25 | def _fake_trace(click_list):
26 | """
27 | 根据点击次数伪造轨迹
28 | :param click_list: 每张图片点击次数列表
29 | :return: 在验证码上移动的轨迹
30 | """
31 | # 轨迹构造已删除, 请自行编写, 提示: [-1, -1, -1, 0] 开头, 点击位置处停留时间稍长
32 | # 轨迹样式:
33 | trace = [[-1, -1, -1, 0], [110, 33, 1571136448228, 1], [115, 33, 696, 2], [129, 33, 17, 2], [137, 33, 16, 2], [145, 33, 17, 2]]
34 | return trace
35 |
36 |
37 | def encrypt(data, cap_key):
38 | """
39 | 加密
40 | :param data: 待加密数据
41 | :param cap_key: 验证码 ID
42 | :return:
43 | """
44 | with open('mgj_encrypt.js', 'rb') as f:
45 | js = f.read().decode()
46 | ctx = execjs.compile(js)
47 | return ctx.call('encrypt', data, cap_key)
48 |
49 |
50 | def get_auth(data):
51 | """
52 | 签名验证
53 | :param data:
54 | :return:
55 | """
56 | with open('get_auth.js', 'rb') as f:
57 | js = f.read().decode()
58 | ctx = execjs.compile(js)
59 | return ctx.call('get_auth', data)
60 |
61 |
62 | def get_cap_key():
63 | """
64 | 获取验证码初始化 ID
65 | :return:
66 | """
67 | url = 'https://shieldcaptain.mogu.com/gettoken'
68 |
69 | params = {
70 | 'auth': get_auth({}),
71 | '_': int(time.time() * 1000),
72 | 'callback': ''
73 | }
74 |
75 | resp = requests.get(url, params=params, headers=headers)
76 | try:
77 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
78 | cap_key = result['capkey']
79 | return cap_key
80 | except:
81 | return None
82 |
83 |
84 | def _download_captcha(cap_key):
85 | """
86 | 下载验证码图片
87 | :param cap_key: 验证码 ID
88 | :return:
89 | """
90 | url = 'https://shieldcaptain.mogu.com/getimage'
91 |
92 | params = {
93 | 'code': cap_key,
94 | 'auth': get_auth({'code': cap_key})
95 | }
96 | imgdata = requests.get(url, params=params, headers=headers).content
97 |
98 | with open('captcha.jpg', 'wb') as f:
99 | f.write(imgdata)
100 |
101 | img = Image.open('captcha.jpg')
102 | img.show()
103 |
104 |
105 | def _input_click():
106 | """
107 | 输入点击次数
108 | :return:
109 | """
110 | click_times = []
111 | x1 = input('请输入第一张图片需要点击几次 >> \n')
112 | click_times.append(int(x1))
113 | x2 = input('请输入第二张图片需要点击几次 >> \n')
114 | click_times.append(int(x2))
115 | x3 = input('请输入第三张图片需要点击几次 >> \n')
116 | click_times.append(int(x3))
117 | x4 = input('请输入第四张图片需要点击几次 >> \n')
118 | click_times.append(int(x4))
119 |
120 | return click_times
121 |
122 |
123 | def _click_verify(cap_key, click_times):
124 | """
125 | 最终验证
126 | :param cap_key: 验证码 ID
127 | :param click_times: 点击次数
128 | :return:
129 | """
130 | url = 'https://shieldcaptain.mogu.com/validate'
131 |
132 | trace = _fake_trace(click_times)
133 |
134 | data = {
135 | 'probc': cap_key,
136 | # 最后需要反转一下, 加密的是翻转的列表
137 | 'probd': encrypt(click_times[::-1], cap_key),
138 | 'probe': encrypt(trace, cap_key),
139 | 'probf': encrypt([[-1, -1, -1, 0]], cap_key),
140 | 'probg': encrypt([[-1, -1, -1, 0]], cap_key),
141 | }
142 | auth = get_auth(data)
143 | data['auth'] = auth
144 |
145 | resp = requests.post(url, data=data, headers=headers).json()
146 | print(resp)
147 | if resp['ret'] == 'SUCCESS':
148 | return resp['data']['captkey']
149 | return None
150 |
151 |
152 | def click():
153 | # 获取验证码 ID
154 | cap_key = get_cap_key()
155 | # 下载验证码并显示
156 | _download_captcha(cap_key)
157 | # 手动输入点击次数
158 | click_times = _input_click()
159 | # 最终验证
160 | result = _click_verify(cap_key, click_times)
161 | if result:
162 | return {
163 | 'success': 1,
164 | 'message': '校验通过! ',
165 | 'data': {
166 | 'captkey': result
167 | }
168 | }
169 | return {
170 | 'success': 0,
171 | 'message': '校验失败! ',
172 | 'data': None
173 | }
174 |
175 |
176 | if __name__ == '__main__':
177 | x = click()
178 | print(x)
179 |
--------------------------------------------------------------------------------
/city58/get_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/18 12:24
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : get_trace.py
6 | # @Software: PyCharm
7 |
8 |
9 | import random
10 | from numpy import *
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | def plot_line(x, y, xrange=None, yrange=None):
15 | """
16 | :param x: x list
17 | :param y: y list
18 | :param xrange: x坐标范围
19 | :param yrange: y坐标范围
20 | :return: 画出折线图
21 | """
22 | fig = plt.figure()
23 | ax = fig.add_subplot(3, 2, 1)
24 | ax.plot(np.array(x), np.array(y))
25 |
26 | ax.set_xlabel('x')
27 | ax.set_ylabel('y')
28 | if not xrange:
29 | ax.set_xlim(xrange)
30 | if not yrange:
31 | ax.set_ylim(yrange)
32 |
33 | ax.invert_yaxis()
34 | plt.show()
35 |
36 |
37 | def get_func(x, y):
38 | """
39 | 传入xlist, ylist
40 | list长度3
41 | 生成一个一元二次方程
42 | :param x:
43 | :param y:
44 | :return:
45 | """
46 | if len(x) != len(y):
47 | raise Exception("Error: len(x) != len(y)")
48 | temp_mat = mat(zeros((3, 3)))
49 | for i in range(0, 3):
50 | temp_mat[0, i] = pow(x[i], 2)
51 | temp_mat[1, i] = x[i]
52 | temp_mat[2, i] = 1
53 | temp_mat_inv = np.linalg.inv(temp_mat)
54 | temp_y = mat(array(y))
55 | parameter_abc = temp_y * temp_mat_inv
56 | list_abc = []
57 | for i in range(0, 3):
58 | list_abc.append(parameter_abc[0, i])
59 | return list_abc
60 |
61 |
62 | def generate_gesture_trace(position):
63 | """
64 | 生成手势验证码轨迹
65 | :param position:
66 | :return:
67 | """
68 | x = []
69 | y = []
70 | for i in position:
71 | x.append(int(i.split(',')[0]))
72 | y.append(int(i.split(',')[1]))
73 |
74 | trace_x = []
75 | trace_y = []
76 | for _ in range(0, 2):
77 | tepx = [x[_], x[_ + 1], x[_ + 2]]
78 | tepy = [y[_], y[_ + 1], y[_ + 2]]
79 | [a, b, c] = get_func(tepx, tepy)
80 | if _ == 0:
81 | for i in range(x[0], x[1]):
82 | trace_x.append(i)
83 | trace_y.append(a * i * i + b * i + c)
84 | for i in range(x[1], x[2]):
85 | trace_x.append(i)
86 | if random.randint(1, 5) == 1:
87 | trace_y.append((((float)(y[2] - y[1])) / (x[2] - x[1])) * (i - x[1]) + y[1] + random.randint(-1, 1))
88 | else:
89 | trace_y.append((((float)(y[2] - y[1])) / (x[2] - x[1])) * (i - x[1]) + y[1])
90 | else:
91 | for i in range(x[2], x[3]):
92 | trace_x.append(i)
93 | trace_y.append(a * i * i + b * i + c)
94 | trace_x = [int(i) for i in trace_x]
95 | trace_y = [int(i) for i in trace_y]
96 | last_trace_x = []
97 | last_trace_y = []
98 | plot_line(trace_x, trace_y, [0, 280], [0, 158])
99 | xx = 0
100 | while xx < len(trace_x) - 1:
101 | last_trace_x.append(trace_x[xx])
102 | last_trace_y.append(trace_y[xx])
103 | xx += random.randint(1, 4)
104 | last_trace_x.append(trace_x[-1])
105 | last_trace_y.append(trace_y[-1])
106 |
107 | timestamp_list = []
108 | timestamp = random.randint(180, 220)
109 | for i in range(len(last_trace_x)):
110 | t = random.randint(5, 10)
111 | timestamp += t
112 | timestamp_list.append(timestamp)
113 | i += 1
114 | trace = [{
115 | 'p': ','.join([str(last_trace_x[0]), str(last_trace_y[0])]),
116 | 't': 1
117 | }]
118 | for i in range(len(last_trace_x)):
119 | trace.append({
120 | 'p': ','.join([str(last_trace_x[i]), str(last_trace_y[i])]),
121 | 't': timestamp_list[i]
122 | })
123 | trace.append({
124 | 'p': ','.join([str(last_trace_x[-1]), str(last_trace_y[-1])]),
125 | 't': timestamp_list[-1] + random.randint(50, 100)
126 | })
127 | return x[3] - x[0], trace
128 |
129 |
130 | def generate_slide_trace(distance):
131 | """
132 | 生成滑块验证码轨迹
133 | :param distance: 缺口距离
134 | :return:
135 | """
136 | # 轨迹删除
137 | for index, x in enumerate(tracks_list):
138 | trace.append({
139 | 'p': ','.join([str(x + start_x), str(y_list[index] + start_y)]),
140 | 't': timestamp_list[index]
141 | })
142 | trace.append({
143 | 'p': f'{tracks_list[-1] + start_x},{y_list[-1] + start_y}',
144 | 't': timestamp_list[-1] + random.randint(100, 300)
145 | })
146 | return trace
147 |
148 |
149 | def process_trace(trace):
150 | """
151 | 处理轨迹
152 | :param trace: 轨迹
153 | :return:
154 | """
155 | merge = lambda s: ','.join([str(s['p']), str(s['t'])])
156 | new_trace = '|'.join([merge(i) for i in trace]) + '|'
157 | return new_trace
158 |
159 |
160 | if __name__ == '__main__':
161 | pass
162 |
--------------------------------------------------------------------------------
/iqiyi/process_trace.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 9:29
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_process.py
6 | # @Software: PyCharm
7 |
8 | import time
9 | import random
10 |
11 |
12 | def get_required_origin_data(post_data_length, trace):
13 | """
14 | 将轨迹数组按照5个一组重新排列
15 | :param post_data_length:
16 | :param trace:
17 | :return:
18 | """
19 | required_origin_data = []
20 | a = 0
21 | per = int((len(trace) - 4) / 20)
22 | for _ in range(post_data_length):
23 | required_origin_data.append(trace[a: a + 5])
24 | a += per
25 | return required_origin_data
26 |
27 |
28 | def get_acceleration(data):
29 | """
30 | 处理轨迹数据生成加速度等信息
31 | :param data: 一组长度为5的轨迹数组
32 | :return:
33 | """
34 | u = []
35 | i = len(data) - 1
36 | while i > 0:
37 | u.append((data[i]['x'] - data[i - 1]['x']) / (data[i]['date'] - data[i - 1]['date']))
38 | i -= 1
39 | t = len(u) - 1
40 | a = []
41 | while t > 0:
42 | a.append((u[t] + u[t - 1]) / 2)
43 | t -= 1
44 | e = a[1]
45 | _ = (a[0] - a[2]) / (data[3]['date'] - data[1]['date'])
46 |
47 | return {
48 | 'x': data[2]['x'],
49 | 'y': data[2]['y'],
50 | 'date': data[2]['date'],
51 | 'v': e,
52 | 'aspeed': _
53 | }
54 |
55 |
56 | def process_trace(trace):
57 | """
58 | 处理轨迹
59 | :param trace:
60 | :return:
61 | """
62 | speed_and_aspeed = []
63 | post_data_length = len(trace) - 4
64 | if post_data_length >= 20:
65 | post_data_length = 20
66 | required_origin_data = get_required_origin_data(post_data_length, trace)
67 | for i in range(post_data_length):
68 | process_data = required_origin_data[i]
69 | speed_and_aspeed.append(get_acceleration(process_data))
70 | return speed_and_aspeed
71 |
72 |
73 | def _generate_trace(distance, ypos):
74 | """
75 | 生成轨迹
76 | :param distance: 缺口距离
77 | :param ypos: y 坐标
78 | :return:
79 | """
80 | start_x = random.randint(105, 120)
81 | back = random.randint(2, 6)
82 | distance += back
83 | # 初速度
84 | v = 0
85 | # 位移/轨迹列表,列表内的一个元素代表0.02s的位移
86 | tracks_list = []
87 | # 当前的位移
88 | current = 0
89 | while current < distance - 13:
90 | # 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细
91 | a = random.randint(10000, 12000) # 加速运动
92 | # 初速度
93 | v0 = v
94 | t = random.randint(9, 18)
95 | s = v0 * t / 1000 + 0.5 * a * ((t / 1000) ** 2)
96 | # 当前的位置
97 | current += s
98 | # 速度已经达到v,该速度作为下次的初速度
99 | v = v0 + a * t / 1000
100 | # 添加到轨迹列表
101 | if current < distance:
102 | tracks_list.append(round(current))
103 | # 减速慢慢滑
104 | if round(current) < distance:
105 | for i in range(round(current) + 1, distance + 1):
106 | tracks_list.append(i)
107 | else:
108 | for i in range(tracks_list[-1] + 1, distance + 1):
109 | tracks_list.append(i)
110 | # 回退
111 | for _ in range(back):
112 | current -= 1
113 | tracks_list.append(round(current))
114 | tracks_list.append(round(current) - 1)
115 | if tracks_list[-1] != distance - back:
116 | tracks_list.append(distance - back)
117 | # 生成时间戳列表
118 | timestamp_list = []
119 | timestamp = int(time.time() * 1000)
120 | for i in range(len(tracks_list)):
121 | t = random.randint(11, 18)
122 | timestamp += t
123 | timestamp_list.append(timestamp)
124 | i += 1
125 | y_list = []
126 | zy = 0
127 | for j in range(len(tracks_list)):
128 | y = random.choice(
129 | [0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
130 | -1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, -1, 0, 0])
131 | zy += y
132 | y_list.append(zy)
133 | j += 1
134 | trace = []
135 | for index, x in enumerate(tracks_list):
136 | trace.append({
137 | 'x': x + start_x,
138 | 'y': y_list[index] + ypos,
139 | 'date': timestamp_list[index]
140 | })
141 | return trace[: -1]
142 |
143 |
144 | def get_risk_data(distance, start_time, ypos):
145 | """
146 | 根据缺口距离构造轨迹数组并处理成提交表单样式
147 | :return:
148 | """
149 | trace = _generate_trace(distance, ypos)
150 | speed_and_aspeed = process_trace(trace)
151 | time.sleep(random.uniform(0.3, 0.6))
152 | arrive_time = int(time.time() * 1000)
153 | spend_time = arrive_time - start_time
154 | return {
155 | 'click_times': 1,
156 | 'arrive_time': arrive_time,
157 | 'click_frequency': 1 / spend_time * 1000,
158 | 'spend_time': spend_time,
159 | 'speed_and_aspeed': speed_and_aspeed
160 | }
161 |
162 |
163 | if __name__ == '__main__':
164 | pass
165 |
--------------------------------------------------------------------------------
/ztggame/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/22 20:41
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 |
9 | import os
10 | import requests
11 | import base64
12 | import time
13 | import re
14 | from PIL import Image
15 | import cv2
16 | import numpy as np
17 |
18 | session = requests.session()
19 | session.headers = {
20 | 'Referer': 'https://my.ztgame.com/plugin/pwd',
21 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'
22 | }
23 |
24 |
25 | def _pic_download(url, type):
26 | """
27 | 图片下载
28 | :param url:
29 | :param type:
30 | :return:
31 | """
32 | save_path = os.path.abspath('...') + '\\' + 'images'
33 | if not os.path.exists(save_path):
34 | os.mkdir(save_path)
35 |
36 | img_path = save_path + '\\' + '{}.jpg'.format(type)
37 | img_data = session.get(url).content
38 | with open(img_path, 'wb') as f:
39 | f.write(img_data)
40 | return img_path
41 |
42 |
43 | def get_distance(slider_url, captcha_url):
44 | """
45 | 获取缺口距离
46 | :param slider_url:
47 | :param captcha_url:
48 | :return:
49 | """
50 | save_path = os.path.abspath('...') + '\\' + 'images'
51 | if not os.path.exists(save_path):
52 | os.mkdir(save_path)
53 |
54 | # 引用上面的图片下载
55 | slider_path = _pic_download(slider_url, 'slider')
56 |
57 | # 引用上面的图片下载
58 | captcha_path = _pic_download(captcha_url, 'captcha')
59 |
60 | # # 计算拼图还原距离
61 | target = cv2.imread(slider_path, 0)
62 | template = cv2.imread(captcha_path, 0)
63 | w, h = target.shape[::-1]
64 |
65 | temp = save_path + '\\' + 'temp.jpg'
66 | targ = save_path + '\\' + 'targ.jpg'
67 | cv2.imwrite(temp, template)
68 | cv2.imwrite(targ, target)
69 | target = cv2.imread(targ)
70 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
71 | target = abs(255 - target)
72 | cv2.imwrite(targ, target)
73 | template = cv2.imread(temp)
74 | template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
75 | template = abs(255 - template)
76 | cv2.imwrite(temp, template)
77 | target = cv2.imread(targ)
78 | template = cv2.imread(temp)
79 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
80 | x, y = np.unravel_index(result.argmax(), result.shape)
81 |
82 | # 调用PIL Image 做测试
83 | image = Image.open(captcha_path)
84 |
85 | xy = (y, x, y + w, x + h)
86 | # 切割
87 | imagecrop = image.crop(xy)
88 | # 保存切割的缺口
89 | imagecrop.save(save_path + '\\' + "new_image.png")
90 | # imagecrop.show()
91 | return y
92 |
93 |
94 | def _init_slider():
95 | """
96 | 初始化滑块
97 | :return:
98 | """
99 | url = 'https://nocaptcha.ztgame.com/nocaptcha/init'
100 |
101 | params = {
102 | 'version': '0.0.1',
103 | 'callback': '',
104 | 'appid': 'my',
105 | 'element': '.captcha',
106 | 'type': 'verifydrag',
107 | 'width': '292px',
108 | 'height': '240px',
109 | 'mode': 'embed',
110 | '_': int(time.time() * 1000)
111 | }
112 |
113 | resp = session.get(url, params=params).json()
114 |
115 | if resp['code'] == 0:
116 | html = resp['html']
117 | imgs = re.findall(r'url\((.*?)\);', html)
118 |
119 | return {
120 | 'nonce': resp['nonce'],
121 | 'captcha_url': 'https:' + imgs[0],
122 | 'slider_url': 'https:' + imgs[1]
123 | }
124 | return None
125 |
126 |
127 | def _slider_verify(nonce, distance):
128 | """
129 | 滑块验在
130 | :param nonce: 验证码 ID
131 | :param distance: 缺口距离
132 | :return:
133 | """
134 | url = 'https://nocaptcha.ztgame.com/nocaptcha/verify'
135 |
136 | params = {
137 | 'version': '0.0.1',
138 | 'appid': 'my',
139 | 'input': base64.b64encode(str(distance).encode()).decode(),
140 | 'nonce': nonce,
141 | 'callback': '',
142 | '_': int(time.time() * 1000)
143 | }
144 |
145 | resp = session.get(url, params=params).json()
146 | print(resp)
147 | if resp['code'] == 0:
148 | return resp['token']
149 | return None
150 |
151 |
152 | def crack():
153 | # 初始化滑块
154 | init_data = _init_slider()
155 | # 获取缺口距离
156 | distance = get_distance(init_data['slider_url'], init_data['captcha_url'])
157 | # 最终验证
158 | result = _slider_verify(init_data['nonce'], distance)
159 | if result:
160 | return {
161 | 'success': 1,
162 | 'message': '校验通过! ',
163 | 'data': {
164 | 'token': result
165 | }
166 | }
167 | return {
168 | 'success': 0,
169 | 'message': '校验失败! ',
170 | 'data': None
171 | }
172 |
173 |
174 | if __name__ == '__main__':
175 | x = crack()
176 | print(x)
177 |
--------------------------------------------------------------------------------
/wanmei/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 19:54
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : geetest.py
6 | # @Software: PyCharm
7 |
8 | import random
9 | import time
10 | import json
11 | import requests
12 | from wanmei.img_locate import _get_distance, process_location
13 | from wanmei import wm_crypt
14 | from wanmei.trace import _generate_trace
15 |
16 |
17 | session = requests.session()
18 | session.headers = {
19 | 'Referer': 'https://passport.wanmei.com/sso/login?service=passport&isiframe=1&location=2f736166652f',
20 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36'
21 | }
22 |
23 |
24 | def get_cap_ticket():
25 | """
26 | 获取验证码标识
27 | :return:
28 | """
29 | url = 'https://passport.wanmei.com/sso/servlet/ajax?op=mCaptchaInit&isAICap=1'
30 | resp = session.get(url).json()
31 | if resp['code'] == 0:
32 | cap_ticket = resp['data']['capTicket']
33 | return cap_ticket
34 | return None
35 |
36 |
37 | def fist_test(cap_ticket):
38 | """
39 | 智能验证, 判断用户可疑程度, 使用点选验证还是滑块验证
40 | :param cap_ticket:
41 | :return:
42 | """
43 | url = 'https://captchas.wanmei.com/aicaptcha/firstTest'
44 | r = "[[149,163,3,772],[146,191,6,859],[146,191,5,859],[146,192,6,873],[146,192,5,873],[146,206,3,978],[146,209,6,1004],[146,209,5,1005],[146,211,6,1012],[146,211,5,1013],[145,232,3,1122],[145,233,1,1283],[145,233,2,1497]]"
45 | op = wm_crypt.encrypt(cap_ticket, r)
46 | params = {
47 | 'callback': '',
48 | 'appId': '10003',
49 | 'capTicket': cap_ticket,
50 | 'mobile': '0',
51 | 'op': op,
52 | 'fp': '4170524067',
53 | 'isInIframe': 'true',
54 | '_': int(time.time() * 1000)
55 | }
56 | resp = session.get(url, params=params)
57 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
58 | if result['type'] == 'move_captcha':
59 | return True
60 | return False
61 |
62 |
63 | def init_slider(cap_ticket):
64 | """
65 | 初始化验证码
66 | :return:
67 | """
68 | params = {
69 | 'callback': '',
70 | 'appId': '10003',
71 | 'capTicket': cap_ticket,
72 | '_': int(time.time() * 1000)
73 | }
74 | url = 'https://captchas.wanmei.com/aicaptcha/getCaptcha?'
75 | resp = session.get(url, params=params)
76 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
77 | if result['code'] == 0:
78 | print('滑块初始化成功! ')
79 | return {
80 | 'cap_key': result['capKey'],
81 | 'img_url': result['imgUrl'],
82 | 'data': result['data']
83 | }
84 | return None
85 |
86 |
87 | def _slider_verify(cap_ticket, cap_key, validate, op):
88 | """
89 | 最终验证
90 | :return:
91 | """
92 | url = 'https://captchas.wanmei.com/aicaptcha/secondTest/move_captcha'
93 | params = {
94 | 'callback': '',
95 | 'appId': '10003',
96 | 'capTicket': cap_ticket,
97 | 'capKey': cap_key,
98 | 'validData': validate,
99 | 'op': op,
100 | 'fp': '4170524067',
101 | 'label': 1,
102 | '_': int(time.time() * 1000)
103 | }
104 | resp = session.get(url, params=params)
105 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
106 | print(result)
107 | if result['code'] == 0:
108 | return {
109 | 'success': 1,
110 | 'message': '校验通过! ',
111 | 'data': {
112 | 'result': result['result']
113 | }
114 | }
115 | return {
116 | 'success': 0,
117 | 'message': '校验失败! ',
118 | 'data': None
119 | }
120 |
121 |
122 | def crack():
123 | capt_ticket = get_cap_ticket()
124 | # 触发验证, 最开始可能是点选, 直到出现滑块验证为止
125 | while True:
126 | check = fist_test(capt_ticket)
127 | if check:
128 | break
129 | # 初始化滑块
130 | init_data = init_slider(capt_ticket)
131 | # 处理图片还原数组
132 | location_list = process_location(json.loads(init_data['data']))
133 | # 获取缺口距离
134 | distance = _get_distance(location_list, init_data['img_url'])
135 | # 构造轨迹
136 | start_time = int(time.time() * 1000)
137 | time.sleep(random.uniform(0.1, 0.3))
138 | trace = _generate_trace(distance + random.randint(5, 10), start_time)
139 | # 加密轨迹数据
140 | # op
141 | op = wm_crypt.encrypt(capt_ticket, json.dumps(trace))
142 | time.sleep(random.uniform(1.5, 2.5))
143 | # validate
144 | validate = {
145 | 'length': distance,
146 | 'validateTimeMilSec': int(time.time() * 1000) - start_time
147 | }
148 | validate_data = wm_crypt.encrypt(capt_ticket, json.dumps(validate))
149 | result = _slider_verify(capt_ticket, init_data['cap_key'], validate_data, op)
150 | return result
151 |
152 |
153 | if __name__ == '__main__':
154 | x = crack()
155 | print(x)
--------------------------------------------------------------------------------
/wanmei/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/9 19:14
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : aes_encrypt.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import cv2
10 | import numpy as np
11 | import requests
12 | from PIL import Image
13 |
14 |
15 | def _pic_download(url, type):
16 | """
17 | 图片下载
18 | :param url:
19 | :param type:
20 | :return:
21 | """
22 | save_path = os.path.abspath('...') + '\\' + 'images'
23 | if not os.path.exists(save_path):
24 | os.mkdir(save_path)
25 |
26 | img_path = save_path + '\\' + '{}.jpg'.format(type)
27 | img_data = requests.get(url).content
28 | with open(img_path, 'wb') as f:
29 | f.write(img_data)
30 | return img_path
31 |
32 |
33 | def process_location(location_array):
34 | """
35 | 处理滑块验证码接口返回的图片还原数组
36 | :param location_array:
37 | :return: 图片顺序
38 | """
39 | new_loaction_list = []
40 | for t in location_array:
41 | if t < 20:
42 | new_loaction_list.append({
43 | 'x': -int(260 / 20 * t),
44 | 'y': 0
45 | })
46 | else:
47 | new_loaction_list.append({
48 | 'x': -int(260 / 20 * (t % 20)),
49 | 'y': -60
50 | })
51 | return new_loaction_list
52 |
53 |
54 | def _cut_slider(path):
55 | """
56 | 滑块切割
57 | :return:
58 | """
59 | image = Image.open(path)
60 | x = []
61 | y = []
62 | for i in range(image.size[0]):
63 | for j in range(image.size[1]):
64 | pix = image.load()[i, j]
65 | if pix != 255:
66 | x.append(i)
67 | y.append(j)
68 | z = (np.min(x), np.min(y), np.max(x), np.max(y))
69 | result = image.crop(z)
70 | result.convert('RGB').save(path)
71 | # result.show()
72 | return result.size[0], result.size[1]
73 |
74 |
75 | def get_merge_image(location_list, url):
76 | """
77 | 根据图片位置合并还原
78 | :param location_list: 图片位置数组
79 | :param url: 图片 url
80 | :return:
81 | """
82 | save_path = os.path.abspath('...') + '\\' + 'images'
83 | if not os.path.exists(save_path):
84 | os.mkdir(save_path)
85 |
86 | filename = _pic_download(url, 'all')
87 | im = Image.open(filename)
88 | width, height = im.size
89 | # print(width, height)
90 | big = im.crop((0, 0, 260, height))
91 | captcha_path = save_path + '\\' + 'captcha.jpg'
92 | slider_path = save_path + '\\' + 'slider.jpg'
93 | big.convert('RGB').save(captcha_path)
94 |
95 | small = im.crop((260, 0, width, height))
96 | small.convert('RGB').save(slider_path)
97 |
98 | new_im = Image.new('RGB', (260, height))
99 |
100 | upper_list = location_list[:20]
101 | lower_list = location_list[20:]
102 |
103 | x_offset = 0
104 | for location in upper_list:
105 | imgcrop = big.crop((abs(location['x']), abs(location['y']), abs(location['x']) + 13, abs(location['y']) + 60))
106 | new_im.paste(imgcrop, (x_offset, 0))
107 | x_offset += 13
108 |
109 | x_offset = 0
110 | for location in lower_list:
111 | imgcrop = big.crop((abs(location['x']), abs(location['y']), abs(location['x']) + 13, abs(location['y']) + 60))
112 | new_im.paste(imgcrop, (x_offset, 60))
113 | x_offset += 13
114 |
115 | new_im.show()
116 | new_im.save(captcha_path)
117 | return captcha_path, slider_path
118 |
119 |
120 | def process_img(img1, img2):
121 | """
122 | 图片处理
123 | :param img1: 处理后图片
124 | :param img2: 待处理图片
125 | :return:
126 | """
127 | cv2.imwrite(img1, img2)
128 | target = cv2.imread(img1)
129 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
130 | target = abs(255 - target)
131 | cv2.imwrite(img1, target)
132 |
133 |
134 | def _get_distance(location_list, url):
135 | """
136 | 获取缺口距离
137 | :param url: 验证码图片合集
138 | :return:
139 | """
140 | save_path = os.path.abspath('...') + '\\' + 'images'
141 | if not os.path.exists(save_path):
142 | os.mkdir(save_path)
143 |
144 | captcha_path, slider_path = get_merge_image(location_list, url)
145 | # 计算拼图还原距离
146 | target = cv2.imread(slider_path, 0)
147 | template = cv2.imread(captcha_path, 0)
148 | temp = save_path + '\\' + 'temp.jpg'
149 | targ = save_path + '\\' + 'targ.jpg'
150 | process_img(temp, template)
151 | process_img(targ, target)
152 | w, h = _cut_slider(targ)
153 | cv2.imwrite(temp, template)
154 | target = cv2.imread(targ)
155 | template = cv2.imread(temp)
156 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
157 | x, y = np.unravel_index(result.argmax(), result.shape)
158 | # 缺口位置
159 | # print((y, x, y + w, x + h))
160 |
161 | # 调用PIL Image 做测试
162 | image = Image.open(captcha_path)
163 |
164 | xy = (y + 3, x, y + w, x + h)
165 | # 切割
166 | imagecrop = image.crop(xy)
167 | # 保存切割的缺口
168 | imagecrop.save(save_path + '\\' + "new_image.jpg")
169 | imagecrop.show()
170 | return int(y + 3)
171 |
--------------------------------------------------------------------------------
/tongdun/img_locate.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/10/17 8:21
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : img_locate.py
6 | # @Software: PyCharm
7 |
8 | import os
9 | import numpy as np
10 | import execjs
11 | from PIL import Image
12 | import cv2
13 | import requests
14 |
15 |
16 | def _pic_download(url, type):
17 | """
18 | 图片下载
19 | :param url:
20 | :param type:
21 | :return:
22 | """
23 | save_path = os.path.abspath('...') + '\\' + 'images'
24 | if not os.path.exists(save_path):
25 | os.mkdir(save_path)
26 |
27 | img_path = save_path + '\\' + '{}.jpg'.format(type)
28 | img_data = requests.get('https://static.tongdun.net' + url).content
29 | with open(img_path, 'wb') as f:
30 | f.write(img_data)
31 | return img_path
32 |
33 |
34 | def get_merge_str(imageGeneral, bgImageSplitSequence):
35 | """
36 | 获取图片还原数组
37 | :param imageGeneral:
38 | :param bgImageSplitSequence:
39 | :return:
40 | """
41 | with open('merge_img.js', 'rb') as f:
42 | js = f.read().decode()
43 | ctx = execjs.compile(js)
44 | return ctx.call('merge', imageGeneral, bgImageSplitSequence)
45 |
46 |
47 | def parse_int(text):
48 | js = """
49 | function parse_int(text) {
50 | return parseInt(text, 16)
51 | }
52 | """
53 | ctx = execjs.compile(js)
54 | return ctx.call('parse_int', text)
55 |
56 |
57 | def merge_img(init_data):
58 | """
59 | 还原验证码
60 | :return:
61 | """
62 | img_path = _pic_download(init_data['validateCodeObj']['slideBgi'], 'captcha')
63 | img = Image.open(img_path)
64 | upper_list = []
65 | lower_list = []
66 | for i in range(8):
67 | upper_crop = img.crop((round(320 / 8) * i, 0, round(320 / 8) * i + 40, 90))
68 | upper_list.append(upper_crop)
69 | lower_crop = img.crop((round(320 / 8) * i, 90, round(320 / 8) * i + 40, 180))
70 | lower_list.append(lower_crop)
71 |
72 | new_image = Image.new('RGB', img.size)
73 | merge_str = get_merge_str(init_data['validateCodeObj']['imageGeneral'],
74 | init_data['validateCodeObj']['bgImageSplitSequence'])
75 | for m in range(16):
76 | n = parse_int(merge_str[m])
77 | if n < 8:
78 | if m >= 8:
79 | new_image.paste(lower_list[m - 8], (round(320 / 8) * n, 0))
80 | else:
81 | new_image.paste(upper_list[m], (round(320 / 8) * n, 0))
82 | else:
83 | if m >= 8:
84 | new_image.paste(lower_list[m - 8], (round(320 / 8) * (n - 8), 90))
85 | else:
86 | new_image.paste(upper_list[m], (round(320 / 8) * (n - 8), 90))
87 |
88 | new_image.show()
89 |
90 | save_path = os.path.abspath('...') + '\\' + 'images'
91 | if not os.path.exists(save_path):
92 | os.mkdir(save_path)
93 |
94 | img_path = save_path + '\\' + 'new_captcha.jpg'
95 | new_image.save(img_path)
96 | return img_path
97 |
98 |
99 | def _cut_slider(path):
100 | """
101 | 滑块切割
102 | :return:
103 | """
104 | image = Image.open(path)
105 | x = []
106 | y = []
107 | for i in range(image.size[0]):
108 | for j in range(image.size[1]):
109 | pix = image.load()[i, j]
110 | if pix != 255:
111 | x.append(i)
112 | y.append(j)
113 | z = (np.min(x), np.min(y), np.max(x), np.max(y))
114 | result = image.crop(z)
115 | result.convert('RGB').save(path)
116 | # result.show()
117 | return result.size[0], result.size[1]
118 |
119 |
120 | def get_distance(init_data):
121 | """
122 | 获取缺口距离
123 | :param init_data: 验证码初始化数据
124 | :return:
125 | """
126 | save_path = os.path.abspath('...') + '\\' + 'images'
127 | if not os.path.exists(save_path):
128 | os.mkdir(save_path)
129 |
130 | # 引用上面的图片下载
131 | slider_path = _pic_download(init_data['validateCodeObj']['slideImage'], 'slider')
132 |
133 | # 图片还原
134 | captcha_path = merge_img(init_data)
135 |
136 | # # 计算拼图还原距离
137 | target = cv2.imread(slider_path, 0)
138 | template = cv2.imread(captcha_path, 0)
139 | temp = save_path + '\\' + 'temp.jpg'
140 | targ = save_path + '\\' + 'targ.jpg'
141 | cv2.imwrite(targ, target)
142 | w, h = _cut_slider(slider_path)
143 | cv2.imwrite(temp, template)
144 | target = cv2.imread(targ)
145 | target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
146 | target = abs(255 - target)
147 | cv2.imwrite(targ, target)
148 | target = cv2.imread(targ)
149 | template = cv2.imread(temp)
150 | result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
151 | x, y = np.unravel_index(result.argmax(), result.shape)
152 |
153 | # 调用PIL Image 做测试
154 | image = Image.open(captcha_path)
155 |
156 | xy = (y, x, y + w, x + h)
157 | # 切割
158 | imagecrop = image.crop(xy)
159 | # 保存切割的缺口
160 | imagecrop.convert('RGB').save(save_path + '\\' + "new_image.jpg")
161 | imagecrop.show()
162 | return int(round(y))
163 |
164 |
165 | if __name__ == '__main__':
166 | pass
167 |
--------------------------------------------------------------------------------
/anjuke/geetest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Time : 2019/9/27 10:43
3 | # @Author : Esbiya
4 | # @Email : 18829040039@163.com
5 | # @File : test.py
6 | # @Software: PyCharm
7 |
8 |
9 | import requests
10 | import json
11 | import execjs
12 | import os
13 | import random
14 | from PIL import Image
15 |
16 | headers = {
17 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
18 | 'accept-encoding': 'gzip, deflate, br',
19 | 'accept-language': 'zh-CN,zh;q=0.9',
20 | 'referer': 'https://www.anjuke.com/captcha-verify/',
21 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'
22 | }
23 |
24 |
25 | def get_token():
26 | url = 'https://cdata.58.com/fpToken?callback='
27 | resp = requests.get(url, headers=headers)
28 | result = json.loads(resp.text.replace('(', '').replace(')', ''))
29 | if result['status'] == 'success':
30 | return result['token']
31 |
32 |
33 | def get_track(distance):
34 | track_path = os.getcwd() + '\\' + 'trace.txt'
35 | with open(track_path, 'r+') as fp:
36 | lines = fp.readlines()
37 | match_tracks = []
38 | for line in lines:
39 | if line.strip() == '':
40 | continue
41 | x_pos = int(line.split('=')[0])
42 | track = line.split('=')[1].strip()
43 |
44 | if distance == x_pos or distance == x_pos + 1 or distance == x_pos - 1:
45 | match_tracks.append((distance, track))
46 | try:
47 | x_pos, track = random.choice(match_tracks)
48 | return x_pos, track
49 | except:
50 | return distance, None
51 |
52 |
53 | def pic_download(url):
54 | """
55 | 下载验证码图片
56 | :param url:
57 | :return:
58 | """
59 | img_data = requests.get(url).content
60 | img_db_path = os.getcwd() + '\\' + 'img_db'
61 | if not os.path.exists(img_db_path):
62 | os.mkdir(img_db_path)
63 | img_path = img_db_path + '\\' + 'anjuke_captcha.jpg'
64 | with open(img_path, 'wb') as f:
65 | f.write(img_data)
66 | return img_db_path, img_path
67 |
68 |
69 | def get_distance(image):
70 | """
71 | 获取缺口距离
72 | :param image:
73 | :return:
74 | """
75 | img_db_path, img_path = pic_download(image)
76 | image = Image.open(img_path)
77 | # image.show()
78 | image = image.resize((284, 160))
79 | image = image.convert('L')
80 | yuzhi = 150
81 | yuzhi2 = 40
82 | ll = 10
83 | for i in range(55, image.size[0] - 20): # 260
84 | for j in range(0, image.size[1] - 20): # 160
85 | flag = True
86 | for l in range(0, ll):
87 | pixel = image.getpixel((i, j)) - image.getpixel((i + 1, j + l))
88 | if pixel < yuzhi2:
89 | flag = False
90 | # pixel = image.getpixel((i - l, j))
91 | # if pixel