Вступление:
В Беларуси стоит острая задача с приобретением виз в Еврозону (т.е. Шенген). Все из-за того, что Польское представительство предоставляет так называемые мульти-визы за покупками (т.е. многократные). Регистрация производится на сайте представительства онлайн. Но каждая задача состоит в том, что свободных дат не словить. Исключительный вариант — круглосуточно чекать страницу, и если появится дата — стремительно «ловить» ее и заканчивать регистрацию. Т.к. свободного времени для круглосуточного чека нет, было принято решение об автоматизации данного процесса.
Сразу оговорюсь, что существуют разные скрипты, которые вылавливают свободные даты и за которые люди получают деньги. Мой скрипт не претендует на их место по быстроте, качеству и т.д. Данный скрипт был сделан только для себя, никакой торговой и другой выгоды я не преследовал.
Постановка задачи и входные данные:
Для начала нужно было исследовать то, как проходит процесс регистрации.
Линк на сайт представительства: by.e-konsulat.gov.pl/
На основной странице видим два селекта, с выбором страны и города. Предпочтя нужные параметры нас редиректит на by.e-konsulat.gov.pl/Informacyjne/Placowka.aspx?IDPlacowki=94.
Потом выбираем из меню «Национальная Виза — Зарегистрируйте бланк» и переходим на by.e-konsulat.gov.pl/Uslugi/RejestracjaTerminu.aspx?IDUSLUGI=1&IDPlacowki=94 — данный урл я и брал за входную точку, т.к. нет смысла в автоматизации предыдущих страниц (безусловно, перед этим я проверил вероятность входа по данному урлу с чистыми куками)
Дальше мы видим капчу. Введя ее, нам дается итог — Неимение свободных дат.
Исходя из этих данных, мы можем сделать очерк плана нашего грядущего скрипта:

Выбор инструмента
Позже того, как я определился с тем, что нужно делать — стал вопрос о подходящем инструменте. Сразу хочу оговориться, я не являюсь программистом, я тестироващик. Но некоторые познания языков присутствуют.
В самом начале я хотел автоматизировать данный процесс на TestComplete. Позже автоматизации я столкнулся с некоторыми загвоздками, основная из которых была скорость отработки скрипта, да и плюс ко каждому я юзал ветхую версию тесткомплита 7.5, которая работает максимум с браузером Mozzila 3.5. Сами понимаете, что в таком ветхом браузере отображение элементов хромает, да и верстка местами едет. Следственно на данный инструмент я забил и присмотрелся к Selenium WebDriver.
Языком написания скрипта был выбран Python. Выбор пал на него по одной только причине, я был немножко знаком с данным скриптовым языком, а лезть в Java, скажем и постигать его не было ни времени, ни мечты.
Работа с капчей
На самом деле автоматизировать данные действия не составляет специального труда, но все портит неприятная капча. Каждая задача заключалась в том, что капчи с периодичность раз в один-два месяца менялись и следственно не было смысла продумывать спецтехнологию разгадывания капчи (создания образцов, масок и т.д.). По этой причине я решил заюзать antigate.
Зарегистрировавшись там и закинув 3 бакса, я получил источников на 3000 капч.
Но сейчас нужно было продумать алгорифм обработки данной капчи, отправки ее на антигейт и приобретения значения капчи. Выглядело это приблизительно так:

