我在Firefox上使用iMacros自动下载我的Wells Fargo PDF银行对帐单,并为文件指定链接名称,例如“声明04/22/12(597K)”< / p>
但是,我不能在文件名中添加斜杠(Windows限制...)。所以我试图用破折号替换正斜杠。
下面是我的iMacro。我在以下行中收到错误代码:
SET !VAR1 EVAL("var s=\"{{!EXTRACT}}\"; s.replace(/\//g, "-");")
我的javascript或我的正则表达式不起作用,我不知道为什么。我用这两种语言都不强 - 我试图尽可能地从其他例子中复制,但没有成功。如果你能提供帮助,那就太好了。感谢。
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
另外,如果您知道如何在javascript中删除带有Regex的“(597K)”,那将是锦上添花。 (显然,这个文本字符串的值对于每个不同的文件都是不同的,所以它必须是动态的)
答案 0 :(得分:1)
您错过了"-"
中的引号,因此结束了iMacros字符串而不是启动JavaScript字符串。
你也可能在/\//
regexp中遇到问题,因为我怀疑iMacros会吃\/
并将其转换为/
,而JS会使用无效的文字{{} 1}}。它必须是///
。
此外,如果/\\//
变量包含引号,反斜杠或换行符,它会直接将这些内容注入JavaScript代码中,从而破坏JS字符串文字并可能执行任意脚本。
这些是嵌套转义上下文的许多问题的示例。您可以通过使用备用非冲突引号来避免前两个,并通过使用简单字符串替换!EXTRACT
/ split
惯用来删除正则表达式文字:
join
但这仍然存在JS注入问题。从快速查看手册,似乎iMacros没有任何可用的字符串处理功能,因此您将无法进行手动JS-string-literal-replace,或者只是执行SET !VAR1 EVAL("'{{!EXTRACT}}'.split('/').join('-').split(' (')[0]")
从iMacros中替换/
。那将是明智的做法;从字符串创建可执行代码几乎总是一种极其错误的东西,以便极力避免。
[除了咆哮:从手册上看,iMacros的存在让我真的很不高兴。它为您提供了一个完全随意但无法使用的自制脚本语言,而不仅仅是使用已经可用的JavaScript,然后让你去JS,除了可笑的琐碎之外做任何事情......并没有给你工具来安全地传递两者之间的价值。这个软件的重点是什么?自从4GL的黑暗日子以来,我一直没有感到因为试图解决错误的语言设计而感到沮丧。这太可怕了。人们用这个吗?]
答案 1 :(得分:1)
使用javascript整理你的imacros代码可以更轻松地解决你的任务,就像大多数非平凡的抓取问题一样
看看这个例子。我不使用富国银行,所以我无法测试实际的下载,但基本的骨架就在那里
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
}
}