如何自动保存网页?

时间:2019-01-03 09:46:49

标签: selenium automation macros wget imacros

我需要以浏览器称为“另存为,完成”的样式来存档数百个网页,这意味着它们会保存该页面本身的HTML文件以及一个充满其他文件的文件夹,这些文件夹需要正确呈现该页面,例如作为CSS,JS和图像文件。这样一来,您就可以离线查看页面,就像在线显示时一样。

这是我尝试过的方法以及每个方法的问题:

  • Firefox中的手动过程

    • 在下一页的链接上,右键单击。在“保存链接位置”中键入“ A”,以将目标URL复制到剪贴板。
    • 单击链接转到页面。
    • 为“将页面另存为”键入“ Alt-F-A”。如果尚未选择,请将“另存为类型”设置为“完整的网页”。
    • 如果尚不存在,请将光标置于“文件名”中。键入“ Ctrl-Insert”以粘贴剪贴板,其中包含当前页面的URL。
    • 将光标移到URL的末尾,然后将其移回直到到达最后一个“ /”。从左侧选择,以选择URL的路径部分。
    • 按“删除”以从URL中删除路径,仅保留文件名。
    • 按键盘上的Enter键或对话框中的“确定”。
    • 页面已保存。单击下一页的链接,重复此过程。 (这假设每个页面都有一个“下一步”链接,这对我正在归档的页面是正确的。如果不正确,那么将有一个附加步骤,返回到包含所有链接列表的页面,然后单击那里的下一个。)

    一遍又一遍,这很繁琐。这是我要自动化的过程。

  • iMacros。这种重复性任务正是宏的用途。我以前在网络浏览器中使用过iMacros来完成类似的任务,但是很长一段时间都没有使用过。我重新安装了它,弄清楚了如何再次使用它,并编写了一个单行或两行宏来保存当前页面及其URL的文件名。然后,当我尝试运行它时,iMacros通知我SaveAs命令在免费版本中不可用,我需要升级到100美元版本(具有30天免费试用)才能获得该功能。 。在当前版本的软件中,我没有留下深刻的印象,发现它笨拙且文档记录不充分。所以我更愿意寻找另一种解决方案。

  • Wget。这很酷。 Wikipedia将其描述为“一种从Web服务器检索内容的计算机程序”。这对我来说是新的,花了一段时间才弄清楚。它主要被标为Unix程序,也可用于Windows,它只是一个很小的可执行文件,不需要安装。我学到了足够多的知识,可以下载一些测试页面,但是当我进入需要存档的页面时,该页面就无法工作了。我已发送有关该问题的e-mail to the Wget mailing list,并等待我是否可以在一些帮助下解决。 (链接的电子邮件具有我使用的Wget命令行,包括我要存档的页面的URL,以及该页面看起来像是在线的并由Wget保存后的附件图像文件。)

    编辑:超过一个星期后,Wget邮件列表上没有任何回复。

  • Selenium。尽管是doesn't say it's for building macros, but "test cases.",但它看起来比iMacros高得多的质量。所以我尝试了。但是我发现它没有记录我在上面 Firefox中的手动过程下的过程中需要做的所有事情。例如,当我右键单击链接并键入“ A”以存储链接的URL时,Selenium并未向正在记录的算法添加任何内容。链接之后,当我保存页面时,Selenium再次没有执行任何操作。因此,尽管它看起来像是优质软件,但它似乎并没有我需要的功能,除非我误会了某些东西。

所以我很困惑。我不会进行数百次手动处理。所以我需要找到一种自动化的方法。我该怎么办?

2 个答案:

答案 0 :(得分:1)

WGet是用于下载网站的非常好且非常快速的工具,并且如果可行,我建议您使用它。 但是在设计上仅适用于纯HTML页面(例如Wikipedia或stackoverflow)。由于它不使用浏览器,并且无法呈现或执行Javascript,因此在复杂的网站上通常会失败。

如果wget失败,则最好的替代方法是kantu:正如我在my other answer中提到的那样,kantu和真实用户模块可以使此任务自动化。您需要专门查看的命令是XClick,尤其是XType,用于触发所需的所有按键。

答案 1 :(得分:0)

我接受了蒂姆·范德泽(Tim Vanderzeil)的回答,因为他将我定向到了我所需的工具。现在,我想与他给我的分享一下我所做的。由于Kantu的问题,该解决方案仅是半自动化的,但它远比尝试手动完成要好得多。我将其发布在这里,目的是分享我所学到的知识,并看看是否有人可以提供改进,包括解决阻止完全自动化的问题的解决方案。

首先,让我提及一些技术背景,这很有趣。 Kantu,尤其是扩展名XModules(这是我为此项目所需要的),是非常新的。制造它们的公司是founded in 2016,而Kantu是announced in September 2017。但是他们的历史要比其深得多,因为其创始人包括Mathias Roth的原始开发者iMacros。 Kantu是我在问题different implementation中提到的另一个工具的Selenium。因此,在这个深奥的浏览器自动化领域中存在很多交叉授粉。

许多人在StackOverflow上询问很长时间了,如何自动保存网页,例如1234,{{3 }}和5。在我看来,所有答案都无济于事。有点奇怪,因为所有浏览器都具有该功能,因此为此必须在某些地方浮动一些模块,因此我不知道为什么不能只在PHP中为其调用函数。上面链接为6的问题说,该问题通过“ #5”出现在浏览器中,但知道这还没有使我有用。