Для работы с антигейтом я применял API данного обслуживания. Пришлось развернуть на локальной машине PHP server, не заморачиваясь выбор пал на Denwer. Сотворил локальный сайт test1.ru и закинул туда php страницу для работы с API обслуживания.
Листинг данной страницы
<?php
function recognize(
$filename,
$apikey,
$is_verbose = true,
$sendhost = "antigate.com",
$rtimeout = 10,
$is_phrase = 0,
$is_regsense = 1,
$is_numeric = 0,
$min_len = 4,
$max_len = 4,
$is_russian = 1)
{
if (!file_exists($filename))
{
if ($is_verbose) echo "<b>file $filename not found</b>";
return false;
}
$fp=fopen($filename,"r");
if ($fp!=false)
{
$body="";
while (!feof($fp)) $body.=fgets($fp,1024);
fclose($fp);
$ext=strtolower(substr($filename,strpos($filename,".") 1));
}
else
{
if ($is_verbose) echo "<b>could not read file $filename<b>";
return false;
}
if ($ext=="jpg") $conttype="image/pjpeg";
if ($ext=="gif") $conttype="image/gif";
if ($ext=="png") $conttype="image/png";
$boundary="---------FGf4Fh3fdjGQ148fdh";
$content="--$boundaryrn";
$content.="Content-Disposition: form-data; name="method"rn";
$content.="rn";
$content.="postrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="key"rn";
$content.="rn";
$content.="$apikeyrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="phrase"rn";
$content.="rn";
$content.="$is_phrasern";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="regsense"rn";
$content.="rn";
$content.="$is_regsensern";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="numeric"rn";
$content.="rn";
$content.="$is_numericrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="min_len"rn";
$content.="rn";
$content.="$min_lenrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="max_len"rn";
$content.="rn";
$content.="$max_lenrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="is_russian"rn";
$content.="rn";
$content.="$is_russianrn";
$content.="--$boundaryrn";
$content.="Content-Disposition: form-data; name="file"; filename="capcha.$ext"rn";
$content.="Content-Type: $conttypern";
$content.="rn";
$content.=$body."rn";
$content.="--$boundary--";
$poststr="POST http://$sendhost/in.php HTTP/1.0rn";
$poststr.="Content-Type: multipart/form-data; boundary=$boundaryrn";
$poststr.="Host: $sendhostrn";
$poststr.="Content-Length: ".strlen($content)."rnrn";
$poststr.=$content;
$fp=fsockopen($sendhost,80,$errno,$errstr,30);
if ($fp!=false)
{
fputs($fp,$poststr);
$resp="";
while (!feof($fp)) $resp.=fgets($fp,1024);
fclose($fp);
$result=substr($resp,strpos($resp,"rnrn") 4);
}
else
{
if ($is_verbose) echo "<b>could not connect to anti-captcha</b>";
if ($is_verbose) echo "<b>socket error: $errno ( $errstr )</b>";
return false;
}
if (strpos($result, "ERROR")!==false or strpos($result, "<HTML>")!==false)
{
if ($is_verbose) echo "<b>server returned error: $result</b>";
return false;
}
else
{
$ex = explode("|", $result);
$captcha_id = $ex[1];
if ($is_verbose) echo "<b>$captcha_id</b>";
}
}
$text=recognize("captcha.png","Тут должен быть ключ для работы с сервисом",true,"antigate.com");
?>
Я не стал исчерпывающе разбираться, что к чему, но исключительное, что я выставил — это следующие настройки:
$is_phrase = 0, //является ли ваша капча фразой
$is_regsense = 1, //регистро зависимая либо нет?
$is_numeric = 0, //Состоит из цифр?
$min_len = 4, //минимальная длинна
$max_len = 4, //максимальная длинна
$is_russian = 1 //есть ли русские символы
В выводе нам нужно разместить изображение captcha.png в директорию, где находится index.php и перейти по урлу test1.ru
В выводе капча полетит на сервис, когда она разгадается нам придет ее id, обрамленный в тег b, либо придет какая-нибудь оплошность, которая отобразиться.
Останется дело за малым, только забрать значение капчи со страницы по ее id.
Создание скрипта
Т.к. все заблаговременные подготовки сделаны, то можем приступать непринужденно к написанию скрипта.
Трудиться мы будем с двумя открытыми окнами Firefox. Т.к. в одном окне у нас будет протекать чек дат, а во втором все работы касательно капчи. Для отображения капчи в новом окне, мы легко будем находить сам элемент на странице по id и считывать урл нынешней капчи. При обращении на данный урл, мы получим только изображение капчи, без лишних элементов.

Сейчас листинг скрипта, с комментариями:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time
driver = webdriver.Firefox() #запускаем первое окно (основное)
add_driver = webdriver.Firefox() #запускаем до