python爬虫如何解决图片验证码


Posted in Python onFebruary 14, 2021

之前刚开始做爬虫的时候遇到过登录验证码问题,看过很多帖子都没有解决我的问题,发现大多数帖子都是治标不治本,于是想分享一下自己的解决方案。本次采用的网站是古诗文网,使用百度API,因为百度API免费!免费!免费!适合自己学习的时候使用。如果还没有使用过百度API识别验证码的朋友可以看一下我的这个帖子。
以下案例采用的时古诗文网:登录古诗文网,

1、selenium处理图片验证码

先定位到验证码图片,在获取验证码图片在页面中的位置,使用save_screenshot截取页面,再根据图片的位置去截取验证码,最后通过接口识别文字获取验证码,直接上代码:

element = driver.find_element_by_id('imgCode') # 定位验证码图片
# 获取验证码图片在网页中的位置
left = int(element.location['x'])  # 获取图片左上角坐标x
top = int(element.location['y'])  # 获取图片左上角y
right = int(element.location['x'] + element.size['width'])    # 获取图片右下角x
bottom = int(element.location['y'] + element.size['height'])  # 获取图片右下角y

# 通过Image处理图像
path = current_dir + str(random.random()) + '.png'  # 生成随机文件名
driver.save_screenshot(path)    # 截取当前窗口并保存图片
im = Image.open(path)        # 打开图片
im = im.crop((left, top, right, bottom))  # 截图验证码
im.save(path)    # 保存验证码图片

# 使用百度API识别验证码
def get_code():
  client = AipOcr(APP_ID, API_KEY, SECRET_KEY)  # 百度API文档中提供的方法识别文字

  # 由于我处理的验证码图片没有填多的线条,所以直接采用灰度是验证码数字更加清晰,具体的处理方式可根据验证码的实际情况而定
  im = Image.open(path)
  # 转换为灰度图像
  im = im.convert('L')
  im.save(path)

  # 读取图片,应为百度API中提供的方法参数只能是字节流
  with open(path, 'rb')as f:
    image = f.read()
  # 使用API中提供的方法识别验证码并返回验证码
  code = client.basicGeneral(image)

  print(code['words_result'][0]['words']) # {'words_result': [{'words': '4TBiD ', 'location': {'top': 1, 'left': 6, 'width': 43, 'height': 13}}], 'log_id': 1358288307112378368, 'words_result_num': 1}
  return code['words_result'][0]['words']

2、使用requests请求验证码

这里用到了会话机制,对于初学者来说可能不太了解,简单说一下会话机制的作用,会话就是用来保存你之前请求的cookie,让浏览器知道你之前就在这里,这样浏览器就不会认为你重新来到这里,从而刷新验证码,这样就可以带着我们获取的验证码去登录了。

