2018年年初,我对自己说:“你的人生在未来的几个月内可能会有一次大的变故,你一定要拼尽全力,因为你和别人的生活不一样。你没有任何退路。”
各位同学们好,随着几个月的python学习,渐渐的被这门语言的魅力所折服。其中也学到了许多有意思的东西,所以想把个人认为好玩的和大家分享一下。废话不多说,直接上代码:
进群:960410445 即可获取数十套PDF!
class Login(): """实现12306的登录""" def __init__(self): self.capycha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.27575294592849064' self.capycha_check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check' self.login_url = 'https://kyfw.12306.cn/passport/web/login' def download_code(self): """1.下载验证码""" response = session.get(self.capycha_url) f = open('code.jpg','wb') f.write(response.content) f.close() self.check_code()
不知道大家对那一张验证码有没有印象,说起网上购票,很多人谈起12306首先想到的就是他的验证码。登录的时候各种奇葩验证码,什么选择其中的龙舟,茶几往往自己不是抢不到票,而是被验证码挡在了门外。而对于爬虫来说更是如此,12306的首个关卡就是登录的时候验证码。12306的验证码有时连人类识别起来都非常困难,就别说咱们的程序了。所以,很多人爬取12306 的时候就是被验证码拦住了,久久不能前行。而今天,我将和大家分享一下12306的登录问题和咱们关心的车次信息查询问题。
首先打开12306的登录页面,F12打开管理者工具,我们故意输错验证码,发现出现了两条ajax请求,我们发现其中一条返回的结果是一张图片,这张图片恰好是我们的验证码。而另一条信息则是我们选择错误验证码返回的信息。
而这时我们就有了思路,先用get请求吧验证码图片下载到本地,然后把我们的识别情况以post方式发送,我们可以发现关键的点事answer这个参数,这个就是我们的验证码的选择情况。不知道大家看见这些数字想到的是什么了没有。没错,就是坐标系验证码。每一张图片都是一片固定位置,我们用鼠标点一下返回给服务器的都是一个坐标。这时,有了思路。就开始讲代码:我先定义了一个Login类,用来实现登录,我首先通过requests请求下载验证码图片,然后下载到本地,识别之后将数据以post方式返回给服务器。
def check_code(self): """2.检测验证码""" code = input("请输入验证码:") #要去掉验证码头部30px左右 data = { 'answer': code.split(), 'login_site': 'E', 'rand': 'sjrand', } res = session.post(self.capycha_check_url,data=data) res_json = res.json() if res_json['result_code'] != '4': print("验证码错误") self.download_code() else: self.login()
这中间有一个问题,就是如何告诉服务器我识别的这个验证码就是刚才我下载的那张?那这里又用到了一个知识点,就是 session的处理。简单点说就是会话保持。不过这个学过web开发的一般都会有印象,常常用来保持登录状态。
def login(self): """3.登录""" login_data = { 'username': config.username, 'password': config.password, 'appid': 'otn', } result = session.post(self.login_url,data=login_data) print(result.text) with open('cookies.json','w') as f: json.dump(session.cookies.get_dict(),f)
那么接下来就是发送用户名和密码实现登录了。登录完成之后我们就可以把cookies保存到本地,以备下一次使用。
if __name__ == '__main__': """登录""" # with open('cookies.json','r') as f: # session.cookies.update(json.loads(f.read())) get = Login() get.download_code()
哈哈,是不是成功了!
今天就讲到这,下次我讲讲如何实现车次信息查询。对了,我先附一张最后的实现效果:
有兴趣的小伙伴欢迎来交流,我们共同进步!
进群:960410445