frankyxu 发表于 2019-5-9 11:02

利用python破解js加密模拟登录猎X网

本帖最后由 wushaominkk 于 2019-6-6 21:07 编辑

# python模拟登录猎聘
## 好久没写python相关的教程了,这次给大家带来的是python模拟登录猎聘,这次主要用到的技术就是python模拟执行js,分析js请求,调用python库,执行js

# 原理
## 利用python的requests包模拟正常请求,拿到登录cookie,其中会遇到js加密解密

# 代码
```
# -*- coding: utf-8 -*-
# @Time    : 2019/5/8 下午1:53
# @AuThor: xuzongyuan
# @site    : guapier.github.io
# @file    : login.py
# @Software: PyCharm
# @Function: 模拟登录猎聘
import time
import requests
import execjs
import re
import json
import hashlib

headers = {
    'Referer': 'https://www.liepin.com/',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/73.0.3683.103 Safari/537.36',
    'DNT': '1',
}


def loads_jsonp(_jsonp):
    """
    解析jsonp数据格式为json
    :return:
    """
    try:
      return json.loads(re.match(".*?({.*}).*", _jsonp, re.S).group(1))
    except:
      raise ValueError('Invalid Input')


def get_token(username):
    """
    获取用户token和加密js
    :param username: 用户名
    :return:
    """
    params = (
      ('sign', username),
      ('callback', 'jQuery171029989774566236793_' + timestamp),
      ('_', timestamp),
    )

    response = requests.get('https://passport.liepin.com/verificationcode/v1/js.json', headers=headers, params=params)
    print(response.text)
    return loads_jsonp(response.text)


def login(username, password):
    """
    登录
    :param username: 用户名
    :param password: 密码
    :return:
    """
    result = get_token(username)
    token = result.get('data').get('token')
    js = result.get('data').get('js')
    print(token, js, sep='\n')

    ctx = execjs.compile(js)
    value = ctx.call('encryptData', username)

    m = hashlib.md5()
    m.update(password.encode('utf-8'))

    params = (
      ('callback', 'jQuery17108618602708711502_'+timestamp),
      ('login', username),
      ('pwd', m.hexdigest()),
      ('token', token),
      ('value', value),
      ('url', ''),
      ('_bi_source', '0'),
      ('_bi_role', '0'),
      ('_', timestamp),
    )

    response = requests.get('https://passport.liepin.com/account/individual/v1/login.json', headers=headers,
                            params=params)
    print(response.text)


if __name__ == '__main__':
    timestamp = str(int(time.time() * 1000))
    login('用户名', '密码')


```
# 思路
## 分析请求,会发现第一个请求会返回来token和加密的js,用于第二个请求,计算value值,密码采用md5加密,然后构造请求,最后拿到返回结果


# 谢谢大家

时空之外 发表于 2019-5-9 16:10

frankyxu 发表于 2019-5-9 15:44
一家论坛有滑块验证码,可能要基于selenium才能做出来
我试了selenium,每次滑动都报错,为什么?以下是源码,仿你之前的那个做的:
import re
import os
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver import ChromeOptions
# from exe_js import js1, js2, js3, js4, js5


class OnePlusSpider(object):
    def __init__(self):
      self.login_url = 'https://account.oneplus.com/cn/login?jump=https%3A%2F%2Faccount.oneplus.com%2Fcn'
      self.username = '*****'# 账户名
      self.password = '*****'# 密码
      # option = ChromeOptions()
      # option.add_experimental_option('excludeSwitches', ['enable-automation'])
      self.driver = webdriver.Chrome()
      self.driver.maximize_window()

    # def __del__(self):
    #   self.driver.close()

    @staticmethod
    def get_track(distance):
      """
      根据偏移量获取移动轨迹
      :param distance: 偏移量
      :return: 移动轨迹
      """
      # 移动轨迹
      track = []
      # 当前位移
      current = 0
      # 减速阈值
      mid = distance * 4 / 5
      # 计算间隔
      t = 0.2
      # 初速度
      v = 0

      while current < distance:
            if current < mid:
                # 加速度为正2
                a = 2
            else:
                # 加速度为负3
                a = -3
            # 初速度v0
            v0 = v
            # 当前速度v = v0 + at
            v = v0 + a * t
            # 移动距离x = v0t + 1/2 * a * t^2
            move = v0 * t + 1 / 2 * a * t * t
            # 当前位移
            current += move
            # 加入轨迹
            track.append(round(move))
      print(track)
      print(sum(track))
      return track

    def one_plus_login(self):
      self.driver.get(self.login_url)
      self.driver.find_element_by_xpath('//*[@id="input-email"]').send_keys(self.username)
      self.driver.find_element_by_xpath('//*[@id="login-password"]').send_keys(self.password)
      bnt = self.driver.find_element_by_xpath('//*[@id="nc_1_n1z"]')
      ActionChains(self.driver).click_and_hold(bnt).perform()
      for x in self.get_track(268):
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
      ActionChains(self.driver).release().perform()
      time.sleep(5)


if __name__ == '__main__':
    new_spider = OnePlusSpider()
    new_spider.one_plus_login()

frankyxu 发表于 2019-5-10 15:05

uumesafe 发表于 2019-5-10 13:22
有个小问题,你怎么知道返回的js调用的是encryptData,因为返回的包括其他.




其实这个我也是调试中才发现,value值恰好是window.encryData(t)加密后完成的值,发现的过程是在调试login.json的时候发现会发出新的js.json请求,然后当在login.js调用栈打断点,发现加密是在js.json请求中完成的,然后就一步一步分析js.json的调用栈里面的加密

frankyxu 发表于 2019-5-9 11:04

大伙可以给点评分和热心值吗{:301_998:}

xiaosi2031 发表于 2019-5-9 11:15

支持下技术贴·

frankyxu 发表于 2019-5-9 11:17

xiaosi2031 发表于 2019-5-9 11:15
支持下技术贴·

哈哈哈,感谢支持

孙悟空丶 发表于 2019-5-9 11:19

高手,这个是高手

frankyxu 发表于 2019-5-9 11:22

孙悟空丶 发表于 2019-5-9 11:19
高手,这个是高手

感谢夸奖,这里面水还深这呢{:301_997:}

卡卡$罗特 发表于 2019-5-9 11:23

虽然脑子笨看不懂,但还是支持一下原创!

frankyxu 发表于 2019-5-9 11:25

卡卡$罗特 发表于 2019-5-9 11:23
虽然脑子笨看不懂,但还是支持一下原创!

哈哈哈,感谢,这个纸上得来终觉浅,绝知此事要躬行

jinsanpang666 发表于 2019-5-9 11:27

这个思路还是可以的,不错,加油

Abby_小杰 发表于 2019-5-9 11:27

这些网站登录,真的,天天打电话来推销,没意思
页: [1] 2 3
查看完整版本: 利用python破解js加密模拟登录猎X网