Вот мы неспеша и подобрались к очень интересной теме. Запись и сохранение информации при помощи iMacros и Javascript — вещь крайне необходимая. Подобные функции нам понадобятся постоянно и везде. Допустим, у нас есть текстовый файл, а в нем список групп вконтакте, в которые нужно зайти и оставить в каждой рекламное сообщение с предложением увеличить пенис, например. Или наоборот, нам понадобится снять позиции сайтов в гугле или яндексе по разным запросам и сохранить все это в файл или таблицу Excel.
Как НЕ нужно считывать и сохранять текстовые файлы
У меня слезы на глазах наворачивались, когда я видел, как другие люди пытались решить подобную задачу, нестандартно эксплотируя функционал iMacros. Сложно было удержаться, чтобы не переименовать функции во что-то более нормальное, но решил оставить как есть, пример из интернета:
Так записывать в файлы НЕ надо:
function sohranyaem_v_txt(sohranyaem) { var macro; iimSet("SOHRANYAEM",sohranyaem); macro = "CODE:"; macro += "ADD !EXTRACT {{SOHRANYAEM}}"+"\n"; macro += "SAVEAS TYPE=EXTRACT FOLDER=C:\\iMacros FILE=otchet.txt"+ "\n"; iimPlay(macro) } // Текст для сохранения var sohranyaem = 'текст, который мы собираемся сохранить' // Сохраняем в файл sohranyaem_v_txt(sohranyaem);
Во-первых, привыкайте называть функции и переменные нормальными именами, желательно английскими и в camelCase, например: function saveToFile (text) {...}
. Данное решение, несмотря на свою убогость, рабочее, но если нам понадобится чтение из файла, такой подход не подойдет, придется искать костыли и грабли с совершенно другой логикой. Код будет неконсистентный, к тому же есть решение намного лучше.
Вот еще плохой пример с просторов интернета, это макрос для автологина на почту.
Так читать файлы НЕ надо:
var put = 'C:\\iMacros\\Macros' var url = 'https://www.yandex.ua' var count = Number(window.prompt("введите цифру в какую почту зайти"+ "\n"+"1-aa@yandex.com"+ "\n"+"2-bb@yandex.com"+ "\n"+"3-cc@yandex.com"+ "\n")) var tabPoshta = 'yandexPoshta.csv'; var macroStart; macroStart ="CODE:"; iimSet("COUNT",count); macroStart +="CLEAR" + "\n";// очищаем куки macroStart +="SET !DATASOURCE_DELIMITER ;" + "\n";// обозначаем разделитель в таблице ; macroStart +="CMDLINE !DATASOURCE "+put+"\\"+tabPoshta+ "\n"; macroStart +="SET !DATASOURCE_COLUMNS 2" + "\n"; //iMacros количество колонок в этом файле macroStart +="SET !DATASOURCE_LINE {{COUNT}} " + "\n"; //из какой строки по счету нужно извлечь информацию macroStart += "ADD !EXTRACT {{!COL1}}"+ "\n";//почта macroStart += "ADD !EXTRACT {{!COL2}}"+ "\n";//пароль iimPlay(macroStart) var poshta = iimGetLastExtract(1);//вытягиваем почту в джаваскрипт var pass = iimGetLastExtract(2);//вытягиваем пароль в джаваскрипт var macroVhod; macroVhod ="CODE:"; macroVhod += "URL GOTO="+url+ "\n";//заход на адрес macroVhod += "TAG POS=1 TYPE=INPUT:TEXT FORM=ACTION:https://passport.yandex.ru/passport?mode=auth&retpath=https://mail.yandex.ua ATTR=ID:* CONTENT="+poshta+ "\n";//вводим в поле почту macroVhod += "SET !ENCRYPTION NO"+ "\n";//не шифруем пароль macroVhod += "TAG POS=1 TYPE=INPUT:PASSWORD FORM=ACTION:https://passport.yandex.ru/passport?mode=auth&retpath=https://mail.yandex.ua ATTR=ID:* CONTENT="+pass+ "\n";//вводим пароль macroVhod += "TAG POS=2 TYPE=BUTTON FORM=ACTION:https://passport.yandex.ru/passport?mode=auth&retpath=https://mail.yandex.ua ATTR=TXT:Войти"+ "\n";//нажимаем кнопку войти. iimPlay(macroVhod)
Такой жуткий код отпугнет не только новичка, но и профи. Тут используются стандартные функции для работы с форматом CSV и они ужасны. Дело даже не в говнокоде, а в том, что при таком подходе мы не имеем удобного доступа к каждой ячейке таблицы, много лишних промежуточных переменных. Еще огромный минус, это скорость работы скрипта, написанного подобным образом. Это не пустословие, я как-то делал бота в таком стиле, он брал, добавлял и изменял информацию в таблице, объемом несколько сотен строк — для операции поиска, перебора и замены значений уходило около минуты(!). При помощи Javascript, это можно сделать за тысячные доли секунды. В следующем уроке я вам расскажу про формат CSV, и покажу во много раз более изящный и простой способ работать с Excel-таблицами. Вы сами увидите, как можно удобно и приятно манипулировать даже большими табличными данными.
Правильная работа с txt-файлами при помощи iMacros и Javascript
В прошлых уроках вы уже сталкивались с использованием Components и Classes в iMacros. Там, разумеется, есть классы для чтения и записи файлов. Но, сегодня мы не будем их использовать. Помните, мы смотрели содержимое this при помощи window.console.log(this)
;. Дело в том, что если там покопаться, можно найти объект imns, внутри которого есть объект FIO, которые отвечает за файловый ввод-вывод, этот объект используется самим iMacros, например, когда вы в боковой панели сохраняете макрос или открываете его для редактирования.
Рассмотрим несколько необходимых нам методов у этого объекта:
imns.FIO.readTextFile(file)
— считывает текстовый файл и возвращает его содержимое
imns.FIO.writeTextFile(file, text)
— создает текстовый файл, если он не был создан и записывает в него текст
imns.FIO.appendTextFile(file, text)
— создает текстовый файл, если он не был создан, либо открывает существующий файл и в конец дописывает текст(удобно для записи логов и статистики в файлы)
Для работы с вводом-выводом обычно используется дескриптор файла, это своего рода указатель на файл, в нашем случае для его получения используется метод imns.FIO.openNode(pathFileName);
. Все функции выше в качестве параметра file принимают именно дескриптор файла а не строку с указанием пути к файлу.
Чтение txt-файла и быстрый доступ к любой строке
У текстового файла необязательно должно быть расширение «.txt», могут быть и любые другие. Давайте создадим маленький текстовый файл с несколькими ссылками и сохраним его в папку C:\BOTS\iMacros\.
links.txt
http://ya.ru http://google.com http://yahoo.com http://bing.com
Теперь напишем функцию, которая будет получать в качестве параметра путь к файлу а возвращать содержимое файла.
var loadFile = function (fileName) { var fileDescriptor = imns.FIO.openNode(fileName); return imns.FIO.readTextFile(fileDescriptor); } // Пример использования var text = loadFile("C:\\BOTS\\iMacros\\links.txt"); window.console.log(text); // Выводит содержимое файла
Обратите внимание, что при указании пути к файлу мы экранируем бэкслеши, поскольку это спецсимвол. Для Unix\Linux систем путь бы выглядел иначе, например "/var/imacros/links.txt"
, слеши поменяли свое направление и их экранировать не надо. Учтите эту разницу при написании кроссплатформенных скриптов под разные операционные системы.
Уже неплохо, но хотелось бы иметь удобный доступ к каждой строке и возможность проходиться по строкам в цикле. Для этого давайте преобразуем текст в массив, где каждый элемент массива — это отдельная строка. Еще, мы оставим возможность получать текст целиком. То есть, теперь наша функция будет возвращать не строку, а объект, содержащий в себе текст целиком и массив строк:
var loadFile = function (fileName) { var fileDescriptor = imns.FIO.openNode(fileName); var text = imns.FIO.readTextFile(fileDescriptor); return { text: text, strings: text.split('\r\n') // стандартные символы перевода каретки и новой строки в текстовых файлах }; } // Пример использования var content = loadFile("C:\\BOTS\\iMacros\\links.txt").text; window.console.log(content); // Выведет весь текст var strings = loadFile("C:\\BOTS\\iMacros\\links.txt").strings; // Массив строк window.console.log(strings.length); // 4 - Количество строк в файле window.console.log(strings[0]); // "http://ya.ru" - первая строка window.console.log(strings[3]); // "http://bing.com" - четвертая строка // По очереди заходим на каждый сайт из файла с промежутком в 5 секунд for (var i = 0; i < strings.length; i++) { iimPlayCode(` URL GOTO=${strings[i]} WAIT SECONDS=5 `); }
Посмотрите, что получилось, мы одной строкой загружаем файл в переменную и дальше можем делать с ним что угодно. Доступ к строкам по индексу — это удобно, но есть еще более крутой вариант, где доступ будет осуществляться не только по индексам, но и по ключам, я говорю про JSON. О нем напишу позже.
Запись текста в txt(текстовый файл)
Для записи текста в файлы, мы будем использовать все тот же объект iMacros — imns.FIO. Тут кода получится поменьше.
var saveToFile = function (fileName, text) { var fileDescriptor = imns.FIO.openNode(fileName); imns.FIO.writeTextFile(fileDescriptor, text); } // Пример использования saveToFile("C:\\BOTS\\iMacros\\text.txt", "текст для сохранения");
Данный код создаст файл text.txt и запишет туда наш текст. Если мы запустим макрос несколько раз, то все данные каждый раз будут перезаписываться новыми данными.
Добавление в конец текстового файла, пишем лог
Иногда бывает удобно просто дописывать в файл какие-либо данные, например при ведении логов. Давайте напишем функцию для добавления текста в конец любого файла и сделаем небольшую обертку для одновременной записи логов и в файл и в консоль. Плюс, мы будем автоматически проставлять дату и время для каждого сообщения.
var appendToFile = function (fileName, text) { var fileDescriptor = imns.FIO.openNode(fileName); imns.FIO.appendTextFile(fileDescriptor, text); } var log = function (msg) { // Добавляем дату и время в начало строки и добавляем перевод строки в конец var text = "[ " + new window.Date().toLocaleDateString() + " " + new window.Date().toLocaleTimeString() + "] " + msg + "\r\n"; // Записываем в файл и выводим в консоль appendToFile("C:\\BOTS\\iMacros\\log.txt", text); window.console.log(text); } // Пример использования log('Начинаем сбор с крана: nagibaka.ru...'); log('Собрано 500 сатоши(22 копейки)'); log('Поиск следующего крана...');
Если вы все правильно сделали, то у вас получится вот так:
Примечание: если у вас в консоли или в файле выводятся иероглифы, то нужно сохранить файл вашего скрипта в кодировке UTF-8 с BOM. Я использую Sublime Text 3 и для удобной работы с кодировками у меня установлен плагин Encoding Helper. В данном редакторе кодировка меняется из меню File.
На сегодня, думаю хватит. В следующих уроках мы разберем такие популярные форматы файлов, как CSV и JSON, научимся генерировать и читать файлы, следуя правилам этих форматов и конечно, напишем удобные функции для работы с ними.
круто! спасибо! а как брать данные из гугл таблиц? и туда же сыпать отчёт?
Брать:
request.open(«GET», «https://content-sheets.googleapis.com/v4/spreadsheets/ID Вашей таблицы/values/Лист1!A3:A40?key=Ваш ключ», false);
Сыпать:
request.open(«GET», «https://script.google.com/macros/s/ID Вашей таблицы/exec?col1=данные&col2=данные», false);
В Google Sheet принимаем данные:
function doGet(e) {
row = Номер строки;
var inputCol1 = ContentService.createTextOutput(JSON.stringify(e.parameter.col1)).getContent();
var inputCol2 = ContentService.createTextOutput(JSON.stringify(e.parameter.col2)).getContent();
sheet.getRange(row, 1).setValue(inputCol1);
sheet.getRange(row, 2).setValue(inputCol1);
}
И можно забыть про csv — файлы. )
И исходные данныи и результат в Google Sheet
Минусы данного метода:
— проблематично работать с данными в формате CSV (по сути с таблицами сохраненными в виде текста), при чтении файла подобной функцией;
— опять же, проблематично записать данные в виде таблицы (CSV-формат файла), для дальнейшей обработки в Excel’e;
Решением данных проблем может быть только дополнительный обработчик, приводящий текст к нужному виду, перед сохранением в файл или после чтения данных из файла
В десятом уроке уроке подробно разжевывается, как работать с CSV. Как преобразовывать в js-массив и обратно + сохранение. Проблем никаких нету, наоброт, мы можем работать с таблицей, как с нативным двумерным массивом и использовать полный функционал Javascript.
Думаю, вы имели ввиду 10 укор, а не 9.
Ок, суть моего коммента не противоречит ни уроку 9, ни 10.
Как уже написал выше, решением является написание отдельной функции преобразующей данные.
Не работает в Firefox:
Если пользуюсь appendToFile, то выводит ReferenceError: imns is not defined, line 30 (Error code: -991)
Доделал код из примера «как не надо делать» :)) но теперь всё работает.
В новой версии, с 9, (я так понял для поддержки многопроцессорности) исключили много возможностей из imacros, в том числе imns, обращение к window.console.
function saveToFile(savetext) {
var macro;
iimSet(«SAVETEXT», savetext);
macro = «CODE:»;
macro += «ADD !EXTRACT {{SAVETEXT}}»+»\n»;
macro += «SAVEAS TYPE=EXTRACT FOLDER=D:\\123 FILE=PaLBotLog.txt»;
iimPlay(macro)
}
var log = function (msg) {
var now = new Date();
var text = «[» + now + «] » + msg + «\r\n»;
saveToFile(text);
}
вот и нужна она эта многопроцессорность?
особенно если учесть, что кроме этого в 9 версии теперь не работают даже русскоязычные пути к файлам
А как быть c imns.FIO в iMacros 9? Может альтернативу кто подскажет
P.S. Мозилу даунгрейдить нельзя.
Виталий, альтернатива есть.
Например, попробуйте http://stackoverflow.com/questions/9667445/how-to-read-write-file-with-xul или погуглить «xul read file», «xul write file».
Пока нету времени, чтобы добавить решение в статью, но могу подсказать куда копать. Все функции в imns — это обертки, подобные тем, которые делаю я в данной статье. Если ваш уровень знаний позволит вам ковыряться в исходниках, то можете попробывать вытащить реализацию функций чтения и записи файлов.
В версии iMacros 8.9.7 открываете файл
utils.js
— у меня он находится тутC:\FirefoxPortable\Data\profile\extensions\{81BF1D23-5F17-408D-AC6B-BD6DF7CAF670}\modules\utils.js
.Функция для чтения из файла там выглядит вот так:
Но этого недостаточно, чтобы все заработало, нужно вытаскивать сопутствующие методы и функции + импортировать необходимые модули.
Спасибо, буду разбираться. С js только начинаю работать, пока многое не понятно. Если получится то, что задумал обязательно отпишусь.
Как зделать так чтоб данные в определённой колонке которые находятся в текстовом файле вставлялись в конец новой ссылки которая прописанна внутри сценария аймакроса
Отличные посты! Как рекомендация, у кого не работает: пространство imns не работает на последних версиях firefox и imacros. У меня заработало на firefox 46.01 и imacros 8.9.7 http download.imacros.net archive iMacros-Fx imacros_for_firefox-8.9.7-fx.xpi
Большое спасибо!
Подскажите, возможно ли решить: текст загружаю с дропбокса, сохраняю, в листере строки видны, а в notepad уже нет, склеены.
Поэтому ошибка can not parse macro line: m.facebook.com/natasha.kli…ko.3 (Error code: -910)
notepad или notepad++ ?
notepad не воспринимает перенос строк по \n только по \r\n, что, впрочем, ни как не мешает iMacros корректно обрабатывать такие строки!
Ошибка же, can not parse macro line говорит о некорректной строке в макросе, так что смотрите что вы там намудрили в коде, например, при вставке строки из файла в макрос
Файл сохраняется в utf 8, но нужно сохранять его в 1251, как это сделать?
UTF8 понимает любая программа, в том числе и excel, зачем вам windows 1251?
Если открыть CSV файл, то там кодировка 1251. Соответственно если сохраняю его в UTF8, то появляются проблемы с кирилицей.
К старым данным в файле csv в 1251 нужно добавить новые данные.
Если он создан не iMacros — возможно, пересохраните в UTF8, в чем сложность?
Помогло, спасибо. Может подскажите как заставить эксель сохранять csv в utf8?
http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=8&TID=12928
прямого решения — нет, есть обходные, со сторонним софтом
гугл по фразе «excel сохранить csv кодировка utf8» (прямая ссылка на премодерации)
Спасибо
Как сделать вход в вк с вашим скриптом
как проверить на существование файла?
А что проверка на ошибки уже не действует? Или лишь бы спросить, не думая?
При чтении файла — вернет результат с содержимым файла, при отсутствии файла вернет ошибку.
В чем сложность-то?
Здравствуйте. Вот у меня не работает этот код в консоле. Скачивал разные версии Mazilla вплоть до 28, везде выдает ошибку ReferenceError: imns is not defined [Подробнее]. Файл и папка существуют. В чем может быть проблема?
var loadFile = function (fileName) {
var fileDescriptor = imns.FIO.openNode(fileName);
return imns.FIO.readTextFile(fileDescriptor);
}
// Пример использования
var text = loadFile(«C:\\BOTS\\iMacros\\links.txt»);
window.console.log(text); // Выводит содержимое файла
Поиск по тексту ошибки в гугле?! Не?!
Обьявите что такое inns,iMacros не знает что это
В гугле вторая ссылка на аналогичную проблему на офф. форуме по imacros
Ссылок, не даю, тут они требуют премодерации
Опечатка (т9)
imns
Так я в консоле запускаю, а не в imacros. Должно window.console.log(text); // Выводить содержимое файла/ А она не выводит не чего.
Добавил
var wm = imns.Cc[«@mozilla.org/appshell/window-mediator;1»].getService(imns.Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow(«navigator:browser»);
Все равно консоль выдает ReferenceError: imns is not defined [Подробнее]
Обычный вопрос создаю скрипт по старой технологии все работает но скорость чтения и записи низкая , вы привели пример как реализовать для бастродействия. imns.FIO не могу на место где нужно вставить логин и пароль на почте чтобы вставлялись данные с таблицы старый метод работает {{!COL1}} и {{!COL2}} просто вставляю а как реализовать это с вашим методом
Я имею ввиду вы привели пример говнокода в начале статьи, только пример реализации этих же операций со входом на почту с новым методом не привели, было бы наглядней если вы бы это сделали заранее благодарю
а что включать голову и изучать js должен за вас автор статьи?
или вам еще и работу с текстом в js разжевать? так вон гугл есть, сотни ресурсов по js и уроки в том числе
Подскажите, как загрузить картинку? Нужно будет передать её через xmlhttprequest.
какая разница как реализован код. Главное что он работает! Все были новичками и новичкам так понятнее
Добра Вам.
Подскажите как в текстовый файл сохранить URL групп фейсбук и если скажем она меньше 300 чел то ее URL не вписывать в коец текстового файла. Тоесть я спрашиваю про парсер.
Спасибо, много полезного.
Вероятно от недостатка внимания, не могу найти
как сохранить в файл содержимое window.console.log( );
Последний в статье листинг, надеюсь заменить переменную на нужное вам, сами догадаетесь как
Спасибо, реализовал через вывод в Json, почти сразу после того, как задал вопрос. Надо было отписать.
Здравствуйте! При запуске этого кода, через некоторое время Mozilla начинает потреблять очень много ОЗУ до 2 Гб, комп начинает жестко тормозить:
var loadFile = function (fileName) {
var fileDescriptor = imns.FIO.openNode(fileName);
var text = imns.FIO.readTextFile(fileDescriptor);
return {
text: text,
strings: text.split(‘\r\n’) // стандартные символы перевода каретки и новой строки в текстовых файлах
};
}
var content = loadFile(«C:\\test\\insta.txt»).text;
for (var i = 0; i SECTION>MAIN>ARTICLE>HEADER>SECTION>DIV>SPAN>SPAN>BUTTON» BUTTON=0
WAIT SECONDS=30
`);
}
В файле C:\\test\\insta.txt у меня список ссылок на аккаунты инстаграмм.
Версия imacros 8.9.7, мозила 49
Подскажите пожалуйста, что можно сделать чтобы этот скрипт не потреблял много памяти?
strings: text.split(‘\r\n’) // стандартные символы перевода каретки и новой строки в текстовых файлах
};
}
Для линуксоидов не стоит забывать, что что там другой перевод строки
split(‘\n’)
Не выводит ничего.И почему маленькими буквами?
VERSION BUILD=9030808 RECORDER=FX
TAB T=1
TAB CLOSEALLOTHERS
var loadFile = function (fileName) {
var fileDescriptor = imns.FIO.openNode(fileName);
return imns.FIO.readTextFile(fileDescriptor);
}
// Пример использования
var text = loadFile(«C:\\1.txt»);
window.console.log(text); // Выводит содержимое файла
не выводит ни чего — кто/где?
тот код что вы привели?
так может сообщение об ошибке посмотрите к примеру?
основы почитаете за одно? или как по вашему должна работать смесь чистого imacros кода с js?
при чем тут маленькие буквы или нет? это вы собственно к чему писали? к вашему собственному коду?
iMacros’у как бы пофиг на регистр собственных команд если что
SET !DATASOURCE C:\iMacros\Macros\1.txt
‘берем данные из первой строки
ADD !EXTRACT {{!COL1}}
‘и подставляем где надо из файла {{!COL1}}
‘Так проще.
поставьте запятую в тексте, который у вас txt файле и посмотрите на результат, проще ли так?! =))
Добрый день!
А можно ли как-то в Вашем варианте кода прописывать относительный путь к файлам?
Конечно можно. Укажите путь и мы подправим.
Путь относительно самой папки Macros, которая находится в папке iMacros. Например хочу чтобы файл брался из папки Datasources, а сам макрос работал на любой машине. То есть путь нужен относительный.
Вытащите из настроек FF путь до папки Datasoucre и поставьте в ваш путь (работает если не стоит галка использовать папку плагина для этих файлов)
А можно подробнее?
var mdt=Components.classes[‘@mozilla.org/preferences-service;1’].getService(Components.interfaces.nsIPrefBranch).getCharPref(‘extensions.imacros.defdatapath’);
var mdw=Components.classes[‘@mozilla.org/preferences-service;1’].getService(Components.interfaces.nsIPrefBranch).getCharPref(‘extensions.imacros.defdownpath’);
кавычки только замените на нормальные, местный парсер их заменяет
СПАСИБО!!!! Буду пробовать!
Хоть я уже сделала так:
ADD !EXTRACT {{!FOLDER_DATASOURCE}}
Нормально работает))))
Я не стал приводить этот способ, т.к. он работает не во всех версиях iMacros, в старых, например, нет переменной с этим путем
Парни, а как удалить из файла текст. Например, скрипт забирает из селектора текст и при условии если этот текст встречается в другом селекторе то удалить его из файла?
Перезаписать файл с нуля без этого текста
Языков программирования не знаю,наткнулся на imacros,типа запиши действия и ок)))Ага,оказалось еще пиши ручками,ладно, были бы примеры…оказалось он и сохранять с заменой содержимого не умеет,еще и кавычки тыкает(не то чтобы..немного раздражает))Потыкался….вроде бы через js можно сохранять.Ёлы-палы этого еще не хватало…эх,была не была,глаза боятся руки делают.По нету полазил,чё-то примеров не нахожу,все через SAVEAS и DELET и вооот нагибака!!!Теперь все ок парсит по xpatch и сохраняет в .txt с заменой содержимого и без кавычек.что я и хотел.Спасибо!Осталось зациклить и автозагрузку.