Why?

前段时间群里有人开发出了树洞外链的注册机,因为程序本身没有任何反机器人规则,所以几秒钟就能注册出几百个账号出来,很容易被别有用心的人被用来搞破坏,当时想采用Google的黑科技验证码,但几天后。。。

psb
psb

演示站所使用的七牛空间被恶意刷流量,我不得不限制演示站用户数量,并且过滤一下低素质用户,于是就出现了题图中的验证码,正确输入验证码起码要有一些高中的化学知识(但文科森好像要哭了)。截止至目前,日平均注册人数从15减至0,5天内只有一人成功注册,效果不错(doge)。

数据采集

实现这个验证码首先要有大量的化学物质数据,包括分子式和结构图,我用Python采集了国内一个CAS查询网站的数据。CAS号是美国化学会的下设组织化学文摘社(ChemicalAbstractsService,简称CAS)。该社负责为每一种出现在自然世界中的物质分配一个CAS编号,也就是说这个数据库内收录了自然界内已知的所有物质!做验证码不需要采集这么多,我只采集了10000多个,已经足够用了。

Python采集脚本源代码(采集后存入MySQL):

# -*- coding: UTF-8 -*-
from bs4 import BeautifulSoup
import requests
import sys
import MySQLdb
import types
reload(sys)
sys.setdefaultencoding('utf-8')
db = MySQLdb.connect("localhost","root","root","23" )
for i in range(200):
    i = (i+1)*100
    print "START "+str(i)
    url = "http://www.chemicalbook.com/CASDetailList_"+str(i)+".htm"
    r= requests.get(url)
    soup = BeautifulSoup(r.text)
    L=[]
    R=[]
    for c in soup.find_all(id='ContentPlaceHolder1_ProductClassDetail')[0].children:
        soup1 = BeautifulSoup(str(c))
        if(type(soup1.span ) is not types.NoneType):
            R.append(soup1.span .string)
        if(type(soup1.a ) is not types.NoneType):
            L.append(soup1.a .string)
    for m in range(len(L)):
        cas =  L[m]
        anwser = R[m]
        cursor = db.cursor()
        sql = "INSERT INTO `sd_vcode` (`id`, `cas`, `anwser`) VALUES (NULL, '"+cas+"', '"+anwser+"');"
        cursor.execute(sql)
        db.commit()
    L=[]
    R=[]

这个脚本只会采集物质的CAS编码和分子式,结构图片没有采集,因为结构图片可以直接通过http://www.chemicalbook.com/CAS/GIF/CAS编码.gif调用。
接下来的事情就很简单了,php随机取出一组引入结构图像。效果:

qq%e6%88%aa%e5%9b%be20160918124358
qq%e6%88%aa%e5%9b%be20160918124358

在线体验:https://file.aoaoao.me/views/login.php (点击”我要注册”)