模拟登录之拉勾网

接上一篇模拟登录之果壳网。果壳网的模拟登录较为简单,表单的结构不复杂,而有些网站会给密码和账号加密、再添加一些额外验证字段后才进行验证,有些难度,这篇用以记录拉勾网模拟登录过程,前期准备和文章模拟登录之果壳网一样,移步{% post_link 模拟登录之果壳网 %}。

思路

  1. 分析表单,找出需要提交的字段
  2. 经过分析,大多数提交字段都可以在 html 源码中找到
  3. 密码经过 md5 加密

分析表单

拉勾网登录 url:https://passport.lagou.com/login/login.html

登录账号:[email protected]
登录密码:123456789

模拟登录之拉勾网_第1张图片
login.png

由于之前实验了多次,所以出现拉钩官网重置密码的提示,可以忽略。

点击登录后的信息:

模拟登录之拉勾网_第2张图片
info.png

重要的有两个,login.jsoncreate?from=register&refresh=1506950234998
先查看login.json

模拟登录之拉勾网_第3张图片
form2.png

提交的方法为 POST ,说明表单提交的目的地就是这个地址,还有需要提交的表单字段:

模拟登录之拉勾网_第4张图片
form1.png

多达 8 项表单字段,红色方框内以 X- 开头的都可以在 html 源码中找到,值得注意的是橙色方框内的 password 字段并不是我们所填的密码 123456789,而是一串很长的且不是由用户输入的字符串,这就是经过加密的密码,经过某种加密算法生成。

再看create?from=register&refresh=1506950234998

模拟登录之拉勾网_第5张图片
capcha.png

这就是验证码的地址,其实在一开始登录界面时并没有要求输入验证码,但是既然在调试器中发现了,并且为了此次模拟登录的成功,就要将它添加到模拟登录的逻辑中。

寻找表单字段

X-Requested-With

在多次试验后,此字段为固定值:X-Requested-With : XMLHttpRequest

X-Anit-Forge-Code 和 X-Anit-Forge-Token

这两个值在 html 源码中找到,可以使用正则表达式筛选出来:

token.png
# 获取 X-Anit-Forge-Code 和 X-Anit-Forge-Token
def get_anti_Code_Token():
    url = 'https://passport.lagou.com/login/login.html'
    response = session.get(url, headers=headers)
    match_obj = re.match(r".*?Forge_Token = '(.*?)'.*Forge_Code = '(.*?)'.*", response.text, re.DOTALL)
    if match_obj:
        code = match_obj.group(2)
        token = match_obj.group(1)
        return code, token
    else:
        'failed to match code and token!'
isValidate

此字段为固定值,isValidate: true

submit

此字段为空

request_form_verifyCode
  1. 验证码,通过访问https://passport.lagou.com/vcode/create?from=register&refresh=当前时间秒数获得,类似上一篇模拟登录之果壳网,获取验证码方法相似:
# 获取验证码,生成当前时间,拼凑好url,将 response 的内容(也就是验证码图片)下载到本地,在通过 PIL 库展示给用户进行输入
def get_captcha():
    url = 'https://passport.lagou.com/vcode/create?from=register&refresh={}'.format(str(int(time.time() * 1000)))
    response = session.get(url, headers=headers)
    with open('captcha.jpg', 'wb') as f:
        f.write(response.content)
        f.close()
    from PIL import Image
    try:
        captcha_image = Image.open('captcha.jpg')
        captcha_image.show()
        captcha_image.close()
    except:
        print 'captcha.jpg not found!'
    code = raw_input('please check the captcha code and enter it:')
    return code
username

直接输入

password

password 经过 md5 加密,在 html 源码中,查看每一个 js 文件,然后找到了拉勾网对密码加密的具体方法:

模拟登录之拉勾网_第6张图片
md5.png

主要分析红色方框两行代码,分为以下几步加密了用户输入的密码:

  1. 定义一个 c 为字符串 "veenike"
  2. md5() 方法加密用户输入的密码,再将此时得到的值用 hexdigest() 方法转成另一个字符串,字面意思大概是转换成一串 16 进制数,暂且将它命名为 first_encrypt
  3. 此时再将 first_encrypt 与 c 相加,公式为 c + first_encrypt + c,此时得到的结果给它命名为 rude
  4. 此时再重复第 2 步md5() 再次编码,hexdigest() 再次编码,就得到最后结果

写成 python 代码:

def encrypt_password(password):
    stable_word = 'veenike'
    first_encrypt = hashlib.md5(password).hexdigest()
    rude = stable_word + first_encrypt + stable_word
    second_encrypt = hashlib.md5(rude).hexdigest()
    print second_encrypt
    return second_encrypt

到这里,所有的表单字段都已经找到,开始写登录主函数。

登录

一些说明:

  • 基本爬虫必备 User-Agent
  • 用到 requests session(),保证连接持续性
  • cookielib 保存模拟登录成功后的 cookies 到本地,之后的登录读取此 cookies,免账号密码登录

登录主函数示例:

def lagou_login(phone_number, password):
    url = 'https://passport.lagou.com/login/login.json'
    post_data = {
        'isValidate': 'true',
        'username': phone_number,
        'password': # 加密方法函数,
        'request_form_verifyCode': # 获取验证码,
        'submit': ''
    }
    code_token = # 获取两个 token 值
    token_headers = # user-agent 模仿浏览器
    token_headers['X-Anit-Forge-Code'] = code_token[0]
    token_headers['X-Anit-Forge-Token'] = code_token[1]
    token_headers['X-Requested-With'] = 'XMLHttpRequest'
    token_headers['Referer'] = 'https://passport.lagou.com/login/login.html' # 在浏览器找到添加
    response = session.post(url, data=post_data, headers=token_headers) # 用 session 保持连续性
    session.cookies.save()  # 保存登录成功后的 cookies
    pass

Referer 也是要提交的表单字段之一,和其他字段一样,在调试器中找到。

等代码运行完后看看保存到本地的 cookies

cookies.png

目测有效期为一个星期左右。

测试 cookies 是否有效

获取到 cookies 后,因为不知道 cookies 是否有效,此时有必要写一个函数来验证它的有效性,拿着这个 cookies 去访问一个需要登录后才能访问的 url,比如个人中心,这些 url 没有登录是不能访问的:

session = requests.session()
session.cookies = cookielib.LWPCookieJar('cookies.txt')
try:
    session.cookies.load(ignore_discard=True) #加载cookies
except:
    print 'cookies failed to load!'
else:
    print 'cookies has been loading!'
    
def is_login(): 
    url = 'https://www.lagou.com/mycenter/invitation.html'
    response = session.get(url, headers=headers)
    if response.status_code != 200:
        return False
    else:
        return True

返回状态码为 200 时,就说明此 cookies 有效。

完整代码地址: github

你可能感兴趣的:(模拟登录之拉勾网)