iMacros:使用带有 EVAL 的 Javascript 替换变量中的文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10465153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iMacros: Using Javascript with EVAL to replace text in a variable
提问by Olivier Compagne
I'm using iMacros on Firefox to download my Wells Fargo PDF bank statements automatically, and give the files the name of the link, like "Statement 04/22/12 (597K)"
我在 Firefox 上使用 iMacros 自动下载我的 Wells Fargo PDF 银行对账单,并为文件指定链接名称,例如“ Statement 04/22/12 (597K)”
However, I can't have slashes in the file name (Windows restriction...). So I'm trying to replace the forward slashesby a dash.
但是,文件名中不能有斜杠(Windows 限制...)。所以我想,以取代正斜杠由破折号。
Here is my iMacro below. I get an error code on the following line:
下面是我的 iMacro。我在以下行收到错误代码:
SET !VAR1 EVAL("var s=\"{{!EXTRACT}}\"; s.replace(/\//g, "-");")
My javascript or my Regex doesn't work, and I don't know why. I'm not strong in either language - I've tried to copy from other examples as best as I could, but with no success. If you can help, that'd be great. Thanks.
我的 javascript 或我的 Regex 不起作用,我不知道为什么。我对这两种语言都不擅长 - 我试图尽可能地从其他例子中复制,但没有成功。如果你能帮忙,那就太好了。谢谢。
VERSION BUILD=5010424 RECORDER=CR
' SET !ERRORIGNORE YES
TAB OPEN
TAB T=2
URL GOTO=https://online.wellsfargo.com/login
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:Signon ATTR=ID:username CONTENT=XXX
SET !ENCRYPTION TMPKEY
TAG POS=1 TYPE=INPUT:PASSWORD FORM=ID:Signon ATTR=ID:password CONTENT=XXX
TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:Signon ATTR=NAME:continue&&VALUE:Sign<SP>On
TAG POS=1 TYPE=A ATTR=TXT:View<SP>online<SP>statements
SET !EXTRACT_TEST_POPUP NO
TAG POS=1 TYPE=A ATTR=TXT:Statement<SP>* EXTRACT=TXT
SET !VAR1 EVAL("var s=\"{{!EXTRACT}}\"; s.replace(/\//g, "-");") <---- THIS IS THE PROBLEMATIC LINE!!!!!!!!!!!!!!
ONDOWNLOAD FOLDER=D:\Wells<SP>Fargo\CREDIT<SP>CARD\ FILE={{!VAR1}}.pdf
TAG POS=1 TYPE=A ATTR=TXT:Statement<SP>* CONTENT=EVENT:SAVETARGETAS
TAB CLOSE
As an extra, if you know how to remove the "(597K)" with Regex in the javascript, that'd be the icing on the cake. (obviously, the value of this text string will be different for each different file, so it has to be dynamic)
另外,如果您知道如何在 javascript 中使用 Regex删除“ (597K)”,那将是锦上添花。(很明显,这个文本字符串的值对于每个不同的文件都会不同,所以它必须是动态的)
回答by bobince
You missed escaping the quotes in "-"
, so ended the iMacros string instead of starting a JavaScript string.
你错过了转义 中的引号"-"
,所以结束了 iMacros 字符串而不是开始一个 JavaScript 字符串。
You've also potentially got a problem in the /\//
regexp, because I suspect iMacros will eat the \/
and turn it into /
, leaving JS with the invalid literal ///
. It would have to be /\\//
.
您还可能在正则/\//
表达式中遇到问题,因为我怀疑 iMacros 会吃掉\/
并将其变成/
,从而使 JS 具有无效的文字///
。它必须是/\\//
。
Also, if the !EXTRACT
variable contains quotes, backslashes, or newlines, it will inject those into the JavaScript code directly, breaking the JS string literal and potentially executing arbitrary script.
此外,如果!EXTRACT
变量包含引号、反斜杠或换行符,它将直接将它们注入 JavaScript 代码,破坏 JS 字符串文字并可能执行任意脚本。
These are examples of the many problems with nested escaping contexts. You can avoid the first two by using alternate non-clashing quotes, and getting rid of the regex literal by using the simple string replace split
/join
idiom instead:
这些是嵌套转义上下文的许多问题的示例。您可以通过使用备用的非冲突引号来避免前两个,并通过使用简单的字符串替换split
/join
成语来摆脱正则表达式文字:
SET !VAR1 EVAL("'{{!EXTRACT}}'.split('/').join('-').split(' (')[0]")
but this still leaves the JS injection problem. From a quick look at the manual, it seems iMacros doesn't have any usable string processing functionality, so you wouldn't be able to do a manual JS-string-literal-replace, or indeed just do the /
-to-
replacement from within iMacros. That would have been the sensible thing to do; creating executable code from strings is almost always a disastrously wrong thing to strenuously avoid.
但这仍然留下了JS注入问题。快速查看手册,似乎 iMacros 没有任何可用的字符串处理功能,因此您将无法手动执行 JS-string-literal-replace,或者实际上只是从内部执行/
-to-
替换iMacros。那将是明智的做法;从字符串创建可执行代码几乎总是要极力避免的灾难性错误。
[aside rant: From that look at the manual, the existence of iMacros makes me genuinely unhappy. It's offering you a completely arbitrary yet incapable homebrew scripting language instead of just using the already-available JavaScript, then making you go to JS anyway to do anything beyond the laughably trivial... and not giving you tools to transfer values between the two safely. What is even the point of this software? I haven't felt this frustrated with trying to work around wrong-headed language design since the dark days of 4GLs. This is just awful. People use this?]
[旁白:从手册上看,iMacros 的存在让我真的很不高兴。它为您提供了一种完全任意但无能的自制脚本语言,而不仅仅是使用已经可用的 JavaScript,然后让您无论如何都要使用 JS 来做任何超出可笑微不足道的事情……并且没有为您提供工具来安全地在两者之间传输值. 这个软件的意义何在?自从 4GL 的黑暗时代以来,我并没有因为试图解决错误的语言设计而感到沮丧。这太可怕了。人用这个?】
回答by Noah
Your task, like most non-trivial scraping problems can be solved much easier using javascript to organize your imacros code
您的任务,就像大多数非平凡的抓取问题一样,可以使用 javascript 来组织您的 imacros 代码更容易解决
Take a look at this example. I don't use Wells Fargo so I can't test the actual downloading but the basic skeleton is there
看看这个例子。我不使用 Wells Fargo,所以我无法测试实际下载,但基本框架在那里
run()
function run() {
// loginResult is null on success
var loginError = performLogin()
if (loginError) {
alert(JSON.stringify(loginError, null, ' '))
throw new Error(JSON.stringify(loginError))
}
// loginResult is null on success
var extractError = extractStatement()
if (extractError) {
alert(JSON.stringify(extractError, null, ' '))
throw new Error(JSON.stringify(extractError))
}
iimDisplay('Download completed successfully')
}
/**
* @return null on success, error object on failure
*/
function extractStatement() {
var error,
code,
extract
code = iimPlay('CODE: TAG POS=1 TYPE=A ATTR=TXT:View<SP>online<SP>statements\n'
+ 'TAG POS=1 TYPE=A ATTR=TXT:Statement<SP>* EXTRACT=TXT')
if (code !== 1) {
error = {
message: 'error extracting statement',
error: iimGetLastError(),
errorCode: code
}
}
extract = iimGetLastExtract()
// #EANF# means Extract Anchor Not Found (ie extract failed)
if (extract === '#EANF#') {
error = {
message: 'error extracting statement',
error: 'extract not found'
}
}
// the magic line to replace all slashes
var filename = extract.replace(/\//g, '-')
// add the .pdf extension
filename = filename + '.pdf'
// download with the new filename, the double slashes are needed because
// javascrtip otherwise views a backslash as an escape character
var folderPath = 'D:\Wells<SP>Fargo\CREDIT<SP>CARD\'
var downloadCode = iimPlay('CODE: ONDOWNLOAD FOLDER=' +folderPath + ' FILE=' + filename + '\n'
+ 'TAG POS=1 TYPE=A ATTR=TXT:Statement<SP>* CONTENT=EVENT:SAVETARGETAS\n'
+ 'TAB CLOSE')
if (downloadCode !== 1) {
error = {
message: 'failed to download statement',
error: iimGetLastError(),
errorCode: downloadCode
}
return error
}
// download completed correctly
return null
}
/**
* @return null on success, error object on failure
*/
function performLogin() {
var code = iimPlay('CODE: TAB OPEN\n'
+ 'TAB T=2\n'
+ 'URL GOTO=https://online.wellsfargo.com/login\n'
+ 'TAG POS=1 TYPE=INPUT:TEXT FORM=ID:Signon ATTR=ID:username CONTENT=XXX\n'
+ 'SET !ENCRYPTION TMPKEY\n'
+ 'TAG POS=1 TYPE=INPUT:PASSWORD FORM=ID:Signon ATTR=ID:password CONTENT=XXX\n'
+ 'TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:Signon ATTR=NAME:continue&&VALUE:Sign<SP>On\n')
// code will be 1 on success
if (code === 1) {
return null
}
var error = {
message: 'error performing login',
error: iimGetLastError(),
errorCode: code
}
}