Pull to refresh

Автоматизация через Userscript

Reading time3 min
Views3.2K
Привет, Хабр!

Вступление

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

Решение

Можно было бы написать небольшое десктопное приложение (благо опыт в C# есть), но это трудоемко, а задачу решить надо в кратчайшие сроки. На помощь мне пришел Userscript, позволяющий внедрить свою функцию в страничку и запустить её.
Для избежания проблем с регулярными выражениями (стандартная функция RegEx) воспользовался библиотекой jQuery и базовыми функциями Javascript внедрил её в страничку:
   var head = document.getElementsByTagName('head')[0];
   var script= document.createElement('script');
   script.type= 'text/javascript';
   script.src= 'http://code.jquery.com/jquery-latest.js';
   head.appendChild(script);

Следующим шагом было определить кнопочку голосования:
<tr>
  <td>
	<a href="#"><span>АВТОР</span></a>
  </td>
  <td>
	<span>Рейтинг записи:</span>
  </td>
  <td>
	<div id="thumbs_up">
	  <img src="thumbs_up.png" onclick="vote('UnicID', '1');" alt="Нравится">
	</div>
  </td>
  <td align=center width=20px>
	<div id="mess_ratio_UnicID">
	   <span><b>РЕЙТИНГ</b></span>
	</div>
  </td>
  <td>
	<div id="thumbs_down">
	  <img src="thumbs_down.png" onclick="vote('UnicID', '-1');" alt="Не нравится">
	</div>
  </td>
  <td>
	<div id="vote_status_UnicID">
	   <span></span>
	</div>
  </td>
  <td>
	<span>Сообщение оставлено </span><span>ВРЕМЯ</span>  
  </td>
</tr>

Кнопкой голосования была картинка с изображением «thumbs_up.png» или «thumbs_down.png», решив быть окончательно плохим мальчиком, выбрал минусовать все публикации. Тем самым понижал высокие рейтинги и «убивал» публикации без голосов, вводя рейтинг в минус.

Вызывая следующий код, происходило голосование за (точнее против) все публикации на странице:
   jQuery('img[src*=thumbs_down]').click();

Далее пробежался по всему сайту и проконтролировал каждое голосование.

Проблема

На следующий день в форуме кто-то пожаловался администрации на злостного оценщика. Продолжать участие в таком же темпе было нельзя, вдруг заблокируют. Переоценив ситуацию, решил переделать автоматическое голосование и определять текущий рейтинг каждой публикации. Условие составил такое:
1) если рейтинг меньше нуля или ноль, то голосуем +1;
2) если рейтинг больше нуля, то голосуем -1;

Задача была все та же, не использовать регулярные выражения. Поинтересовался документацией jQuery, выявил новые для себя функции ".not()", ":contains()", ".has()/:has()".
Пересмотрев вырезанный HTML код (см. выше) и поправив выражение, получил следующий код:
  jQuery('img[src*=thumbs_down]').parent().parent().parent().not("
        tr:has(span:contains('MyNick'), 
                   b:contains('-'),
                   b:contains('0')
        )").find('img[src*=thumbs_down]').click();

  jQuery('img[src*=thumbs_down]').parent().parent().parent().has("
                   span:contains('MyNick'),
                   b:contains('-'),
                   b:contains('0')
            ").find('img[src*=thumbs_up]').click(); 

Итак, по порядку:
Первый запрос jQuery
  1. находим картинки голосования [ jQuery('img[src*=thumbs_down]') ]
  2. далее делаем 3 прыжка вверх по родителям и попадаем на ближайшего общего родителя рейтинга и кнопки голосования, это TR ветка [.parent().parent().parent()]
  3. отсеиваем из найденных результатов те, которые:
    a) или не содержат тег «span» с моим ником;
    b) или не содержат тег «b» с рейтингом минус;
    c) или не содержат тег «b» с рейтингом ноль;
    [.not(«tr:has(span:contains('MyNick'), b:contains('-'), b:contains('0') )»)]
  4. находим кнопку отрицательного голосования и нажимаем её [.find('img[src*=thumbs_down]').click()];

Второй запрос jQuery
  1. находим картинки голосования [ jQuery('img[src*=thumbs_down]') ]
  2. далее делаем 3 прыжка вверх по родителям и попадаем на ближайшего общего родителя рейтинга и кнопки голосования, это TR ветка [.parent().parent().parent()]
  3. отсеиваем из найденных результатов те, которые:
    a) или содержат тег «span» с моим ником;
    b) или содержат тег «b» с рейтингом минус;
    c) или содержат тег «b» с рейтингом ноль;
    [.has(«span:contains('MyNick'), b:contains('-'), b:contains('0') „)]
  4. находим кнопку положительного голосования и нажимаем её [.find('img[src*=thumbs_up]').click()];

Итог

Очередной раз подтверждая, что лень двигатель прогресса, сделал автоматизированное и минимализированное автоматическое голосование с определением рейтинга и узнал новые возможности jQuery. Вот такими нехитрыми и понятными для чтения функциями можно избежать многих строк условий if-else.
Tags:
Hubs:
Total votes 8: ↑1 and ↓7-6
Comments6

Articles