Python Web Scraping - Processando CAPTCHA
Neste capítulo, vamos entender como realizar web scraping e processar CAPTCHA que é usado para testar um usuário humano ou robô.
O que é CAPTCHA?
A forma completa de CAPTCHA é Completely Automated Public Turing test to tell Computers and Humans Apart, o que sugere claramente que é um teste para determinar se o usuário é humano ou não.
Um CAPTCHA é uma imagem distorcida que geralmente não é fácil de detectar por um programa de computador, mas um humano pode de alguma forma conseguir entendê-la. A maioria dos sites usa CAPTCHA para evitar que os bots interajam.
Carregando CAPTCHA com Python
Suponha que queremos fazer o registro em um site e existe um formulário com CAPTCHA, então antes de carregar a imagem CAPTCHA precisamos saber sobre as informações específicas exigidas pelo formulário. Com a ajuda do próximo script Python, podemos entender os requisitos do formulário de registro no site denominadohttp://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://example.webscraping.com/user/register'</a>
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</a> = /places/default/index'
).read()
form = form_parsing(html)
pprint.pprint(form)
No script Python acima, primeiro definimos uma função que analisará o formulário usando o módulo lxml python e, em seguida, imprimirá os requisitos do formulário da seguinte maneira -
{
'_formkey': '5e306d73-5774-4146-a94e-3541f22c95ab',
'_formname': 'register',
'_next': '/places/default/index',
'email': '',
'first_name': '',
'last_name': '',
'password': '',
'password_two': '',
'recaptcha_response_field': None
}
Você pode verificar a partir da saída acima que todas as informações, exceto recpatcha_response_fieldsão compreensíveis e diretos. Agora surge a questão de como podemos lidar com essas informações complexas e fazer o download do CAPTCHA. Isso pode ser feito com a ajuda da biblioteca Pillow Python da seguinte maneira;
Pacote Pillow Python
Pillow é um fork da biblioteca de imagens Python com funções úteis para manipular imagens. Ele pode ser instalado com a ajuda do seguinte comando -
pip install pillow
No próximo exemplo, vamos usá-lo para carregar o 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
O script python acima está usando pillowpacote python e definindo uma função para carregar a imagem CAPTCHA. Deve ser usado com a função chamadaform_parser()que é definido no script anterior para obter informações sobre o formulário de inscrição. Este script salvará a imagem CAPTCHA em um formato útil que pode ser extraído como string.
OCR: extração de texto de imagem usando Python
Depois de carregar o CAPTCHA em um formato útil, podemos extraí-lo com a ajuda do Optical Character Recognition (OCR), um processo de extração de texto das imagens. Para este propósito, vamos usar o mecanismo de OCR Tesseract de código aberto. Ele pode ser instalado com a ajuda do seguinte comando -
pip install pytesseract
Exemplo
Aqui vamos estender o script Python acima, que carregou o CAPTCHA usando o pacote Pillow Python, como segue -
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')
O script Python acima irá ler o CAPTCHA no modo preto e branco, que seria claro e fácil de passar para o tesseract da seguinte forma -
pytesseract.image_to_string(bw)
Depois de executar o script acima, obteremos o CAPTCHA do formulário de registro como saída.