详解python 爬取12306验证码

发布时间:2026-10-03 05:17:52 浏览次数:3

接下来我将为你详细讲解“详解Python爬取12306验证码”的完整攻略。

1. 前言

在进行python爬虫时,验证码的破解常常是很重要的一步。而12306验证码的破解则是很多人首次接触验证码破解时的练手项目。本文将详细介绍如何使用Python来爬取12306的验证码。

2. 前置要求

在开始之前,需要满足以下前置要求:

  • 安装Python 2.X或3.X版本
  • 安装requests库
  • 安装Pillow库
  • 确定12306的验证码接口路径

3. 步骤

3.1 获取验证码图片

我们可以使用如下代码:

import requestsfrom PIL import Imagedef get_captcha():    url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    response = requests.get(url)    img_base64 = response.json()['image']    with open('captcha.png', 'wb') as f:        f.write(img_base64.decode('base64'))    img = Image.open('captcha.png')    img.show()if __name__ == '__main__':    get_captcha()

在该代码中,我们首先使用requests库向12306的验证码接口请求验证码图片数据,并将返回的数据中‘image’字段保存为本地的验证码图片文件。接下来,我们使用Pillow库中的Image.open()方法打开该图片,并使用show()方法将其展示出来。

这里我使用的是requests库以及Pillow库,你也可以根据自己的需求来选择使用其他库实现同样的功能。

3.2 自动识别验证码

如果你并不想手动输入验证码,那么可以使用tesseract-OCR。tesseract-OCR作为一款OCR引擎,不仅支持识别验证码图形,还支持多种语言的识别。

安装tesseract-OCR后,我们可以在原有的代码中添加自动识别验证码的功能:

import requestsimport pytesseractfrom PIL import Imagedef get_captcha_text():    url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    response = requests.get(url)    img_base64 = response.json()['image']    with open('captcha.png', 'wb') as f:        f.write(img_base64.decode('base64'))    img = Image.open('captcha.png')    text = pytesseract.image_to_string(img)    return textif __name__ == '__main__':    captcha_text = get_captcha_text()    print(captcha_text)

在该代码中,我们首先使用requests库向12306的验证码接口请求验证码图片数据,并将返回的数据中‘image’字段保存为本地的验证码图片文件。接下来,我们使用Pillow库中的Image.open()方法打开该图片,并使用pytesseract库中的image_to_string()方法自动识别验证码。

3.3 将识别结果提交到服务器

最后,我们可以将识别结果提交到服务器,以此完成登录过程。在该过程中,可能需要使用session等机制维持登录状态,具体操作可以参考Python的requests和cookies相关API。

示例一:

import requestsimport pytesseractfrom PIL import Imagedef login(username, password):    login_url = 'https://kyfw.12306.cn/otn/login/init'    captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    captcha_check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'    headers = {        'Host': 'kyfw.12306.cn',        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',        'Referer': 'https://kyfw.12306.cn/otn/login/init'    }    session = requests.session()    session.get(login_url, headers=headers)    captcha_text = get_captcha_text()    data = {        'answer': captcha_text,        'login_site': 'E',        'rand': 'sjrand'    }    response = session.post(captcha_check_url, data=data, headers=headers)    if response.json()['result_code'] == '4':        print('验证码校验通过!')    else:        print('验证码校验失败!')        return False    data = {        'username': username,        'password': password,        'appid': 'otn'    }    response = session.post(login_url, data=data, headers=headers)    if response.json()['result_code'] == 0:        print('登录成功!')        return True    else:        print('登录失败!')        return Falsedef get_captcha_text():    url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    response = requests.get(url)    img_base64 = response.json()['image']    with open('captcha.png', 'wb') as f:        f.write(img_base64.decode('base64'))    img = Image.open('captcha.png')    text = pytesseract.image_to_string(img)    return textif __name__ == '__main__':    login('your_username', 'your_password')

在该代码中,我们使用requests库创建了一个session对象,并分别请求了登录页面、验证码图片以及验证码校验接口。在验证码校验中,我们传递了自动识别出的结果,并通过检查返回的json数据中‘result_code’字段判断验证码是否识别正确。在成功校验验证码后,我们以同样的方式提交了用户名和密码,并最终判断了登录结果(通过判断返回的json数据中‘result_code’字段)。

示例二:

import requestsimport pytesseractfrom PIL import Imagesession = requests.session()def get_captcha_text():    url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    response = session.get(url)    img_base64 = response.json()['image']    with open('captcha.png', 'wb') as f:        f.write(img_base64.decode('base64'))    img = Image.open('captcha.png')    text = pytesseract.image_to_string(img)    return textdef get_cookie():    url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64'    response = session.get(url)    cookie = response.cookies['RAIL_EXPIRATION']    cookie = str(int(cookie) + 60 * 60 * 24 * 30)    return cookiedef login(username, password):    login_url = 'https://kyfw.12306.cn/otn/login/init'    captcha_check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'    headers = {        'Host': 'kyfw.12306.cn',        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',        'Referer': 'https://kyfw.12306.cn/otn/login/init'    }    captcha_text = get_captcha_text()    data = {        'answer': captcha_text,        'login_site': 'E',        'rand': 'sjrand'    }    response = session.post(captcha_check_url, data=data, headers=headers, cookies=session.cookies.get_dict())    if response.json()['result_code'] == '4':        print('验证码校验通过!')    else:        print('验证码校验失败!')        return False    cookie = get_cookie()    headers.update({        'Cookie': 'RAIL_EXPIRATION={};RAIL_DEVICEID=your_device_id'.format(cookie)    })    data = {        'username': username,        'password': password,        'appid': 'otn'    }    response = session.post(login_url, data=data, headers=headers, cookies=session.cookies.get_dict())    if response.json()['result_code'] == 0:        print('登录成功!')        return True    else:        print('登录失败!')        return Falseif __name__ == '__main__':    login('your_username', 'your_password')

在该代码中,我们依然是先获取并识别验证码,但是在验证码校验与登录过程中增加了许多细节操作。为了避免被封IP,我们获取了cookie中的RAIL_EXPIRATION,将其增加了30天的有效期后放回cookie中。在请求登录接口时,我们还需要将获取到的cookie作为请求头的一部分传递。

4. 总结

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477