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

How can I save all href values from list items to a text file with iMacros?

我是 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

我收到一个错误框

我也尝试过修改 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,+ 在“简约”Implementations/Scripts 中发布 2 个(实际上是 3 个)不同的 Solutions/Implementations,我会提到几个 Concepts/Techniques我不会(深入)解释,否则我需要引用 iMacros 论坛的 Wiki and/or 的一半...
(我用单引号或反引号括起来的术语就是这样的术语...)


关于“循环”和“播放”的警告弹出窗口:
好吧,阅读那个 Popup 上的 Msg,它看起来很清楚,对我来说不言自明...
(嗯,除了里面丑陋的Typo,当然...!)


EXTRACTSAVEAS中获取#EANF#
=> 是的,正常,那是因为您使用 UL 元素作为 'Anchor' 用于 'Relative Positioning',在这种情况下您需要使用 'Double Relative Positioning' 作为 UL 元素实际上是所有 LI + A 元素的 'Container'...
(更多解释 on the Forum,我已经在其中多次解释 Concept/Technique...)
嗯,Linking好像不行...,这里是Link:
https://forum.imacros.net/search.php?keywords=Double+Relative+Positioning


The number of list items can be different so I cannot use a loop of a known number of iterations...
(Emphasis mine...)

嗯,好吧...,这不是真的,在我看来这实际上是“最简单”的实施方式...,因为它的优势在于您可以让 SAVEAS注意为每个循环将每个 Link 保存在 separate/new 行上,(或者您需要 add/implement 自己为该函数创建一个机制...),您可以简单地让如果“未找到”元素,iMacros 会“自然地”中止您的脚本,例如当没有新的 Link 可提取时...
...我将为该部分使用 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>*

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

  • 注意,我不使用 !ERRORIGNORE,而 Abort Func 实际上依赖于它...
  • 在“Links”(A 元素)上提取和循环时,我“切换回”第二个 LI 元素 R-POS中止脚本,就好像我还使用了下一个 Link,EXTRACT 命令永远不会中止脚本(按设计),它只会 return #EANF# 如果未找到元素,如果没有 EXTRACT,脚本将单击并遵循所有先前循环的 Links。
  • !EXTRACT_TEST_POPUP循环脚本时可以省略...
  • “最佳”页面已经“手动”加载一次,或者在每个循环中重新加载页面会减慢执行速度...如果页面“真的”需要从脚本加载,则可以为 'Conditional URL GOTO' 添加一个机制(另一个“Concept/Technique”来搜索 iMacros 论坛,啊-啊...!)只为 Loop=1...[= 加载页面141=]

实施 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)

(mini-Report的内容当然可以自定义...,也可以保存到单独的'.log'文件中...)


实现3:从包含UL的元素中提取所有具有1个EXTRACTLI元素:

这是一个“快速而肮脏”的演示,因为我发现它的实现有点麻烦,但是现在开始...:[=​​63=]

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 Links...
更简洁的方法是使用 for 循环直到 x.length/2 (Incr=2),使用 Array.push(),但这只是一个快速而肮脏的演示,其中重新创建 y String/Array 将需要被“硬编码”30 或 50 次...

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

(脚本只需要 运行 x1 次,=> 使用 'Play' 按钮,而不是 'Loop' 按钮。)

嗯,我应该提到,对于这个实现,实际上是“推荐”“刷新”-加载(或重新加载)页面(=> 使用 URL GOTO 我已经(重新)激活了这个脚本),当然不要在“the”脚本 运行 之前在该页面上“播放”iMacros,否则 iMacros(录制或重播)将在页面的 HTML 结构中注入一些样式, => 在我的“提取:”部分中可见 UL 元素和前 2 个 LI 元素的 style="outline: 1px solid blue;"...
“问题”是这个 style extra-Attribute 每次都包含 (2) 个双引号,但我实际上是基于 EVAL() 中的 split() 之一基于这个双引号字符 (") 来隔离 HREF 值,或者 x[1]/x[3]/x[5]/等将从数组中转移到 (Start)Index 的更高值...而且Increment也会一起变化...