有没有人研究过用Python实现51job的登录?

我猜这里很多人不用 51job ,不过 lz 是苦逼的传统行业,想没事用 python 登录下 51job 刷下简历,本机上是没什么问题了,放到 aws 上怎么就不行了,难道他们不让国外 ip 访问?智联貌似就没问题,这个要怎么解决,设 vpn ?
有没有人研究过用Python实现51job的登录?

15 回复

你的疑问貌似可以很简单就能验证吧


我研究过,51job的登录确实有点门道。他们现在主要用滑块验证码,得先破解这个才能登录。

核心思路是模拟浏览器操作,用Selenium控制浏览器,然后通过图像识别计算滑块缺口位置。这里有个关键点:51job的缺口图是带干扰线的,直接模板匹配效果不好,得用边缘检测。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
import time
import requests
from PIL import Image
import cv2
import numpy as np

def login_51job(username, password):
    # 启动浏览器
    driver = webdriver.Chrome()
    driver.get('https://login.51job.com/login.php')
    driver.maximize_window()
    time.sleep(2)
    
    # 输入账号密码
    driver.find_element(By.ID, 'loginname').send_keys(username)
    driver.find_element(By.ID, 'password').send_keys(password)
    time.sleep(1)
    
    # 点击登录触发验证码
    driver.find_element(By.CLASS_NAME, 'login_btn').click()
    time.sleep(3)
    
    # 获取验证码图片
    bg_img = driver.find_element(By.CLASS_NAME, 'yidun_bg-img')
    front_img = driver.find_element(By.CLASS_NAME, 'yidun_jigsaw')
    
    # 下载图片
    bg_url = bg_img.get_attribute('src')
    front_url = front_img.get_attribute('src')
    
    bg_data = requests.get(bg_url).content
    front_data = requests.get(front_url).content
    
    with open('bg.jpg', 'wb') as f:
        f.write(bg_data)
    with open('front.jpg', 'wb') as f:
        f.write(front_data)
    
    # 图像处理找缺口位置
    bg = cv2.imread('bg.jpg')
    front = cv2.imread('front.jpg')
    
    # 边缘检测
    bg_edge = cv2.Canny(bg, 100, 200)
    front_edge = cv2.Canny(front, 100, 200)
    
    # 模板匹配
    result = cv2.matchTemplate(bg_edge, front_edge, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    
    # 计算滑块需要移动的距离
    gap_position = max_loc[0]
    
    # 获取滑块元素
    slider = driver.find_element(By.CLASS_NAME, 'yidun_slider')
    
    # 模拟拖动
    action = ActionChains(driver)
    action.click_and_hold(slider).perform()
    
    # 分段拖动,模拟人工操作
    tracks = get_track(gap_position)
    for track in tracks:
        action.move_by_offset(track, 0).perform()
        time.sleep(0.01)
    
    action.release().perform()
    time.sleep(2)
    
    # 检查是否登录成功
    if '我的简历' in driver.page_source:
        print('登录成功!')
        cookies = driver.get_cookies()
        return cookies
    else:
        print('登录失败')
        return None

def get_track(distance):
    """生成滑动轨迹"""
    track = []
    current = 0
    mid = distance * 3/4
    t = 0.2
    v = 0
    
    while current < distance:
        if current < mid:
            a = 2
        else:
            a = -3
        v0 = v
        v = v0 + a * t
        move = v0 * t + 1/2 * a * t * t
        current += move
        track.append(round(move))
    
    # 微调
    overshoot = current - distance
    track.append(-round(overshoot))
    return track

# 使用示例
if __name__ == '__main__':
    username = 'your_username'
    password = 'your_password'
    cookies = login_51job(username, password)

注意几个坑:1)滑块移动轨迹要模拟人工,匀速直线会被检测;2)缺口识别准确率不是100%,可能需要重试;3)他们偶尔会换验证码样式。

总结:核心是搞定滑块验证码。

没研究过,应该不会禁国外 IP 吧。既然你本机都可以了 试试用国内代理访问呗

的确啊 感觉没什么好问的= =


手头上没有稳定的国内 vpn , 所以想问问是不是通过修改登录请求的 headers 什么的解决,或者 51job 有没有什么对国际访问的 ip 什么的

是不是被检测到异地登录了



貌似不是,异地登录会跳验证码,这个直接拒绝连接了

你和 3 楼什么关系?超级马甲?

大概是去年偶而登录一下 51job ,感觉每次登录都要至少两次才成功。

第一次输入用户名密码,密码确定是对的,然按确定不能成功,会跳到带验证码的登录输入页面,然后再输入一遍,这才能成功进入个人管理页面。

没有任何关系,不是马甲

直接在头部添加登录后的 Cookie 不行么?

你都没说怎么不行,什么情景
难道让别人给你试?
再说你可真不是没事,是接到活了吧

IP 黑名单了吧?直接在服务器请求看下返回信息

username = “”
password = “”
s = requests.session()
url_login = “http://m.51job.com/my/login.php
url_login_post = “http://m.51job.com/ajax/my/login.ajax.php
url_refresh = “http://m.51job.com/ajax/resume/refreshresume.ajax.php
resume_id = “”
uagent = “Mozilla/5.0 (Linux; Android 4.0.4; <br> Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) <br> Chrome/18.0.1025.133 Mobile Safari/535.19”

headers = {
“user-agent”: uagent,
}

rsp1 = s.get(url_login)

params_login = {
“username”: username,
“password”: password,
“verifycode”: “”,
“autologin”: “0”
}
rsp2 = s.post(url_login_post, headers=headers, data=params_login)
rsp2.encoding = ‘utf-8’
jsn = json.loads(rsp2.text)
if not jsn[‘status’] == “1”:
raise LoginError(“51job login error”)


EC2 上跑的话直接 Timeout,之前抓异地登陆的结果是能正常返回 Json, 里面 status 为 1,

requests.exceptions.Timeout: (<urllib3.connectionpool.HTTPConnectionPool object at 0x7ff0bbddba90>, ‘Connection to m.51job.com timed out. (connect timeout=9.2)’)

在你的 ec2 上用 mtr 51job 的域名 看看哪一跳有问题 有的时候也可能是墙在搞鬼

requests cookie 最简单了

回到顶部