验证码的全称为 全自动区分计算机和人类的公开图灵测试。可以看出,验证码用于测试用户是否为真实人类。一个典型的验证码由扭曲的文本组成,此时计算机难以解析,但人类仍然可以(希望如此)阅读。
如下表单中的最后一项 recaptcha_response_field 就是验证码信息
import cookielib,urllib2,pprint
REGISTER_URL = "http://example.webscraping.com/user/register" # 需要验证码的 url 地址
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
html = opener.open(REGISTER_URL).read()
form = parse_form(html) # 这个函数是上一节定义的
pprint.pprint(form)
"""
输出
{'_formkey':'led4e4c4-fbc6-4d82-a0d3-771d289f8661',
'_formname':'register',
'_next':'/',
'first_name':'',
'last_name':'',
'password':'',
'password_two':None,
'recaptcha_response_field':None}
"""
图1 :验证码表单图
加载验证码图像如下: pip install pillow
from io import BytesIO
import lxml.html
from PIL import Image
def get_captcha(html):
tree = lxml.html.fromstring(html)
img_data = tree.cssselect("div#recaptcha img")[0].get("src")
img_data = img_data.partition(",")[-1]
binary_img_data = img_data.decode("base64") # 转换成二进制图形
file_like = BytesIO(binary_img_data)
img = Image.open(file_like)
return img
以上代码是获取验证码的图像信息,然后用光学字符识别解析验证图形的内容
安装: pip install pytesseract
内部调用的其实是 tesseract,linux 安装参考: https://blog.csdn.net/zhangping1987/article/details/51151050
直接解析效果很差
import pytesseract
img = get_captcha(html) # html 是前面下载下来的: html = opener.open(REGISTER_URL).read()
print pytesseract.image_to_string(img) # 输出 ''
定义 ocr 函数进行一些处理后,再解析效果就好很多
def ocr(img):
gray = img.convert("L") # 黑白
# img.save("xxx.png") 可以把图片保存下来
bw = gray.point(lambda x: 0 if x < 1 else 255,'1') # 只有全黑的保留下来,其他的设置称白色
# bw.save("xxx.png") 可以保存下来看看
return bw
import pytesseract
img = get_captcha(html) # 获取验证码图形
img = ocr(img) # 图形处理
print pytesseract.image_to_string(img) # 成功输出 "strange"
接下来就可以使用解析的验证码进行上一节的表单提交处理。有时候针对很复杂的验证码,有专门的验证码处理服务 API 可以调用,比如 9kw 等。。。