Автоматизируем щелчки мышкой в Linux: xdotool

  • Tutorial
Эта очень короткая заметка на примере активации ключей в Steam описывает процесс автоматизации операций, выполняемых при помощи мыши и клавиатуры.

Допустим, вы купили несколько наборов игр Humble Bundle. Теперь у вас есть, например, 5 ключей для активации в Steam. А может быть 15 или даже 25. Вы очень не хотите активировать их вручную, потому что это слишком муторно: в клиенте Steam нужно каждый раз наводить курсор на меню «Games», щёлкать, потом наводить курсор на пункт меню «Activate a Product on Steam…», опять щёлкать, потом нажимать Enter, потом ещё раз Enter, и только затем наконец-то вводить ключ (а потом нужно подождать, ещё раз нажать Enter, затем Escape). А потом повторять то же самое для каждого последующего ключа. Как писал Леонид Каганов, стоило ли вообще ради такого «прогресса» спускаться с пальмы и брать в руки каменный топор?

В общем, вы решили этот процесс автоматизировать — тем более, что задача-то, на самом деле, очень простая. Для её решения нам потребуются консольные утилиты xdotool и xclip — убедитесь, что они установлены у вас в системе.

Для начала вы собираете ключи с веб-страницы, чтобы затем записать их в текстовый файл, по одному на строку. Естественно, не вручную. Например, со страницы Humble Budle их можно собрать, выполнив через JS-консоль что-нибудь в таком духе:

$("div.keyfield:visible").each(function() {console.log($(this).text())});

Получается текстовый файл с примерно таким содержимым:

9MZ43-42XXZ-0B9X3
I4YYK-CRGVN-VHXCR
NQJ6E-GJWNG-GZWVX
YCKI8-I0B9T-85CM4
KBFHW-5LE39-WHFMW
WFLWX-PPRBT-ZCGAN
ER26C-XFT5C-2NDGG
J876-XPFC-H0SF-KGMO
37YZQ-93TCM-V9MBY
2GFNA-XHBME-3MB70

При сохранении текстового файла убедитесь, что в конце есть перенос строки (некоторые текстовые редакторы не добавляют его автоматически). Иначе при выполнении скрипта последний ключ не будет активирован.

Далее вам нужно открыть Steam и определить координаты тех точек, куда нужно будет автоматически перемещать курсор. Таких точек две: во-первых, точка для первого щелчка (меню «Games»), во-вторых, точка для второго щелчка (пункт меню «Activate a Product on Steam…»). Тут по настроению — можете получить координаты с помощью команды getmouselocation, а можете их подобрать.

В первом случае можно либо запустить xdotool через watch (для автоматического перевыполнения команды через определённый интервал времени), либо добавить sleep.

То есть либо запускаете watch xdotool getmouselocation и наводите курсор на нужное место экрана, посматривая при этом в консоль и запоминая значения нужных точек, либо запускаете xdotool sleep 5 getmouselocation и получаете координаты той точки, где курсор оказывается через 5 секунд после запуска команды (соответственно, смотреть в консоль или запоминать координаты не нужно — достаточно будет просто успеть поместить курсор в нужное место, и уже потом переключиться к консоли).

Во втором случае вы пишете, допустим, xdotool mousemove 52 38, выполняете, смотрите, где оказался курсор, а потом меняете числа, пока не найдёте подходящие. Этот вариант более весёлый, поэтому, думаю, многие предпочтут сделать именно так.

Теперь, когда у нас есть нужные координаты, давайте действовать итеративно: прежде всего попробуем автоматически пройти до момента ввода ключа.

Для этого будем использовать команды mousemove, click, sleep и key. Список команд, кстати, можно посмотреть в документации по xdotool.

Давайте попробуем:

xdotool mousemove 210 105 click 1 mousemove 210 160 sleep 0.1 click 1 sleep 0.1 key Return sleep 0.1 key Return

Если в точке, куда в первую очередь перемещается курсор, не Steam, а какое-то другое окно (например, если Steam скрыт за окном терминала), то нужно добавить команды windowactivate/windowfocus, чтобы сначала отобразилось окно Steam, и уже затем выполнялись следующие команды.

Например:

steam_window=48234551 ; xdotool windowactivate $steam_window windowfocus $steam_window sleep 0.5 mousemove 210 105 click 1 mousemove 210 160 sleep 0.1 click 1 sleep 0.1 key Return sleep 0.1 key Return

