目的:登录12306网站    【本文使用:账号登录(用户名+密码+选图片)】

结果呈现:通过屏幕显示的方法,显示“***,欢迎登录12306”(***是用户名)

注:朋友买了12.18号去广州玩耍的机票,看得我心痒痒,我也好想出去浪啊~我也想好想在阳光下自由的奔跑,呼吸新鲜的空气~

    Emma.......还是不了吧,最近太冷,我还是在实验室的机房好好享受空调的温暖吧~

【生活还是需要小休息的,学累了就出去转一转啊,转换下心情,然后......接着码代码!】

PS:本人没有12306的账号,所以是用的我爸爸的账号做的测试,结果最后显示的用户名是我爸爸的姓名:潘永桂

(顺道解释下我爸爸名字的由来......潘,是因为我爷爷姓潘;永,是永字辈;桂,我爸爸是桂花盛开的季节出生的,且是“贵”(gui)的谐音....)

唠嗑完毕,开始工作!

12306登录的网站为:https://kyfw.12306.cn/otn/resources/login.html

#下面为本实例的爬虫代码,若有问题可以给我留言,或者有更好的解决方法也可以私信我~



"""" 分析12306网站的登录流程 1.获取cookie,获取身份----->通过Session()会话技术 2.下载验证码----->验证码就是一张图片 将图片base64编码 3.校验验证码 4.校验用户名和密码 (需要上一步成功!) 【3成功之后,才能进行4】 5.获取权限token(需要上一步成功!)【4成功之后,才能进行5】 6.校验token(需要上一步成功!) """



一、简单通俗的脚本---->【面向过程】

PS:差不多把每一句都标注了,我真的费尽心血了,所以这个例子大家应该都能看懂~



import requests import re import base64 def get_answer(index): #将下载的验证图中的8个图片转换为对应的序列 change={ '1':'40,50', '2':'110,50', '3':'170,50', '4':'250,50', '5':'40,120', '6':'110,120', '7':'170,120', '8':'250,120', } index=index.split(',') #转换为列表 temp=[] for item in index: temp.append(change[item]) res=','.join(temp) return res ##1.获取cookie session=requests.Session() #实例化一个Session,Session自动化处理cookies headers={'user-agent':'Mozilla/5.0'} session.headers.update(headers) #模拟浏览器 cookie_url='https://kyfw.12306.cn/otn/login' session.get(cookie_url) #为了得到cooies值 #print(session.get(cookie_url).cookies) #<RequestsCookieJar[<Cookie JSESSIONID=E795D0482AC9F099C74E08CC261D8C48 for kyfw.12306.cn/otn>]> ##2.下载验证图片 captcha_url='https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1544746960656&callback=jQuery1910926816989316102_1544746952912&_=1544746952913' #这时候可以直接使用这一长串的网址,没有必要考虑params,也可以省略一些参数,这样返回的就是json格式,可以用字典的键值对获取信息;若不省略参数,就用正则表达式获取信息 response=session.get(captcha_url) data=response.text img_base64=re.findall(r'"image":"(.*?)"',data)[0] #生成的验证图片有前缀 image/jpg;base64,然后再加上img_base64 但测试后发现,前缀不需要 img_bytes=base64.b64decode(img_base64) #将图片由base64编码改为二进制编码 with open('captcha_面向过程.jpg','wb')as f: f.write(img_bytes) f.close() #print('验证码下载完成!') ##3.校验验证码(点击验证码上正确的图片) check_captcha='https://kyfw.12306.cn/passport/captcha/captcha-check?callback=jQuery191007509780872156879_1544746998996&rand=sjrand&login_site=E&_=1544746998999' params={'answer':get_answer(input('请输入正确的序号:').strip())}#需要传入answer参数,表示选择的图片,其中answer是坐标值 【此处写一个函数来获取】 response=session.get(check_captcha,params=params) data=response.text #返回是否验证码是否检验成功 ,当result_code为4的时候,校验成功! code=re.findall(r'"result_code":"(.*?)"',data)[0] if code=='4': print('验证图片成功!') ##4.校验用户名和密码-------->需要在3完成之后 login_url='https://kyfw.12306.cn/passport/web/login' #是一个post请求,需要带上data【注:data里面需要带上answer参数,但是发现可以省略,因为第3步已经成功】 data={ 'username':'***********', #此处写自己的账号 'password':'***********', #此处写自己的密码 'appid':'otn' } response=session.post(login_url,data=data) data=response.text #返回是否校验成功 ,当result_code为0的时候,校验成功! code=re.findall(r'"result_code":(\d+)',data)[0] #返回字符型 if code=='0': print('用户名密码检验成功!') ##5.获取token--------->需要在4完成之后 且它是存储在uamtk_url里面的,是个post请求,需要data uamtk_url='https://kyfw.12306.cn/passport/web/auth/uamtk' response=session.post(uamtk_url,data={'appid':'otn'}) data=response.text #返回是否校验通过【是否获得token】 ,当result_code为0的时候,成功获得token! code=re.findall(r'"result_code":(\d+)',data)[0] if code=='0': print('获取token成功!') newapptk=re.findall(r'"newapptk":"(.*?)"',data)[0] ##6.校验token check_token='https://kyfw.12306.cn/otn/uamauthclient' response=session.post(check_token,data={'tk':newapptk}) #print(response.text) #{"apptk":"uA9szPKYuIpD9KC4UBbeONFz-ztGl0qu_Xgn-7PGhfMij1210","result_code":0,"result_message":"验证通过","username":"潘永桂"} #此时拿到我的用户名了,成功! username=re.findall(r'"username":"(.*?)"',response.text)[0] print('{},欢迎登录12306'.format(username))



