Python实现破解12306图片验证码的方法分析


Posted in Python onDecember 29, 2017

本文实例讲述了Python实现破解12306图片验证码的方法。分享给大家供大家参考,具体如下:

不知从何时起,12306的登录验证码竟然变成了按字找图,可以说是又提高了一个等次,竟然把图像识别都用上了。不过有些图片,不得不说有些变态,图片的清晰图就更别说了,明显是从网络上的图库中搬过来的。

Python实现破解12306图片验证码的方法分析

谁知没多久,网络就惊现破解12306图片验证码的Python代码了,作为一个爱玩爱刺激的网虫,当然要分享一份过来。

代码大致流程:

1、将验证码图片下载下来,然后切图;
2、利用百度识图进行图片分析;
3、再利用正则表达式来取出百度识图的关键字,最后输出。

代码:

#!/usr/bin/python
# # FileName  : fuck12306.py
# # Author   : MaoMao Wang <andelf@gmail.com>
# # Created   : Mon Mar 16 22:08:41 2015 by ShuYu Wang
# # Copyright  : Feather (c) 2015
# # Description : fuck fuck 12306
# # Time-stamp: <2015-03-17 10:57:44 andelf>
from PIL import Image
from PIL import ImageFilter
import urllib
import urllib2
import re
import json
# hack CERTIFICATE_VERIFY_FAILED
# https://github.com/mtschirs/quizduellapi/issues/2
import ssl
if hasattr(ssl, '_create_unverified_context'):
  ssl._create_default_https_context = ssl._create_unverified_context
UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
pic_url = "https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.21191171556711197"
def get_img():
  resp = urllib.urlopen(pic_url)
  raw = resp.read()
  with open("./tmp.jpg", 'wb') as fp:
    fp.write(raw)
  return Image.open("./tmp.jpg")
def get_sub_img(im, x, y):
  assert 0 <= x <= 3
  assert 0 <= y <= 2
  WITH = HEIGHT = 68
  left = 5 + (67 + 5) * x
  top = 41 + (67 + 5) * y
  right = left + 67
  bottom = top + 67
  return im.crop((left, top, right, bottom))
def baidu_stu_lookup(im):
  url = "http://stu.baidu.com/n/image?fr=html5&needRawImageUrl=true&id=WU_FILE_0&name=233.png&type=image%2Fpng&lastModifiedDate=Mon+Mar+16+2015+20%3A49%3A11+GMT%2B0800+(CST)&size="
  im.save("./query_temp_img.png")
  raw = open("./query_temp_img.png", 'rb').read()
  url = url + str(len(raw))
  req = urllib2.Request(url, raw, {'Content-Type':'image/png', 'User-Agent':UA})
  resp = urllib2.urlopen(req)
  resp_url = resp.read()   # return a pure url
  url = "http://stu.baidu.com/n/searchpc?queryImageUrl=" + urllib.quote(resp_url)
  req = urllib2.Request(url, headers={'User-Agent':UA})
  resp = urllib2.urlopen(req)
  html = resp.read()
  return baidu_stu_html_extract(html)
def baidu_stu_html_extract(html):
  #pattern = re.compile(r'<script type="text/javascript">(.*?)</script>', re.DOTALL | re.MULTILINE)
  pattern = re.compile(r"keywords:'(.*?)'")
  matches = pattern.findall(html)
  if not matches:
    return '[UNKNOWN]'
  json_str = matches[0]
  json_str = json_str.replace('\\x22', '"').replace('\\\\', '\\')
  #print json_str
  result = [item['keyword'] for item in json.loads(json_str)]
  return '|'.join(result) if result else '[UNKNOWN]'
def ocr_question_extract(im):
  # git@github.com:madmaze/pytesseract.git
  global pytesseract
  try:
    import pytesseract
  except:
    print "[ERROR] pytesseract not installed"
    return
  im = im.crop((127, 3, 260, 22))
  im = pre_ocr_processing(im)
  # im.show()
  return pytesseract.image_to_string(im, lang='chi_sim').strip()
