如何使用 iMacros 将列表项中的所有 href 值保存到文本文件中?

问题描述

我是 imacros 的新手,但安装了 12.0.501.6698 版本的 Windows 10 Pro 20H2 - OS Build 19042.1110。

我试图从页面的 html 中提取位于多个列表项中的所有 href 值。然后将这些 URL 保存到一个文本文件中。

列表项的数量可以不同,所以我不能使用已知迭代次数的循环;我必须获取所有列表项并提取 href 属性值。

HTML代码格式示例

<ul class="bullet-list columns-2 columns--regular">
<li><a href="/search/agents/results.htm?location=ampthill" >Estate Agents in Ampthill</a></li>
<li><a href="/search/agents/results.htm?location=barton_le_clay" >Estate Agents in Barton-Le-Clay</a></li>
<li><a href="/search/agents/results.htm?location=bedford" >Estate Agents in bedford</a></li>
<li><a href="/search/agents/results.htm?location=biggleswade" >Estate Agents in Biggleswade</a></li>
<li><a href="/search/agents/results.htm?location=bromham" >Estate Agents in bromham</a></li>
<li><a href="/search/agents/results.htm?location=clapham_beds" >Estate Agents in clapham</a></li>
</ul>

我看过类似文章中的代码,例如 - iMacros: Extract ID attribute from a ul li list

这是我在 imacros 中尝试过的代码

VERSION BUILD=12.0.501.6698
TAB T=1
SET !ERRORIGnorE YES
SET !EXTRACT_TEST_POPUP NO
TAB CLOSEALLOTHERS
'SET !PLAYBACKDELAY 0.00
URL GOTO=https://www.home.co.uk/search/agents/?county=beds

TAG POS=1 TYPE=UL ATTR=ID:bullet-list EXTRACT=LI
TAG POS=R{{!LOOP}} TYPE=A ATTR=ID:* EXTRACT=HREF
SAVEAS TYPE=EXTRACT FOLDER=* FILE=c:\Development\towns.txt

我收到一个错误

enter image description here

我还尝试修改 TYPE 值和要提取内容的所有排列。

应该在这一行中存储来自 href 属性的 URL 的文本文件

<li><a href="/search/agents/results.htm?location=clapham_beds" >Estate Agents in clapham</a></li>

只包含一行 #EANF# 而不是“/search/agents/results.htm?location=clapham_beds”

解决方法

iMacros 论坛上的并行线程(由我打开...,因为我真的不信任该站点的“连续性”...):

[答案现在或多或少“完成”,但我可能仍然“稍微”编辑它...]

[编写此答案所花费的时间:大约 [10] 小时...]...
=> 论坛发帖:大约 2 小时,编写脚本和测试:……剩下的,啊-啊……!
(我第一次花这么多时间在答案上,不得不与网站的“设计”“抗争”很烦人......)


以相反的顺序或多或少地解决所有不同的 Qt,+ 在“简约”实现/脚本中发布 2 个(或实际上 3 个)不同的解决方案/实现,我将提到几个我不会解释的概念/技术(在深度)或者我需要引用一半的 Wiki 和/或 iMacros 论坛...
(我用单引号或反引号括起来的术语就是这样的术语……)


关于“循环”和“播放”的警告弹出窗口:
好吧,阅读该弹出窗口上的消息,对我来说它看起来非常清晰且不言自明...
(嗯,当然,除了里面丑陋的错别字……!)


#EANF#EXTRACT 中获取 SAVEAS
=> 是的,正常,那是因为您使用 UL 元素作为“相对定位”的“锚点”,在这种情况下,您需要使用“双重相对定位”,因为 UL 元素是实际上是所有 LI + A 元素的“容器”...
(更多解释on the Forum,我已经多次解释了概念/技术......)
嗯,链接似乎不起作用...,这是链接:
https://forum.imacros.net/search.php?keywords=Double+Relative+Positioning


列表项的数量可以不同所以我不能使用已知迭代次数的循环...
(强调我的...)

嗯,嗯...,这不是真的,这实际上是我认为“最简单”的实现...,因为这将具有优势,您可以让 SAVEAS 照顾好将每个链接保存在每个循环的单独/新行上,(或者您需要为该功能添加/实现自己的机制......),并且您可以简单地让 iMacros“自然地”中止您的脚本,如果一个元素是“未找到”,就像没有新的链接可以提取...
...我将在该部分使用 2 种不同的机制...

(所有脚本均在 iMacros for FF v8.8.2,PM v26.3.3,Win10_PRO_x64_21H1 中编写和测试。)


实现 1:在 Not Found 上循环 + 中止:

这会给 stg 像:

VERSION BUILD=8820413 RECORDER=FX
TAB T=1

SET Search_Keyword "Estate Agents"

'Debug:
'SET !LOOP 15

'URL GOTO=https://www.home.co.uk/search/agents/?county=beds

