Загрузка данных
#NoEnv
#SingleInstance Force
#Persistent
SendMode Input
SetWorkingDir %A_ScriptDir%
SetBatchLines, -1
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
; ============================================================
; ПОДКЛЮЧЕНИЕ GDI+
; ============================================================
;
; Файл Gdip_All.ahk должен лежать В ТОЙ ЖЕ ПАПКЕ,
; что и этот скрипт.
;
; Например:
;
; Aukcion.ahk
; Gdip_All.ahk
;
; ============================================================
#Include %A_ScriptDir%\Gdip_All.ahk
; ============================================================
; НАСТРОЙКИ
; ============================================================
; ============================================================
; 1. TESSERACT OCR
; ============================================================
;
; Здесь указан путь к программе Tesseract.
;
; Если Tesseract установлен стандартно:
;
; C:\Program Files\Tesseract-OCR\tesseract.exe
;
; ============================================================
TesseractPath := "C:\Program Files\Tesseract-OCR\tesseract.exe"
; ============================================================
; ЯЗЫК OCR
; ============================================================
;
; rus+eng = русский + английский
;
; Если тебе нужен только русский:
;
; OCRLanguage := "rus"
;
; ============================================================
OCRLanguage := "rus+eng"
; ============================================================
; 2. МАКСИМАЛЬНАЯ ЦЕНА
; ============================================================
;
; Скрипт будет выбирать цены НИЖЕ этого значения.
;
; 50000 = 50 000
;
; ============================================================
MaxPrice := 50000
; ============================================================
; 3. ПОЛЕ ПОИСКА
; ============================================================
;
; Координаты места, куда вводится название товара.
;
; X = положение по горизонтали
; Y = положение по вертикали
;
; ============================================================
InputX := 500
InputY := 300
; ============================================================
; ТЕКСТ, КОТОРЫЙ НУЖНО ИСКАТЬ
; ============================================================
SearchText := "НУЖНЫЙ ТЕКСТ"
; ============================================================
; 4. КНОПКА ОБНОВЛЕНИЯ СПИСКА
; ============================================================
;
; После ввода текста скрипт нажимает сюда.
;
; В дальнейшем это будет использоваться
; для обновления списка.
;
; ============================================================
RefreshX := 700
RefreshY := 300
; ============================================================
; 5. ОБЛАСТЬ OCR
; ============================================================
;
; ЭТО ОДИН ИЗ САМЫХ ВАЖНЫХ ПУНКТОВ.
;
; Скрипт будет анализировать ТОЛЬКО эту область экрана.
;
; OCRX / OCRY
; = левый верхний угол области.
;
; OCRWidth
; = ширина области.
;
; OCRHeight
; = высота области.
;
; Пример:
;
; OCRX := 400
; OCRY := 400
; OCRWidth := 700
; OCRHeight := 500
;
; ============================================================
OCRX := 400
OCRY := 400
OCRWidth := 700
OCRHeight := 500
; ============================================================
; 6. КНОПКА ПОДТВЕРЖДЕНИЯ
; ============================================================
;
; После нахождения подходящего варианта:
;
; 1. клик по найденной цене;
; 2. ожидание;
; 3. клик сюда.
;
; ============================================================
ConfirmX := 1000
ConfirmY := 800
; ============================================================
; 7. ПОЛЗУНОК СПИСКА
; ============================================================
;
; Координаты самого ползунка.
;
; ============================================================
ScrollBarX := 1200
ScrollBarY := 500
; ============================================================
; НА СКОЛЬКО ПИКСЕЛЕЙ ОПУСКАТЬ ПОЛЗУНОК
; ============================================================
;
; Например:
;
; 150 = опускать на 150 пикселей.
;
; ============================================================
ScrollPixels := 150
; ============================================================
; СКОЛЬКО РАЗ ПРОКРУЧИВАТЬ ОДНУ СТРАНИЦУ
; ============================================================
;
; Например:
;
; 5 шагов × 150 пикселей.
;
; После 5 шагов скрипт считает страницу законченной.
;
; ============================================================
MaxScrollSteps := 5
; ============================================================
; 8. КНОПКА ПЕРЕХОДА НА 2-Ю СТРАНИЦУ
; ============================================================
;
; ============================================================
Page2X := 1100
Page2Y := 850
; ============================================================
; ЗАДЕРЖКИ
; ============================================================
;
; Все значения указаны в миллисекундах.
;
; 1000 = 1 секунда
; 500 = 0.5 секунды
; 300 = 0.3 секунды
;
; Эти значения можно менять.
;
; ============================================================
; После движения мыши
MoveDelay := 80
; После обычного клика
ClickDelay := 250
; После обновления списка
RefreshDelay := 600
; После ввода текста
InputDelay := 250
; После прокрутки
ScrollDelay := 300
; После перехода на страницу
PageDelay := 600
; После выбора найденного товара
SelectDelay := 350
; ============================================================
; СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ
; ============================================================
ScriptRunning := false
CurrentPage := 1
CurrentScrollStep := 0
; ============================================================
; F3 — ЗАПУСК
; ============================================================
F3::
if (ScriptRunning)
return
ScriptRunning := true
CurrentPage := 1
CurrentScrollStep := 0
ToolTip, СКРИПТ ЗАПУЩЕН
Sleep, 700
ToolTip
; Начинаем с первого пункта
SetTimer, StartSearch, -10
return
; ============================================================
; F6 — ОСТАНОВКА
; ============================================================
F6::
ScriptRunning := false
ToolTip, СКРИПТ ОСТАНОВЛЕН
Sleep, 700
ToolTip
return
; ============================================================
; НАЧАЛО РАБОТЫ
; ============================================================
;
; Здесь выполняются пункты:
;
; 1. Ввод текста
; 2. Обновление списка
;
; ============================================================
StartSearch:
if (!ScriptRunning)
return
; ============================================================
; ПУНКТ 1
; ВВОД НАЗВАНИЯ ТОВАРА
; ============================================================
MouseMove, %InputX%, %InputY%, 0
Sleep, %MoveDelay%
Click
Sleep, %ClickDelay%
; Выделяем старый текст
SendInput, ^a
Sleep, 100
; Вводим новый текст
SendInput, %SearchText%
Sleep, %InputDelay%
; ============================================================
; ПУНКТ 2
; ОБНОВЛЕНИЕ СПИСКА
; ============================================================
MouseMove, %RefreshX%, %RefreshY%, 0
Sleep, %MoveDelay%
Click
Sleep, %RefreshDelay%
; ============================================================
; Начинаем поиск с верхней части первой страницы
; ============================================================
CurrentPage := 1
CurrentScrollStep := 0
Goto, SearchPage1
return
; ============================================================
; ПОИСК НА ПЕРВОЙ СТРАНИЦЕ
; ============================================================
SearchPage1:
if (!ScriptRunning)
return
; ============================================================
; ПУНКТ 3
; OCR АНАЛИЗ ОБЛАСТИ
; ============================================================
OCRResult := OCR_GetPrices(OCRX, OCRY, OCRWidth, OCRHeight, TesseractPath, OCRLanguage, MaxPrice)
; ============================================================
; НАЙДЕНА ПОДХОДЯЩАЯ ЦЕНА
; ============================================================
if (OCRResult != "")
{
StringSplit, Found, OCRResult, |
FoundX := Found1
FoundY := Found2
FoundPrice := Found3
ToolTip, НАЙДЕНА ЦЕНА: %FoundPrice%
Sleep, 500
ToolTip
; ------------------------------------------------------------
; КЛИК ПО НАЙДЕННОМУ ВАРИАНТУ
; ------------------------------------------------------------
MouseMove, %FoundX%, %FoundY%, 0
Sleep, %MoveDelay%
Click
Sleep, %SelectDelay%
; ------------------------------------------------------------
; ПОДТВЕРЖДЕНИЕ
; ------------------------------------------------------------
MouseMove, %ConfirmX%, %ConfirmY%, 0
Sleep, %MoveDelay%
Click
Sleep, %RefreshDelay%
; ------------------------------------------------------------
; ПОСЛЕ ПОКУПКИ:
;
; НЕ ВВОДИМ ТЕКСТ ЗАНОВО.
;
; СРАЗУ ПЕРЕХОДИМ К ПУНКТУ 2.
; ------------------------------------------------------------
CurrentPage := 1
CurrentScrollStep := 0
SetTimer, RefreshSearch, -10
return
}
; ============================================================
; ПОДХОДЯЩЕЙ ЦЕНЫ НЕТ
; ============================================================
CurrentScrollStep++
; ============================================================
; ПУНКТ 4
; ПРОКРУТКА ВНИЗ
; ============================================================
if (CurrentScrollStep <= MaxScrollSteps)
{
ScrollListDown()
Sleep, %ScrollDelay%
Goto, SearchPage1
}
; ============================================================
; ПУНКТ 5
; ПЕРЕХОД НА 2-Ю СТРАНИЦУ
; ============================================================
CurrentPage := 2
CurrentScrollStep := 0
MouseMove, %Page2X%, %Page2Y%, 0
Sleep, %MoveDelay%
Click
Sleep, %PageDelay%
; Переходим к поиску на второй странице
Goto, SearchPage2
return
; ============================================================
; ПОИСК НА ВТОРОЙ СТРАНИЦЕ
; ============================================================
SearchPage2:
if (!ScriptRunning)
return
; ============================================================
; OCR
; ============================================================
OCRResult := OCR_GetPrices(OCRX, OCRY, OCRWidth, OCRHeight, TesseractPath, OCRLanguage, MaxPrice)
; ============================================================
; НАЙДЕНА ПОДХОДЯЩАЯ ЦЕНА
; ============================================================
if (OCRResult != "")
{
StringSplit, Found, OCRResult, |
FoundX := Found1
FoundY := Found2
FoundPrice := Found3
ToolTip, НАЙДЕНА ЦЕНА: %FoundPrice%
Sleep, 500
ToolTip
; ------------------------------------------------------------
; КЛИК ПО ВАРИАНТУ
; ------------------------------------------------------------
MouseMove, %FoundX%, %FoundY%, 0
Sleep, %MoveDelay%
Click
Sleep, %SelectDelay%
; ------------------------------------------------------------
; КНОПКА ПОДТВЕРЖДЕНИЯ
; ------------------------------------------------------------
MouseMove, %ConfirmX%, %ConfirmY%, 0
Sleep, %MoveDelay%
Click
Sleep, %RefreshDelay%
; ------------------------------------------------------------
; ПОСЛЕ УСПЕШНОГО ВЫБОРА:
;
; ВОЗВРАЩАЕМСЯ К ПУНКТУ 2
; ------------------------------------------------------------
CurrentPage := 1
CurrentScrollStep := 0
SetTimer, RefreshSearch, -10
return
}
; ============================================================
; НА ВТОРОЙ СТРАНИЦЕ НИЧЕГО НЕ НАЙДЕНО
; ============================================================
CurrentScrollStep++
; ============================================================
; ПРОКРУТКА ВТОРОЙ СТРАНИЦЫ
; ============================================================
if (CurrentScrollStep <= MaxScrollSteps)
{
ScrollListDown()
Sleep, %ScrollDelay%
Goto, SearchPage2
}
; ============================================================
; ВТОРАЯ СТРАНИЦА ЗАКОНЧИЛАСЬ
;
; НИЧЕГО НЕ НАШЛИ.
;
; ВОЗВРАЩАЕМСЯ К ПУНКТУ 2.
; ============================================================
CurrentPage := 1
CurrentScrollStep := 0
SetTimer, RefreshSearch, -10
return
; ============================================================
; ПУНКТ 2 ПОСЛЕ УСПЕШНОГО ВЫБОРА
; ============================================================
;
; Здесь текст уже введён.
;
; Поэтому заново вводить его НЕ НУЖНО.
;
; Просто обновляем список.
;
; ============================================================
RefreshSearch:
if (!ScriptRunning)
return
MouseMove, %RefreshX%, %RefreshY%, 0
Sleep, %MoveDelay%
Click
Sleep, %RefreshDelay%
CurrentPage := 1
CurrentScrollStep := 0
Goto, SearchPage1
return
; ============================================================
; ФУНКЦИЯ ПРОКРУТКИ
; ============================================================
ScrollListDown()
{
global ScrollBarX
global ScrollBarY
global ScrollPixels
global MoveDelay
; ------------------------------------------------------------
; Наводимся на ползунок
; ------------------------------------------------------------
MouseMove, %ScrollBarX%, %ScrollBarY%, 0
Sleep, %MoveDelay%
; ------------------------------------------------------------
; Зажимаем левую кнопку
; ------------------------------------------------------------
Click, Down
Sleep, 100
; ------------------------------------------------------------
; Рассчитываем новую позицию
; ------------------------------------------------------------
NewScrollY := ScrollBarY + ScrollPixels
; ------------------------------------------------------------
; Опускаем ползунок
; ------------------------------------------------------------
MouseMove, %ScrollBarX%, %NewScrollY%, 300
; ------------------------------------------------------------
; Отпускаем кнопку
; ------------------------------------------------------------
Click, Up
}
; ============================================================
; OCR_GetPrices
; ============================================================
;
; Делает скриншот области OCR.
;
; Передаёт его Tesseract.
;
; Получает TSV.
;
; Ищет число меньше MaxPrice.
;
; Возвращает:
;
; X|Y|PRICE
;
; ============================================================
OCR_GetPrices(X, Y, Width, Height, TesseractPath, Language, MaxPrice)
{
; ------------------------------------------------------------
; Временные файлы
; ------------------------------------------------------------
TempImage := A_Temp "\ahk_auction_screen.png"
TempBase := A_Temp "\ahk_auction_ocr"
TSVFile := TempBase ".tsv"
; ------------------------------------------------------------
; Удаляем старый результат Tesseract
; ------------------------------------------------------------
if (FileExist(TSVFile))
FileDelete, %TSVFile%
; ------------------------------------------------------------
; Запускаем GDI+
; ------------------------------------------------------------
pToken := Gdip_Startup()
if (!pToken)
{
ToolTip, ОШИБКА: GDI+ НЕ ЗАПУСТИЛСЯ
Sleep, 1000
ToolTip
return ""
}
; ------------------------------------------------------------
; Создаём скриншот нужной области
; ------------------------------------------------------------
ScreenArea := X "|" Y "|" Width "|" Height
pBitmap := Gdip_BitmapFromScreen(ScreenArea)
if (!pBitmap)
{
Gdip_Shutdown(pToken)
ToolTip, ОШИБКА: НЕ УДАЛОСЬ СДЕЛАТЬ СКРИНШОТ
Sleep, 1000
ToolTip
return ""
}
; ------------------------------------------------------------
; Сохраняем скриншот
; ------------------------------------------------------------
SaveResult := Gdip_SaveBitmapToFile(pBitmap, TempImage)
; ------------------------------------------------------------
; Освобождаем GDI+
; ------------------------------------------------------------
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
if (SaveResult != 0)
return ""
if (!FileExist(TempImage))
return ""
; ============================================================
; ЗАПУСК TESSERACT
; ============================================================
RunWait, "%TesseractPath%" "%TempImage%" "%TempBase%" -l %Language% --psm 6 tsv,, Hide
; ------------------------------------------------------------
; Проверяем TSV
; ------------------------------------------------------------
if (!FileExist(TSVFile))
return ""
; ------------------------------------------------------------
; Читаем результат
; ------------------------------------------------------------
FileRead, TSV, %TSVFile%
if (ErrorLevel)
return ""
; ============================================================
; ОБРАБОТКА OCR
; ============================================================
Loop, Parse, TSV, `n, `r
{
Line := A_LoopField
; ------------------------------------------------------------
; Пропускаем пустые строки
; ------------------------------------------------------------
if (Line = "")
continue
; ------------------------------------------------------------
; Пропускаем заголовок TSV
; ------------------------------------------------------------
if (InStr(Line, "level" . A_Tab . "page_num"))
continue
; ------------------------------------------------------------
; Разбираем строку TSV
; ------------------------------------------------------------
StringSplit, Col, Line, %A_Tab%
; ------------------------------------------------------------
; Col6 = X
; Col7 = Y
; Col8 = Width
; Col9 = Height
; Col12 = текст
; ------------------------------------------------------------
if (Col12 = "")
continue
Text := Trim(Col12)
if (Text = "")
continue
; ============================================================
; ОЧИСТКА ЦЕНЫ
; ============================================================
CleanPrice := Text
CleanPrice := StrReplace(CleanPrice, "₽", "")
CleanPrice := StrReplace(CleanPrice, "$", "")
CleanPrice := StrReplace(CleanPrice, "€", "")
CleanPrice := StrReplace(CleanPrice, " ", "")
CleanPrice := StrReplace(CleanPrice, ".", "")
CleanPrice := StrReplace(CleanPrice, ",", "")
; ------------------------------------------------------------
; Оставляем только цифры
; ------------------------------------------------------------
CleanPrice := RegExReplace(CleanPrice, "[^\d]")
if (CleanPrice = "")
continue
; ------------------------------------------------------------
; Переводим в число
; ------------------------------------------------------------
Price := CleanPrice + 0
; ============================================================
; ПРОВЕРКА ЦЕНЫ
; ============================================================
if (Price > 0 && Price < MaxPrice)
{
; ------------------------------------------------------------
; Вычисляем координаты центра найденного текста
; ------------------------------------------------------------
FoundX := X + Col6 + (Col8 / 2)
FoundY := Y + Col7 + (Col9 / 2)
; ------------------------------------------------------------
; Возвращаем:
;
; X|Y|PRICE
; ------------------------------------------------------------
return FoundX "|" FoundY "|" Price
}
}
; ============================================================
; НИЧЕГО НЕ НАЙДЕНО
; ============================================================
return ""
}