Python网页抓取处理验证码


在本章中,让我们了解如何执行网页抓取和处理用于测试用户的人或机器人的验证码。

什么是验证码?


验证码的完整形式是 完全自动化的公共图灵测试来区分计算机和人类 ,这清楚地表明这是一个判断用户是不是人的测试。

验证码是一种扭曲的图像,通常不容易被计算机程序检测到,但人类可以设法理解它。大多数网站使用验证码来防止机器人交互。

使用 Python 加载验证码


假设我们要在一个网站上进行注册,并且有带有 CAPTCHA 的表单,那么在加载 CAPTCHA 图像之前,我们需要了解表单所需的具体信息。借助下一个 Python 脚本,我们可以了解名为 http://example.webscrapping.com。

import lxml.html
import urllib.request as urllib2
import pprint
import http.cookiejar as cookielib
def form_parsing(html):
    tree = lxml.html.fromstring(html)
    data = {}
    for e in tree.cssselect('form input'):
        if e.get('name'):
            data[e.get('name')] = e.get('value')
    return data
REGISTER_URL = '<a target="_blank" rel="nofollow" 
    href="http:// example.webscraping.com/user/register">http:
ckj = cookielib.CookieJar()
browser = urllib2.build_opener(urllib2.HTTPCookieProcessor(ckj))
html = browser.open(
    '<a target="_blank" rel="nofollow"
        href="http:// example.webscraping.com/places/default/user/register?_next">
        http:// example.webscraping.com/places/default/user/register?_next = /places/default/index'
).read()
form = form_parsing(html)
pprint.pprint(form)

在上面的 Python 脚本中,首先我们定义了一个函数,使用 lxml python 模块解析表单,然后打印表单要求如下:

{
    '_formkey': '5e306d73-5774-4146-a94e-3541f22c95ab',
    '_formname': 'register',
    '_next': '/places/default/index',
    'email': '',
    'first_name': '',
    'last_name': '',
    'password': '',
    'password_two': '',
    'recaptcha_response_field': None
}

你可以从上面的输出中检查所有信息,除了 recpatcha_response_field 是可以理解和直接的。现在问题出现了,我们如何处理这些复杂的信息并下载 CAPTCHA。可以在枕头 Python 库的帮助下完成,如下所示;

枕头 Python 包


Pillow 是 Python 图像库的一个分支,具有用于处理图像的有用功能。可以通过以下命令安装:

pip install pillow

在下一个示例中,我们将使用它来加载 CAPTCHA:

from io import BytesIO
import lxml.html
from PIL import Image
def load_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

上面的python脚本正在使用 pillow python 包并定义了一个用于加载验证码图像的函数。它必须与名为的函数一起使用 form_parser() 这是在前面的脚本中定义的,用于获取有关注册表单的信息。此脚本将以有用的格式保存 CAPTCHA 图像,该格式可以进一步提取为字符串。

OCR:使用 Python 从图像中提取文本


在以有用的格式加载 CAPTCHA 后,我们可以借助光学字符识别 (OCR) 来提取它,这是一个从图像中提取文本的过程。为此,我们将使用开源 Tesseract OCR 引擎。可以通过以下命令安装:

pip install pytesseract

例子

这里我们将扩展上面的 Python 脚本,通过 Pillow Python Package 加载验证码,如下:

import pytesseract
img = get_captcha(html)
img.save('captcha_original.png')
gray = img.convert('L')
gray.save('captcha_gray.png')
bw = gray.point(lambda x: 0 if x < 1 else 255, '1')
bw.save('captcha_thresholded.png')

上面的 Python 脚本会以黑白模式读取 CAPTCHA,这样会很清晰,很容易传递给 tesseract,如下所示:

pytesseract.image_to_string(bw)

运行上述脚本后,我们将得到注册表单的验证码作为输出。