验证码识别
概念
一种反爬机制。需要识别图片中的数据,用于模拟登录操作。
识别验证码图片的操作:
1、人工肉眼识别,不推荐
2、第三方自动识别
① 云打码 ()
流程:
1、将验证码图片进行本地下载
2、调用平台提供的示例代码进行图片数据识别
模拟登录
爬取基于某些用户的数据。
需求:对人人网进行模拟登录。
进行登录操作,经分析发现:
1、点击登录按钮会发起一个post请求
2、post请求中会携带登录之前录入的参数(用户名、密码、验证码等)
3、验证码每次请求都会动态变化
步骤分析:
1、爬取登录页面,获取验证码图片信息,保存到本地
2、通过第三方平台识别验证码信息
3、获取登录url,对此url发起post请求,封装所需参数
4、打印请求码,看是否成功
进一步的需求:爬取当前用户的个人主页对应的页面数据
步骤:对个人主页的url发起请求,进行数据解析。
请求后发现,页面跳转到登录页面,并未请求到个人主页页面数据。
原因:http/https协议的特性之一就是无状态,服务器不会保留用户状态。何为无状态?就是一旦浏览器和服务器之间的请求和响应完毕后,两者会立马断开连接,也就是恢复成无状态。这样会导致:服务器永远无法辨认,也记不住用户的信息,像一条只有7秒记忆的金鱼。是cookie和session的出现,才破除了web发展史上的这个难题。cookie不仅仅能实现自动登录,因为它本身携带了session的编码信息,网站还能根据cookie,记录你的浏览足迹,从而知道你的偏好,只要再加以推荐算法,就可以实现给你推送定制化的内容。在发起第二次基于个人主页页面的请求的时候,服务器端并不知道此请求时基于登录状态下的请求。
cookies
用抓包工具对个人主页url进行分析,发现request headers中带有cookies参数。
概念
用来让服务器端记录客户端的相关状态。
处理方法
1、手动处理:通过抓包工具获取cookies值,将改值封装到headers中,不推荐。
2、自动处理
1)cookie值得来源在哪里?
- 模拟登录post请求后,由服务器端创建。
- 在response headers里有set cookie的参数,就是服务器往浏览器写入了cookie。
2)用法
cookie在我们日常访问网站的过程中随处可见。例如当我们需要经常登录一个网站,但是又不想每次都输入账号密码时,我们可以勾选一个“记住我”的选项。勾选之后,当我们再打开这个网站就会自动登录,这就是cookie在起作用。
当你登录并勾选“记住我的登录信息”,服务器就会生成一个cookie和这个账号绑定。接着,它把这个cookie告诉你的浏览器,让浏览器把cookie存储到你的本地电脑。当下一次,浏览器带着cookie访问博客,服务器会知道你是此账户,你不需要再重复输入账号密码,即可直接访问。
当然,cookie也是有时效性的,过期后就会失效。你应该有过这样的体验:哪怕勾选了“记住我”,但一段时间过去了,网站还是会提示你要重新登录,就是之前的cookie已经失效。
3) 代码示例
session会话
1、session会话对象
- 作用:
① 可以进行请求的发送;
②如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中。
- 创建session对象:session = requests.Session()
- 使用seesion对象进行模拟登录post请求的发送(cookie会被存储在session中)
- 再利用session对象对个人主页对应的url发送get请求(已携带cookie)
2、代码示例
cookies的存储与读取
避免每次都要输账号密码,需要存储存读取cookie
存储
登录的cookie类型是RequestCookieJar,要将cookie存储为文件,需要以下转换过程:
cookies --> 字典 --> json
读取
存储cookie时,是把它先转成字典,再转成字符串。读取cookie则刚好相反,要先把字符串转成字典,再把字典转成cookie本来的格式。
代码示例
import requests
import json
session = requests.session()
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
# cookie读取
def cookie_read():
cookie_txt = open('cookie_kaikeba.txt', 'r')
cookie_dict = json.loads(cookie_txt.read())
cookie = requests.utils.cookiejar_from_dict(cookie_dict)
return (cookie)
# 登录网站并保存cookies函数
def sign_in():
url_login = 'https://xiaoke.kaikeba.com/example/wordpress/wp-login.php'
data_login = {'log': input('请输入你的账号'),
'pwd': input('请输入你的密码'),
'wp-submit': '登录',
'redirect_to': 'https://xiaoke.kaikeba.com/example/wordpress/2019/10/17/%e5%bc%80%e8%af%be%e5%90%a7%e6%97%a0%e6%95%8c%e5%a5%bd%e5%90%83%e7%9a%84%e9%a3%9f%e5%a0%82%e4%b8%80%e5%91%a8%e8%8f%9c%e8%b0%b1/',
'testcookie': '1'}
session.post(url_login, headers=headers, data=data_login)
# cookie存储。
cookie_dict = requests.utils.dict_from_cookiejar(session.cookies)
cookie_str = json.dumps(cookie_dict)
f = open('cookie_kaikeba.txt', 'w')
f.write(cookie_str)
f.close()
# 发表评论
def write_message():
url_comment = 'https://xiaoke.kaikeba.com/example/wordpress/wp-comments-post.php'
data_comment = {
'comment': input('请输入你要发表的评论:'),
'submit': '发表评论',
'comment_post_ID': '35',
'comment_parent': '0'
}
return (session.post(url_comment, headers=headers, data=data_comment))
try:
session.cookies = cookie_read()
except FileNotFoundError:
sign_in()
session.cookies = cookie_read()
# 判断cookies是否过期
num = write_message()
# 请求成功
if num.status_code == 200:
print('成功啦!')
# 请求不成功,cookies过期
else:
# 再次登录保存cookies
sign_in()
session.cookies = cookie_read()
num = write_message()