conn = requests.Sessoin(  # 创建会话
resp = conn.get('https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx')
selector = Selector(text=resp.text)
img_url = 'https://so.gushiwen.cn/'+selector.xpath('.//img[@id="imgCode"]/@src').get() # 获取图片的路由
img = conn.get(img_url)  # 保持会话请求
filename = str(random.random()) + '.png'
with open(filename, 'wb')as f:
  f.write(img.content)
# 为了后面的调用接口识别不报图片格式错误,进行一次图片转换
im = Image.open(filename)
im.save(filename)
# 使用二进制方式读取图片
with open(filename, 'rb')as f:
image = f.read()
data = client.handwriting(image)  # diao'yong
# 使用API中提供的方法识别验证码并返回验证码
code = client.basicGeneral(image)
code = code['words_result'][0]['words']

selenium源码

# -* coding: utf-8 *-

import time
import random
from PIL import Image
from aip import AipOcr
from selenium.webdriver import Chrome

# 百度API参数
APP_ID = '23647800'
API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN'
SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 调用API接口


def scrapy(username, password):
  """
  :param username:  用户名
  :param password:  密码
  """
  driver = Chrome()
  driver.get('https://so.gushiwen.cn/user/login.aspx')
  driver.find_element_by_id('email').send_keys(username) # 输入账号
  driver.find_element_by_id('pwd').send_keys(password)  # 输入密码

  element = driver.find_element_by_id('imgCode') # 定位验证码图片
  # 获取验证码图片在网页中的位置
  left = int(element.location['x']) # 获取图片左上角坐标x
  top = int(element.location['y']) # 获取图片左上角y
  right = int(element.location['x'] + element.size['width']) # 获取图片右下角x
  bottom = int(element.location['y'] + element.size['height']) # 获取图片右下角y

  # 通过Image处理图像
  filename = str(random.random()) + '.png' # 生成随机文件名
  driver.save_screenshot(filename) # 截取当前窗口并保存图片
  im = Image.open(filename) # 打开图片
  im = im.crop((left, top, right, bottom)) # 截图验证码
  im.save(filename) # 保存验证码图片
  # 由于我处理的验证码图片没有填多的线条,所以直接采用灰度是验证码数字更加清晰,具体的处理方式可根据验证码的实际情况而定
  im = Image.open(filename)
  # 转换为灰度图像
  im = im.convert('L')
  im.save(filename)
  # 读取图片,应为百度API中提供的方法参数只能是字节流
  with open(filename, 'rb')as f:
    image = f.read()
  # 使用API中提供的方法识别验证码并返回验证码
  data = client.basicGeneral(image)
  try:
    code = data['words_result'][0]['words']
  except:
    return data['error_msg']

  driver.find_element_by_id('code').send_keys(code)  # 输入验证码
  driver.find_element_by_id('denglu').click()   # 点击登录
  time.sleep(1000)  # 为了看清登录,等待1000秒


if __name__ == '__main__':
  print(scrapy(username, password)) # 传入你在古诗文网注册的账号密码

requests源码

# -* coding: utf-8 *-
import os
import random
import re
import requests
from PIL import Image
from aip import AipOcr
from scrapy import Selector

headers = {
  'referer': 'https://so.gushiwen.cn/user/login.aspx',
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}

# 百度API参数
APP_ID = '23647800'
API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN'
SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK'

def scrapy(username, password):
  """
  :param username:  用户名
  :param password:  密码
  """
  client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 调用API接口
  conn = requests.Session() # 创建会话
  resp = conn.get('https://so.gushiwen.cn/user/login.aspx', headers=headers) # 获取登录页面
  selector = Selector(text=resp.text)
  __VIEWSTATE = selector.xpath('.//input[@id="__VIEWSTATE"]/@value').get()
  __VIEWSTATEGENERATOR = selector.xpath('.//input[@id="__VIEWSTATEGENERATOR"]/@value').get()
  img_url = 'https://so.gushiwen.cn/' + selector.xpath('.//img[@id="imgCode"]/@src').get() # 获取图片的路由
  img = conn.get(img_url, headers=headers) # 获取图片路由
  # 保存图片
  filename = str(random.random()) + '.png' # 随机生成文件名, 图片格式不能为jpg,API不支持jpg格式的识别
  with open(filename, 'wb')as f:
    f.write(img.content)
   # 由于我处理的验证码图片没有填多的线条,所以直接采用灰度是验证码数字更加清晰,具体的处理方式可根据验证码的实际情况而定
  im = Image.open(filename)
  # 转换为灰度图像
  im = im.convert('L')
  im.save(filename)
  # 使用二进制方式读取图片
  with open(filename, 'rb')as f:
    image = f.read()
  # # 标准识别, 每天免费50000次
  # data = client.basicGeneral(image)
  # 精确识别,每天免费500次
  data = client.handwriting(image)
  # 捕获一下接口识别当中的错误,可参照文档查看报错原因
  try:
    code = data['words_result'][0]['words']
  except:
    return data['error_msg']
  form_data = {
    '__VIEWSTATE': __VIEWSTATE,
    '__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR,
    'from': '',
    'email': username,
    'pwd': password,
    'code':cod,
    'denglu': '登录'
  }
  # 登录
  html = conn.post('https://so.gushiwen.cn/user/login.aspx', headers=headers, data=form_data).text
  # 获取登录标志位
  login_flag = re.findall("alert\('(.*?)'\);",html)[0] if re.findall("alert\('(.*?)'\);",html) else ''
  if not login_flag:
    return '登录成功!'
  elif '验证码有误!' in login_flag:
    return "验证码错误"


if __name__ == '__main__':
  print(scrapy(username, password))

以上就是python爬虫如何解决图片验证码的详细内容,更多关于python 解决图片验证码的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python fileinput模块使用实例
Jun 03 Python
Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
Mar 19 Python
Python使用add_subplot与subplot画子图操作示例
Jun 01 Python
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
Jul 27 Python
解决Python print输出不换行没空格的问题
Nov 14 Python
Python中psutil的介绍与用法
May 02 Python
python3 webp转gif格式的实现示例
Dec 10 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
Jan 10 Python
Python实现随机生成任意数量车牌号
Jan 21 Python
python plt可视化——打印特殊符号和制作图例代码
Apr 17 Python
Python yield生成器和return对比代码实例
Apr 20 Python
python内置模块之上下文管理contextlib
Jun 14 Python
Python实现粒子群算法的示例
Feb 14 #Python
Python中对象的比较操作==和is区别详析
Feb 12 #Python
python绘图模块之利用turtle画图
Feb 12 #Python
Python列表的深复制和浅复制示例详解
Feb 12 #Python
Python就将所有的英文单词首字母变成大写
Feb 12 #Python
详解Java中一维、二维数组在内存中的结构
Feb 11 #Python
SpringBoot首页设置解析(推荐)
Feb 11 #Python
You might like
解析file_get_contents模仿浏览器头(user_agent)获取数据
2013/06/27 PHP
php实现的ping端口函数实例
2014/11/12 PHP
JavaScript进阶教程(第四课第一部分)
2007/04/05 Javascript
基于Jquery的标签智能验证实现代码
2010/12/27 Javascript
6款新颖的jQuery和CSS3进度条插件推荐
2013/03/05 Javascript
基于JavaScript实现Json数据根据某个字段进行排序
2015/11/24 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
2016/01/22 Javascript
js实现无缝循环滚动
2020/06/23 Javascript
jquery自定义表单验证插件
2016/10/12 Javascript
Angular整合zTree的示例代码
2018/01/24 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
解决Nodejs全局安装模块后找不到命令的问题
2018/05/15 NodeJs
关于jquery中attr()和prop()方法的区别
2018/05/28 jQuery
vue-router传递参数的几种方式实例详解
2018/11/13 Javascript
详解vue数组遍历方法forEach和map的原理解析和实际应用
2018/11/15 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
Python中endswith()函数的基本使用
2015/04/07 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例
2018/08/04 Python
python多线程并发让两个LED同时亮的方法
2019/02/18 Python
selenium+python环境配置教程详解
2019/05/28 Python
python爬虫selenium和phantomJs使用方法解析
2019/08/08 Python
win10下安装Anaconda的教程(python环境+jupyter_notebook)
2019/10/23 Python
python实现逢七拍腿小游戏的思路详解
2020/05/26 Python
python能否java成为主流语言吗
2020/06/22 Python
如何在python中实现线性回归
2020/08/10 Python
使用HTML5 Canvas API绘制弧线的教程
2016/03/22 HTML / CSS
Happy Socks英国官网:购买五颜六色的袜子
2020/11/03 全球购物
经贸日语专业个人求职信
2013/12/13 职场文书
企业内控岗位的职责
2014/02/07 职场文书
护士岗位职责
2014/02/16 职场文书
运动会入场词50字
2014/02/20 职场文书
青年文明号口号
2014/06/17 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
php中配置文件保存修改操作 如config.php文件的读取修改等操作
2021/05/12 PHP
使用Oracle跟踪文件的问题详解
2021/06/28 Oracle