def pre_ocr_processing(im):
  im = im.convert("RGB")
  width, height = im.size
  white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(23))
  grey = im.convert('L')
  impix = im.load()
  whitepix = white.load()
  greypix = grey.load()
  for y in range(height):
    for x in range(width):
      greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0],
                    255 + impix[x,y][1] - whitepix[x,y][1],
                    255 + impix[x,y][2] - whitepix[x,y][2]))
  new_im = grey.copy()
  binarize(new_im, 150)
  return new_im
def binarize(im, thresh=120):
  assert 0 < thresh < 255
  assert im.mode == 'L'
  w, h = im.size
  for y in xrange(0, h):
    for x in xrange(0, w):
      if im.getpixel((x,y)) < thresh:
        im.putpixel((x,y), 0)
      else:
        im.putpixel((x,y), 255)
if __name__ == '__main__':
  im = get_img()
  #im = Image.open("./tmp.jpg")
  print 'OCR Question:', ocr_question_extract(im)
  for y in range(2):
    for x in range(4):
      im2 = get_sub_img(im, x, y)
      result = baidu_stu_lookup(im2)
      print (y,x), result
Python 相关文章推荐
python del()函数用法
Mar 24 Python
Python实现遍历数据库并获取key的值
May 17 Python
Python批量转换文件编码格式
May 17 Python
python安装教程 Pycharm安装详细教程
May 02 Python
python学生管理系统
Jan 30 Python
python内置函数sorted()用法深入分析
Oct 08 Python
Python操作Sonqube API获取检测结果并打印过程解析
Nov 27 Python
python base64库给用户名或密码加密的流程
Jan 02 Python
python生成大写32位uuid代码
Mar 03 Python
Python中的__init__作用是什么
Jun 09 Python
Python Socket编程详解
Apr 25 Python
只用20行Python代码实现屏幕录制功能
Jun 02 Python
解决python使用open打开文件中文乱码的问题
Dec 29 #Python
python爬虫获取京东手机图片的图文教程
Dec 29 #Python
python通过getopt模块如何获取执行的命令参数详解
Dec 29 #Python
基于并发服务器几种实现方法(总结)
Dec 29 #Python
Python matplotlib画图实例之绘制拥有彩条的图表
Dec 28 #Python
python操作列表的函数使用代码详解
Dec 28 #Python
Python读csv文件去掉一列后再写入新的文件实例
Dec 28 #Python
You might like
提升PHP速度全攻略
2006/10/09 PHP
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
2014/06/04 PHP
PHP输入输出流学习笔记
2015/05/12 PHP
PHP实现类似题库抽题效果
2018/08/16 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
2019/10/30 PHP
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
JS代码放在head和body中的区别分析
2011/12/01 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
2012/06/20 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
javascript内置对象操作详解
2015/02/04 Javascript
基于javascript显示当前时间以及倒计时功能
2016/03/18 Javascript
第一次接触神奇的Bootstrap菜单和导航
2016/08/01 Javascript
本地Bootstrap文件字体图标引入却无法显示问题的解决方法
2020/04/18 Javascript
Node.js利用断言模块assert进行单元测试的方法
2017/09/28 Javascript
详解javascript 正则表达式之分组与前瞻匹配
2018/05/30 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
element ui分页多选,翻页记忆的实例
2019/09/03 Javascript
python创建一个最简单http webserver服务器的方法
2015/05/08 Python
用Python写冒泡排序代码
2016/04/12 Python
Python设计模式之中介模式简单示例
2018/01/09 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
2019/04/17 Python
python3.5 cv2 获取视频特定帧生成jpg图片
2019/08/28 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
使用Pytorch来拟合函数方式
2020/01/14 Python
Python如何将模块打包并发布
2020/08/30 Python
python中lower函数实现方法及用法讲解
2020/12/23 Python
python 实现的车牌识别项目
2021/01/25 Python
可能这些是你想要的H5软键盘兼容方案(小结)
2019/04/23 HTML / CSS
为什么UNION ALL比UNION快
2016/03/17 面试题
杠杆的科学教学反思
2014/01/10 职场文书
工程师岗位职责规定
2014/02/26 职场文书
工人先进事迹材料
2014/12/26 职场文书
计生个人工作总结
2015/02/28 职场文书
2015年宣传工作总结
2015/04/08 职场文书
2015秋季开学典礼主持词
2015/07/16 职场文书
Vue3中toRef与toRefs的区别
2022/03/24 Vue.js