├── 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