import logging
import re
from time import sleep
import requests
from PIL import Image
from fake_useragent import UserAgent
from pytesseract import image_to_string
class RecognizeCode(object):
"""使用tesseract识别图片的验证码"""
@staticmethod
def filter_color(img_path):
"""对图片颜色进行处理"""
img = Image.open(img_path)
img = img.convert('L') # 转化为黑白图片
img = img.point(lambda x: 0 if x < 140 else 255) # 二值化处理,小于某个值的为黑色,否则为白色
img.save(img_path) # 保存并覆盖原文件
def to_text(self, img_path):
"""识别图片中的验证码"""
self.filter_color(img_path) # 图片颜色过滤
code = image_to_string(Image.open(img_path), lang='enm') # 识别验证码并返回字符串
if code: # 识别成功返回验证码字符串
return code.strip().lower() # 去除换行符并转化成小写
class GuShi(object):
"""使用账号、密码、验证码登录古诗文网,并验证是否登录成功
注意:由于tesseract识别精度有限,验证码错误会导致登录失败,因此需要使用循环进行不断识别验证登录,直到登录成功
"""
user = '' # 账号
password = '' # 密码
def __init__(self):
self.s = requests.Session() # 实例化session对象,用于保持会话
self.headers = {'User-Agent': UserAgent().random} # 随机请求头
def get_code(self):
"""识别图片中的验证码并返回"""
url = 'https://so.gushiwen.cn/RandCode.ashx' # 验证码图片地址
while True:
# 对图片地址发送网络请求
r = self.s.get(url, headers=self.headers).content
# 把图片保存到本地,注意图片格式,png格式进行图片二值化处理有问题
with open('code.gif', 'wb') as f:
f.write(r)
# 使用识别图片验证码的类获取验证码字符串并返回,识别失败会返回None
code = RecognizeCode().to_text('code.gif')
print('识别的验证码为:', code)
# 如果返回的是字符串,终止循环并返回结果;否则继续循环,直到返回字符串结果
if code:
return code # 字符串中有换行符,去除换行符
sleep(1) # 设置休眠时间,降低请求频率
def get_viewstate(self):
"""获取表单数据中所需要的两个值并返回"""
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
r = self.s.get(url, headers=self.headers).text
viewstate1 = re.findall(r'id="__VIEWSTATE" value="(.*?)" />', r)[0]
viewstate2 = re.findall(r'id="__VIEWSTATEGENERATOR" value="(.*?)" />', r)[0]
return viewstate1, viewstate2
def login(self, viewstate1, viewstate2, code):
"""使用post请求进行登录"""
url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
# 构建表单数据
data = {
'__VIEWSTATE': viewstate1,
'__VIEWSTATEGENERATOR': viewstate2,
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': self.user, # 用户账号
'pwd': self.password, # 密码
'code': code, # 验证码
'denglu': '登录'
}
self.s.post(url, data=data, headers=self.headers) # post请求
def get_data(self):
"""验证登录是否成功,成功并返回True;否则返回False"""
url = 'https://so.gushiwen.cn/user/collect.aspx'
r = self.s.get(url, headers=self.headers).text
if '我的收藏' in r:
print('登录成功')
return True
logging.warning('登录失败')
return False
def run(self):
"""执行方法"""
# 1.获取构建表单的两个值
viewstate1, viewstate2 = self.get_viewstate()
while True:
# 2.获取验证码
code = self.get_code()
# 3.post请求进行登录
self.login(viewstate1, viewstate2, code)
# 4.验证登录是否成功,成功即退出循环,否则继续循环
if self.get_data():
break
if __name__ == '__main__':
GuShi().run()
tesseract识别验证码并使用账号密码登录古诗文网
最新推荐文章于 2023-09-09 20:42:40 发布