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


(2)屏幕显示

二、优化一下---->【面向对象】
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)文件夹中的显示


(2)屏幕显示

对比:面向过程很简单,就是流水账,按照步骤来;
但是一般都要求代码写成面向对象的格式(简单理解就是class类,这样理解有误,我会在python的基础学习中讲解面向对象的知识点)
PS:这里贴一个网站:https://leetcode-cn.com/problemset/database/ 这是LeetCode的中文版,这里面的就要求你的代码是写成面向对象的格式
传闻bat的面试会在这里选题目,不知道真假....无聊的时候大家可以用它练练手啊~我可能也会分享我在上面的代码~~~
今日爬虫完成!
今日鸡汤:只要你有能力去做的事就一定要去做,不要给自己留下任何遗憾,人生最重要的不是所站的位置,而是所朝的方向。
加油ヾ(◍°∇°◍)ノ゙
593

被折叠的 条评论
为什么被折叠?