'Extract Links using 'Relative Positioning':
'TAG POS=1 TYPE=H1 ATTR=TXT:Estate<SP>Agents<SP>in<SP>Bedfordshire  //  (Recorded)
TAG POS=1 TYPE=H1 ATTR=TXT:{{Search_Keyword}}<SP>in<SP>*
TAG POS=R{{!LOOP}} TYPE=A ATTR=TXT:{{Search_Keyword}}<SP>in<SP>* EXTRACT=HREF
'>
'Debug:
'PROMPT {{!EXTRACT}}

'Save Link to '.CSV' (or '.TXT'):
SAVEAS TYPE=EXTRACT FOLDER=* FILE=c:\Development\towns.txt
'SAVEAS TYPE=EXTRACT FOLDER=* FILE=SOF_MSB.txt

'Abort Script if no more Link(s) to extract:
SET !TIMEOUT_STEP 1
TAG POS=R1 TYPE=LI ATTR=TXT:{{Search_Keyword}}<SP>in<SP>*

是的,好的,这个已经可以使用了...
提供 URL 的页面上的 21 个链接,我循环脚本 30 次,它在 Loop=21 结束时自行中止...!

  • 注意,我不使用 !ERRORIGNORE,而 Abort Func 实际上依赖于它...
  • 在提取和循环“链接”(A 元素)时,我“切换回”到第二个 LIR-POS 元素以中止脚本,就像我还使用了下一个链接,EXTRACT 命令从不中止脚本(按设计),如果未找到该元素,它将简单地返回 #EANF#,并且没有 EXTRACT,然后脚本将单击并遵循所有先前循环的链接。
  • 循环脚本时可以省略 !EXTRACT_TEST_POPUP...
  • 在页面已经“手动”加载一次的情况下“最好”工作,或者在每个循环上重新加载页面会减慢执行速度......如果页面“真的”需要从脚本加载,则可以添加一个“条件 URL GOTO”(在 iMacros 论坛中搜索的另一种“概念/技术”,啊-啊...!)的机制,用于仅为 Loop=1...
  • 加载页面

实现 2:循环 + 使用 MacroError() 中止 + 报告:

好吧……,这将是我的“最爱”……!:
与 Script_1 相同,但可以应用于 A 元素以中止脚本并使用 MacroError() 允许在 iMacros 侧面板中显示一些迷你报告,例如:

VERSION BUILD=8820413 RECORDER=FX
TAB T=1

SET Search_Keyword "Estate Agents"

'Debug:
'SET !LOOP 15

'URL GOTO=https://www.home.co.uk/search/agents/?county=beds

'Extract Links using 'Relative Positioning':
'TAG POS=1 TYPE=H1 ATTR=TXT:Estate<SP>Agents<SP>in<SP>Bedfordshire  //  (Recorded)
TAG POS=1 TYPE=H1 ATTR=TXT:{{Search_Keyword}}<SP>in<SP>* EXTRACT=TXT
SET Title {{!EXTRACT}}
SET !EXTRACT NULL
TAG POS=R{{!LOOP}} TYPE=A ATTR=TXT:{{Search_Keyword}}<SP>in<SP>* EXTRACT=HREF
'>
'Debug:
'PROMPT {{!EXTRACT}}

'Save Link to '.CSV' (or '.TXT'):
'SAVEAS TYPE=EXTRACT FOLDER=* FILE=c:\Development\towns.txt
SAVEAS TYPE=EXTRACT FOLDER=* FILE=SOF_MSB.txt

'Abort Script if no more Link(s) to extract:
SET !TIMEOUT_STEP 1
SET !EXTRACT NULL
'TAG POS=R1 TYPE=LI ATTR=TXT:{{Search_Keyword}}<SP>in<SP>*
TAG POS=R1 TYPE=A ATTR=TXT:{{Search_Keyword}}<SP>in<SP>* EXTRACT=TXT

'Prepare mini-Report:
SET Report {{!LOOP}}<SP>Links<SP>extracted<SP>for:<BR>{{Title}}
SET Summary (No<SP>Error...!!)<SP>({{!NOW:yyyy-mm-dd<SP>hhhnn}})<BR><BR>{{Report}}<BR><BR>

SET !ERRORIGNORE NO
SET Abort_Report EVAL("var s='{{!EXTRACT}}'; if(s=='#EANF#'){MacroError(\"{{Summary}}\");}")
SET !ERRORIGNORE YES

像 Script_1,=> 循环了 30 或 50 次,将显示:

MacroError: (No Error...!!) (2021-07-22 15h57)

21 Links extracted for:
Estate Agents in Bedfordshire,line 36 (Error code: -1340)

(小报表的内容当然可以自定义...,也可以保存到一些单独的'.log'文件...)


实现 3:从包含 LI 元素中提取所有具有 1 EXTRACTUL 元素:

这是一个“快速而肮脏”的演示,因为我觉得它的实现有点麻烦,但是你去...:

VERSION BUILD=8820413 RECORDER=FX
TAB T=1

SET Search_Keyword "Estate Agents"

URL GOTO=https://www.home.co.uk/search/agents/?county=beds