Чтобы получить идентификатор активного окна, вы можете использовать команду getactivewindow (если окно Steam будет активно через секунду после выполнения команды xdotool sleep 1 getactivewindow, то в консоли отобразится его идентификатор). Кроме того, для команды getmouselocation (см. выше) также указывается идентификатор окна, над которым находится курсор.

Теперь давайте попробуем написать небольшой скрипт, который читает файл с ключами и поочерёдно их активирует.

Скрипт можно назвать, например, activate_steam_keys.sh.

#!/bin/bash
commands=(
    "sleep 1"
    "mousemove 210 105"
    "click 1"
    "mousemove 210 160"
    "sleep 0.1"
    "click 1"
    "sleep 0.1"
    "key Return"
    "sleep 0.1"
    "key Return"
    "sleep 0.1"
    "key ctrl+v"
    "sleep 0.5"
    "key Return"
    "sleep 10"
    "key Return"
    "sleep 0.5"
    "key Escape"
)
while read key
do
    echo -n $key | xclip -selection c
    xdotool ${commands[*]}
done < $1

Разрешаем для файла выполнение и запускаем скрипт. При этом передаём скрипту аргумент — имя файла с ключами.

chmod +x activate_steam_keys.sh
./activate_steam_keys.sh steam_keys.txt

А дальше просто смотрим на экран и наслаждаемся процессом. Всё-таки хорошая идея была взять тот каменный топор.

Весёлого программирования!
Share post

Similar posts

Comments 15

    +1
    В наборах игр Humble Bundle уже очень давно нет никаких ключей.
      +5
      А у меня есть, во всех что брал (последний девятый)
      Может платить нужно больше бакса?
        0
        9-ый был полгода назад. В новых нет ключей.
        Да и если нужна автоматизация возможно удобней будет использовать Sikuli
          +1
          Сейчас там можно привязать стим аккаунт и активировать игры, кликая по ссылке.
            0
            Только в новых бандлах.
        +2
        Мне одному кажется, что если у вас есть 25 ключей активации, ваша проблема не в том, как их ввести, а в том, что вы купили 25 игр, к большинству из которых вы даже не прикоснётесь?
        /me имеет 400+ игр в стиме (при этом коды из HB не активировал, всё купленное там с 2007-го по 2012-й), но уже года полтора, как завязал.
          +2
          Я в стиме завел категорию «не играл» и складываю туда все купленные игры и потихонку в них играю. У меня число игр приближается к 400, и на данный момент игр, в которые я не играл только две.
            +1
            Ух ты. Когда ж вы работать успеваете?
              +1
              Я ж не по 14 часов в день работаю :) Да и аккаунту 7 лет уже, вполне неторопливо играется
          0
          Я, конечно, понимаю, что Вы ещё и приводите примеры работы с xdotool&xclip, но мне Ваш пост очень сильно напомнил вот это:
          robanukah.ru/uploads/images/00/00/02/2011/11/10/420767.png
          ;-)
            +1
            Прелесть какая.

            У меня есть определённый порог совокупности трудности выполнения операции и количества повторений, при достижении которого я обычно берусь за автоматизацию.

            Естественно, во многих случаях можно всё сделать вручную, но часто написать немного кода приятнее, чем многократно выполнять какие-то рутинные действия. Например, если нужно собрать ссылки на все задачи в Редмайне, уведомления по которым пришли по почте. Или, например, сохранить все посты из чьего-нибудь ЖЖ.
              +2
              И опять я могу ответить комиксом xkcd =)
              xkcd.com/1205/
              Собственно, это многим не мешало бы на стенку повесить — в первую очередь, наверное, мне =)
              Хотя насчёт того, что код писать приятнее — согласен. И порог у меня тоже такой имеется — вон, задолбало флешки на одной своей сугубо консольной системе вручную монтировать… почти закончил свой демон автомонтирования с регулярками и кастомными скриптами ;-) Плюс, если написать красиво и опубликовать, этот код послужит хотя бы примером для многих людей, которые тоже, может быть, захотят сделать то же самое, и ещё не поленятся сначала погуглить на предмет готового решения =)
                +2
                Для автоматизации полноценной работы с сайтами из обычных скриптов, а не из консоли браузера, советую попробовать PhantomJS в паре с Selenium. Сам недавно для себя открыл, классная штука!
                  0
                  Спасибо!
              +1
              Первое действительно надежное средство отключение скринсейвера :)

              Only users with full accounts can post comments. Log in, please.