当我们登录12306时会发现,在登录界面选择账号登录时不仅需要输入正确的账号和密码,还需要选中正确的图片进行验证。其实这并不是针对反爬所做的处理,而是为了使同一时间登录的人尽可能的减少以减少服务器压力,类似与去银行办理业务时需要排队叫号一样。然而这个处理也给爬虫带来了不小的麻烦,当我们需要爬取一些网站的信息时却卡在图片验证这一步?别着急,下面以中国铁路12306为例教你用python做图片验证!
首先打开12306的登录界面,选择账户登录然后打开开发者工具,输入正确的账户名和错误的密码(不用登录进去),点击正确的验证图片,点击立即登录后观察Network中出现的请求:
找到上图所示的请求后点击 Headers。在Request URL中如图圈出的部分是我们需要的网址:
"?"连接的部分是一些参数,可以在Query String Parameters中找到。我们可以看到answer后面的参数就是一个(x,y)的坐标,也就是我们进行图片验证的坐标。
接下来点击第3个请求:
同样找到Headers中的Requests URL,图中框选的部分是我们需要的网址:
但是这里需要注意一个问题,我们将网址复制到网址栏中打开后发现并不是我们想要都图片,而是一大段看不懂的代码:
这里是因为对网址进行了base64处理,只需要将网址中image64中的64删除即可。再次输入网址后就得到我们想要的图片了:
完整代码如下:
import requests
req =requests.Session() #保持session会话
def login():
#请求图片的url
pic_response=req.get('https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand')
#在活动栏中得到图片
codeImage=pic_response.content
fn=open('code.png','wb')
fn.write(codeImage)
fn.close()
#加上请求头
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
#运行后输入坐标回车即可
codeStr=input('请输入验证码坐标:')
data={
'answer':codeStr,
'rand': 'sjrand' ,
'login_site': 'E'
}
#请求目标url
res=req.post('https://kyfw.12306.cn/passport/captcha/captcha-check',data=data,headers=headers)
print(res.text)
login()
注:验证图片的坐标可以通过截图功能实现,拉伸截图框左上角出现的数字即为验证图片的坐标