'TAG POS=1 TYPE=LI ATTR=TXT:Estate<SP>Agents<SP>in<SP>Ampthill
'TAG POS=1 TYPE=LI ATTR=TXT:Estate<SP>Agents<SP>in<SP>Barton-Le-Clay
'TAG POS=1 TYPE=DIV ATTR=TXT:Estate<SP>agent<SP>listings<SP>are<SP>available<SP>for<SP>th* EXTRACT=HTM

'TAG POS=1 TYPE=P ATTR=TXT:Estate<SP>agent<SP>listings<SP>are<SP>available*
'TAG POS=R1 TYPE=UL ATTR=* EXTRACT=HTM

'Hum,can better use the 'H1' Element as Anchor...:
'TAG POS=1 TYPE=H1 ATTR=TXT:Estate<SP>Agents<SP>in<SP>Bedfordshire  //  (Recorded)
TAG POS=1 TYPE=H1 ATTR=TXT:{{Search_Keyword}}<SP>in<SP>*
TAG POS=R1 TYPE=UL ATTR=* EXTRACT=HTM

SET Results_HREF EVAL("var s='{{!EXTRACT}}'; var w,x,y,z; w=s.split('regular\">')[1]; x=w.split('\"'); y=x[1]+','+x[3]+','+x[5]; z=y.split(',').join('\\r\\n'); z;")
'>
'Debug:
PROMPT Results:<BR><BR>_{{Results_HREF}}_

'Not really finished... (Quick and dirty Demo...)

'Save Links to '.CSV' (or '.TXT':
'SAVEAS TYPE=EXTRACT FOLDER=* FILE=c:\Development\towns.txt

'>>>

'Extracted:
'<ul style="outline: 1px solid blue;" class="bullet-list columns-2 columns--regular"> 
'<li style="outline: 1px solid blue;"><a href="/search/agents/results.htm?location=ampthill">Estate Agents in Ampthill</a></li> 
'<li style="outline: 1px solid blue;"><a href="/search/agents/results.htm?location=barton_le_clay">Estate Agents in Barton-Le-Clay</a></li> 
'<li><a href="/search/agents/results.htm?location=bedford">Estate Agents in Bedford</a></li> 
'<li><a href="/search/agents/results.htm?location=biggleswade">Estate Agents in Biggleswade</a></li> 
'<li><a href="/search/agents/results.htm?location=bromham">Estate Agents in Bromham</a></li> 
'<li><a href="/search/agents/results.htm?location=clapham_beds">Estate Agents in Clapham</a></li> <li><a href="/search/agents/results.htm?location=dunstable">Estate Agents in Dunstable</a></li> <li><a href="/search/agents/results.htm?location=flitwick">Estate Agents in Flitwick</a></li> <li><a href="/search/agents/results.htm?location=harlington">Estate Agents in Harlington</a></li> <li><a href="/search/agents/results.htm?location=henlow">Estate Agents in Henlow</a></li> <li><a href="/search/agents/results.htm?location=houghton_regis">Estate Agents in Houghton Regis</a></li> <li><a href="/search/agents/results.htm?location=kempston">Estate Agents in Kempston</a></li> <li><a href="/search/agents/results.htm?location=langford">Estate Agents in Langford</a></li> <li><a href="/search/agents/results.htm?location=leighton_buzzard">Estate Agents in Leighton Buzzard</a></li> <li><a href="/search/agents/results.htm?location=linslade">Estate Agents in Linslade</a></li> <li><a href="/search/agents/results.htm?location=luton">Estate Agents in Luton</a></li> <li><a href="/search/agents/results.htm?location=potton">Estate Agents in Potton</a></li> <li><a href="/search/agents/results.htm?location=sandy">Estate Agents in Sandy</a></li> <li><a href="/search/agents/results.htm?location=shefford">Estate Agents in Shefford</a></li> <li><a href="/search/agents/results.htm?location=stotfold">Estate Agents in Stotfold</a></li> 
'<li><a href="/search/agents/results.htm?location=toddington">Estate Agents in Toddington</a></li> </ul>

关于脚本,这是一个“快速而肮脏”的解决方案,关于 y 部分,仅演示前 3 个链接...
更简洁的方法是使用 for 循环直到 x.length/2 (Incr=2),带有 Array.push(),但这只是一个快速而肮脏的演示,其中重新创建了 y 字符串/Array 需要“硬编码”30 或 50 次...

=> 查看调试内容 PROMPT...

(脚本只需要运行 x1 次,=> 使用“播放”按钮,而不是“循环”按钮。)

嗯,我应该提到,对于此实现,实际上“建议”“刷新”加载(或重新加载)我在此脚本中(重新)激活的页面(=> with URL GOTO ),并且当然不要在“脚本”运行之前在该页面上“播放”iMacros,否则 iMacros(录制或重播)将在页面的 HTML 结构中注入一些样式,=> 就像在我的“提取: " 部分带有 style="outline: 1px solid blue;"UL 元素和前 2 个 LI 元素...
“问题”是这个 style 额外属性每次都包含 (2) 个双引号,但我实际上基于 split() 中的 EVAL() 之一基于这个非常双引号字符 ({ {1}}) 以隔离 " 值,否则 HREF/x[1]/x[3]/etc 将从数组中转移到(起始)索引的更高值......而且增量也会一起改变......