Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 27, 2017 18:21:05

alekssim
Зарегистрирован: 2017-12-27
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопрос по распознаванию капчи

Доброго вам времени суток. Столкнулся с необходимостью обойти капчу на сайте. Знаю, что есть вариант её просто отключить для определенного адреса, но суть задачи как раз именно в этом. Так вот, перерыл кучу страничек в поисках информации. Нашёл несколько интересных вариантов, но не совсем могу понять как они работают. Теперь немного подробностей:
Вот так выглядит сама капча (captcha.jpg во вложении) вариант с распознаванием картинки с помощью извлечения цвета, как я понимаю, не подходит, т.к. не получится выделить именно цвет символов. (или получится?), поэтому изучал дальше и нашёл еще один похожий вариант, но никак не могу разобраться в связи с небольшим багажом знаний языка Python.
Тем, кто задавался этим вопросом, думаю. будет знаком вот такой вот декодер:

from PIL import Image
import sys


def decoder(
im,
threshold=200,
mask=“letters.bmp”,
alphabet=“0123456789abcdef”):

img = Image.open(im)
img = img.convert(“RGB”)
box = (8, 8, 58, 18)
img = img.crop(box)
pixdata = img.load()

# open the mask
letters = Image.open(mask)
ledata = letters.load()

def test_letter(img, letter):
A = img.load()
B = letter.load()
mx = 1000000
max_x = 0
x = 0
for x in range(img.size - letter.size):
_sum = 0
for i in range(letter.size):
for j in range(letter.size):
_sum = _sum + abs(A - B)
if _sum < mx:
mx = _sum
max_x = x
return mx, max_x

# Clean the background noise, if color != white, then set to black.
for y in range(img.size):
for x in range(img.size):
if (pixdata > threshold) \
and (pixdata > threshold) \
and (pixdata > threshold):

pixdata = (255, 255, 255, 255)
else:
pixdata = (0, 0, 0, 255)

counter = 0
old_x = -1

letterlist =

for x in range(letters.size):
black = True
for y in range(letters.size):
if ledata != 0:
black = False
break
if black:
box = (old_x + 1, 0, x, 10)
letter = letters.crop(box)
t = test_letter(img, letter)
letterlist.append((t, alphabet, t))
old_x = x
counter += 1

box = (old_x + 1, 0, 140, 10)
letter = letters.crop(box)
t = test_letter(img, letter)
letterlist.append((t, alphabet, t))

t = sorted(letterlist)
t = t # 5-letter captcha

final = sorted(t, key=lambda e: e)

answer = ''.join(map(lambda l: l, final))
return answer

if __name__ == ‘__main__’:
print(decoder(sys.argv))


Вызывается он в другом файле, который выглядит так:

import unittest
from captcha_decoder import decoder


class TestStringMethods(unittest.TestCase):

def test_images(self):
self.assertEqual(decoder('test.jpg'), ‘c71fe’)
self.assertEqual(decoder('test2.jpg'), ‘7f4ca’)

if __name__ == ‘__main__’:
unittest.main()

Собственно, сам вопрос. Во втором файлике в строке self.assertEqual(decoder('test.jpg'), ‘c71fe’) указана картинка и символы, которые на ней изображены. При запуске в среде разработки PyCharm, получаем “ок” т.е. как я понимаю, указанные символы соответствуют символам на изображении. А как мне выделить то сами символы? т.е. не сверить, что они соответствуют, а именно узнать, какие там символы с помощью этого замечательного декодера. Извиняюсь за неграмотность задаваемого вопроса, но я надеюсь, что вы сможете понять, что я хотел бы найти. Заранее спасибо. Очень надеюсь на вашу помощь.

Прикреплённый файлы:
attachment captcha.jpg (5,1 KБ)

Офлайн

#2 Дек. 28, 2017 07:29:50

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Вопрос по распознаванию капчи

Возвращаемые символы - это переменная answer. Что мешает ее просто распечатать?
И вставляйте код с помощью тега code, чтобы отступы сохранялись.

Офлайн

#3 Дек. 28, 2017 12:41:32

alekssim
Зарегистрирован: 2017-12-27
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Вопрос по распознаванию капчи

Elaphe
Возвращаемые символы - это переменная answer. Что мешает ее просто распечатать?И вставляйте код с помощью тега code, чтобы отступы сохранялись.

А как это должно выглядеть? я пока не совсем понимаю. Пробую писать print и название этой переменной, но в итоге получаею ошибку “Missing parentheses in call to ‘print’”

 from PIL import Image
import sys
def decoder(
        im,
        threshold=200,
        mask="letters.bmp",
        alphabet="0123456789abcdef"):
    img = Image.open(im)
    img = img.convert("RGB")
    box = (8, 8, 58, 18)
    img = img.crop(box)
    pixdata = img.load()
    # open the mask
    letters = Image.open(mask)
    ledata = letters.load()
    def test_letter(img, letter):
        A = img.load()
        B = letter.load()
        mx = 1000000
        max_x = 0
        x = 0
        for x in range(img.size[0] - letter.size[0]):
            _sum = 0
            for i in range(letter.size[0]):
                for j in range(letter.size[1]):
                    _sum = _sum + abs(A[x + i, j][0] - B[i, j][0])
            if _sum < mx:
                mx = _sum
                max_x = x
        return mx, max_x
    # Clean the background noise, if color != white, then set to black.
    for y in range(img.size[1]):
        for x in range(img.size[0]):
            if (pixdata[x, y][0] > threshold) \
                    and (pixdata[x, y][1] > threshold) \
                    and (pixdata[x, y][2] > threshold):
                pixdata[x, y] = (255, 255, 255, 255)
            else:
                pixdata[x, y] = (0, 0, 0, 255)
    counter = 0
    old_x = -1
    letterlist = []
    for x in range(letters.size[0]):
        black = True
        for y in range(letters.size[1]):
            if ledata[x, y][0] != 0:
                black = False
                break
        if black:
            box = (old_x + 1, 0, x, 10)
            letter = letters.crop(box)
            t = test_letter(img, letter)
            letterlist.append((t[0], alphabet[counter], t[1]))
            old_x = x
            counter += 1
    box = (old_x + 1, 0, 140, 10)
    letter = letters.crop(box)
    t = test_letter(img, letter)
    letterlist.append((t[0], alphabet[counter], t[1]))
    t = sorted(letterlist)
    t = t[0:5]  # 5-letter captcha
    final = sorted(t, key=lambda e: e[2])
    answer = ''.join(map(lambda l: l[1], final))
    return answer
if __name__ == '__main__':
    print(decoder(sys.argv[1]))

 import unittest
from captcha_decoder import decoder
class TestStringMethods(unittest.TestCase):
    def test_images(self):
        self.assertEqual(decoder('test.jpg'), 'c71fe')
        self.assertEqual(decoder('test2.jpg'), '7f4ca')
if __name__ == '__main__':
    unittest.main()

Офлайн

#4 Дек. 31, 2017 10:20:33

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Вопрос по распознаванию капчи

Написано же - не хватает скобок.
Надо вот так:

print(answer)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version