运行代码,一次的流程:

(1)文件夹中,下载的验证图片

怎么登录 MariaDB_怎么登录 MariaDB

怎么登录 MariaDB_javascript_02

(2)屏幕显示

怎么登录 MariaDB_爬虫_03

二、优化一下---->【面向对象】

PS:此时把注释都删了,看起来比较简洁~



import requests import re import base64 class ChineseRoad_login(): def __init__(self,username,password): self.username=username self.password=password def get_answer(slef,index): #将下载的验证图中的8个图片转换为对应的序列 change={ '1':'40,50', '2':'110,50', '3':'170,50', '4':'250,50', '5':'40,120', '6':'110,120', '7':'170,120', '8':'250,120', } index=index.split(',') #转换为列表 temp=[] for item in index: temp.append(change[item]) res=','.join(temp) return res def login(self): try: session=requests.Session() headers={'user-agent':'Mozilla/5.0'} session.headers.update(headers) cookie_url='https://kyfw.12306.cn/otn/login' session.get(cookie_url) captcha_url='https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1544746960656&callback=jQuery1910926816989316102_1544746952912&_=1544746952913' response=session.get(captcha_url) data=response.text img_base64=re.findall(r'"image":"(.*?)"',data)[0] img_bytes=base64.b64decode(img_base64) with open('captcha_面向对象.jpg','wb')as f: f.write(img_bytes) f.close() check_captcha='https://kyfw.12306.cn/passport/captcha/captcha-check?callback=jQuery191007509780872156879_1544746998996&rand=sjrand&login_site=E&_=1544746998999' params={'answer':self.get_answer(input('请输入正确的序号:').strip())} response=session.get(check_captcha,params=params) data=response.text code=re.findall(r'"result_code":"(.*?)"',data)[0] if code=='4': print('验证图片成功!') login_url='https://kyfw.12306.cn/passport/web/login' data={ 'username':self.username, 'password':self.password, 'appid':'otn' } response=session.post(login_url,data=data) data=response.text code=re.findall(r'"result_code":(\d+)',data)[0] if code=='0': print('用户名密码检验成功!') uamtk_url='https://kyfw.12306.cn/passport/web/auth/uamtk' response=session.post(uamtk_url,data={'appid':'otn'}) data=response.text code=re.findall(r'"result_code":(\d+)',data)[0] if code=='0': print('获取token成功!') newapptk=re.findall(r'"newapptk":"(.*?)"',data)[0] check_token='https://kyfw.12306.cn/otn/uamauthclient' response=session.post(check_token,data={'tk':newapptk}) username=re.findall(r'"username":"(.*?)"',response.text)[0] print('{},欢迎登录12306'.format(username)) except: print('对不起,您没有选择正确的序号,请重新选择!') self.login() MY_Login=ChineseRoad_login('**********','**********')#此处传入自己的用户名和密码 MY_Login.login()



运行代码,一次的流程:

(1)文件夹中的显示

怎么登录 MariaDB_怎么登录 MariaDB_04

怎么登录 MariaDB_javascript_05

(2)屏幕显示

怎么登录 MariaDB_怎么登录 MariaDB_06

对比:面向过程很简单,就是流水账,按照步骤来;

         但是一般都要求代码写成面向对象的格式(简单理解就是class类,这样理解有误,我会在python的基础学习中讲解面向对象的知识点)

PS:这里贴一个网站:https://leetcode-cn.com/problemset/database/    这是LeetCode的中文版,这里面的就要求你的代码是写成面向对象的格式

传闻bat的面试会在这里选题目,不知道真假....无聊的时候大家可以用它练练手啊~我可能也会分享我在上面的代码~~~

今日爬虫完成!

今日鸡汤:只要你有能力去做的事就一定要去做,不要给自己留下任何遗憾,人生最重要的不是所站的位置,而是所朝的方向。

加油ヾ(◍°∇°◍)ノ゙