因此,在此之前,直到找到该PHP函数,我必须通过将Web浏览器变成机器人来做到这一点。我为下面的几本电子书开发了代码,这些电子书背后有一个我有一个合法帐户并希望保留供离线使用的付费壁垒,并且不提供pdf文件。我确定了两种使用Kantu下载页面的方式:

  • 我对目录页面的HTML进行了按摩,以提取所需的URL并将其放入CSV文件。可以用Kantu的命令csvRead读取。该URL传递给命令open以打开页面,然后命令XType发送Ctrl-S(或Alt-F-A)告诉浏览器保存页面。再次使用XType输入要另存为的文件名(URL中最后一个“ \”之后的部分),最后一个XType发送Enter来结束浏览器的另存为对话。循环播放,即可保存该书。循环可以使用标签和命令gotoLabel在宏内部完成,也可以将宏编写为一页,然后可以在Kantu的GUI中进行循环。

  • 或者,我可以使用每页上的链接转到下一页。这是我在问题中描述的过程。我首先使用了Kantu的记录过程来获取下一页链接的标识,并将其用作下面宏的代码中的数据(特别是用作命令XClickclick的“目标”) 。我在第一个网页上启动Kantu,宏使用命令XClick右键单击下一页链接,然后使用XType将“ A”发送到浏览器,告诉它复制链接的URL到剪贴板。然后,推荐的click单击该链接以打开页面,其余与前面的方法相同。在这里,我正在使用下一页链接来获取URL,而不是CSV文件。

现在,我提到了Kantu中存在一个问题,该问题无法完全自动化。由于未知原因,该过程的最后一步(将Enter发送到浏览器以结束“另存为”对话框很不稳定)。有时它可以工作,有时对话框只是在那儿,要求我自己按下Enter,以允许该过程继续到下一个网页。这很繁琐,这意味着我需要参与该过程,而不是让它自己运行。因此,这不是完美的方法,但是比必须手动完成所有其余过程要好得多,因为数百页是不可能的。

免费版本的XModules每次运行最多只能有25个命令。要超过该限制,有一个Webkit。如果我可以让流程独立运行,那将是非常值得的。但是由于无论如何我都必须照看它,所以我当前正在通过单击每个页面的Kantu的Play macro按钮以及查看何时需要按Enter来运行宏。

我已经在Kantu的论坛上发布了有关Enter问题和其他一些问题的信息。他们的团队反应迅速,乐于助人。我希望我或他们或阅读此书的人能找到解决方案。同时,半自动化过程总比没有好。

在上述两种方法之间,仅是第二种方法,它使用下一页链接来获取URL,这些URL可以无循环运行,即,手动按Play macro来访问每一页。这就是我现在一直在使用的那个。该代码的重复次数非常少,仅为25个Ctrl-Left,这是解决Home词汇中XType键的意外缺失以及缺失(据我所知)的一种解决方法(已找到)用于重复按键的命令。

这是JSON中的Kantu代码:

{"Name": "SavePageAsComplete",
 "CreationDate": "2019-01-03",
 "Commands":
  [{"Command": "comment",
    "Target":  "Macro for Kantu with XModules. Based on demo macros DemoXClick and 
         DemoXType and docs https://a9t9.com/kantu/docs/xclick and https://a9t9.com/kantu/docs/xtype. 
         The target in the XClick and click commands are what was obtained from 
         attempting to record this macro on the website, which resulted in only an open 
         command and two identical click commands with that target.",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Set play speed to 0.3 seconds. (See Kantu manual section 'Setting the right macro replay speed'.)",
    "Value":   ""
    },
   {"Command": "store",
    "Target":  "medium",
    "Value":   "!replayspeed"
    },
   {"Command": "bringBrowserToForeground",
    "Target":  "",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Right-click the link for the next page and copy its URL to the clipboard.",
    "Value":   ""
    },
   {"Command": "XClick",
    "Target":  "//*[@id=\"container\"]/div[2]/section/div[2]/a/div",
    "Value":   "#right"
    },
   {"Command": "XType",
    "Target":  "A",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Click the link for the next page. (Tried with 'clickAndWait' instead in 
         order to wait for the page to load, but that yielded error 'No page load 
         event detected after 10 seconds.')",
    "Value":   ""
    },
   {"Command": "click",
    "Target":  "//*[@id=\"container\"]/div[2]/section/div[2]/a/div",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Open the Save-as dialog.",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_S}",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Wait for the dialog to appear.",
    "Value":   ""
    },
   {"Command": "pause",
    "Target":  "2000",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Paste the clipboard (URL of now-current page) into Filename text box.",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_V}",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Move the cursor to the beginning of the URL. (There is no Home key!)",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}${KEY_CTRL+KEY_LEFT}",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Select from the beginning of the URL to the end of its path part.",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}${KEY_SHIFT+KEY_CTRL+KEY_RIGHT}",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Delete the selection, leaving just the filename.",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_DEL}",
    "Value":   ""
    },
   {"Command": "pause",
    "Target":  "500",
    "Value":   ""
    },
   {"Command": "comment",
    "Target":  "Save the page.",
    "Value":   ""
    },
   {"Command": "XType",
    "Target":  "${KEY_ENTER}",
    "Value":   ""
    }
   ]
 }

这可能会对想要自动保存页面的其他人有所帮助。如果有人可以对此进行改进,也许您可​​以在评论或其他答案中说出如何。尤其是如果您知道“另存为”对话框为何无法可靠关闭的原因,并且知道如何解决此问题。