4-12306网站的登录实现【面向过程+面向对象】

目的:登录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)文件夹中,下载的验证图片

ec7f0875e3e097f37cef7b51baf3fc6ddb1.jpg

ceed3e33a5eab8bbbd7e9aa9130e042a3a9.jpg

(2)屏幕显示

c1c217acb8fc47dda57cc02f5c90852a10e.jpg

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

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)文件夹中的显示

48e2065d6f7aeea7f00ce694d7c2b519801.jpg

d62ce121b6c4ce5c67b488da53642002867.jpg

(2)屏幕显示

d614716b045d55141df75dfe7d6a6190f6e.jpg

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

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

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

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

今日爬虫完成!

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

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

转载于:https://my.oschina.net/pansy0425/blog/2988355

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值