网络与节点,phantomjs和骑手一起爬行
钥匙要点
- >利用node.js和npm有效地为Web爬网和其他命令行任务设置自定义CLI缩影。
> >使用Phantomjs和Horseman软件包来模拟浏览器中的用户互动,从而增强了自动化的Web爬行功能。 - 结合了骑士方法的链接,以执行复杂的动作序列,从而在网页中进行动态交互。
- 利用骑士中的evaluate()方法直接从DOM中提取灵活的脚本和数据提取,可用于诸如污损检测之类的任务。
- >利用Horseman的屏幕截图功能在网上爬行期间捕获和保存屏幕截图,以帮助视觉QA测试等任务。
- >确保每次使用后都关闭骑士实例,以防止孤立的phantomjs过程,保持系统性能和稳定性。
- >
可以在GitHub上找到本教程的源代码。为了运行示例,您需要同时安装node.js和phantomjs。可以在此处找到用于下载和安装的说明:node.js,phantomjs。
>设置基本命令行框架任何CLI框架的核心是将命令转换为一个或多个可选或必需的参数,转换为具体操作的概念。在这方面非常有用的两个NPM软件包是指挥官和提示。
指挥官允许您定义支持哪些参数,同时提示允许您(足够适当地)提示用户在运行时输入。最终结果是一个句法甜蜜的界面,用于基于某些用户提供的数据,以动态行为执行各种动作。
>说,例如,我们希望我们的命令看起来像这样:
>$ <span>node run.js -x hello_world </span>
我们的入口点(run.js)定义了这样的参数:
>program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
并定义了这样的各种用户输入案例:
><span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
>
如您所见,该模块期望提供一个phantomjs对象(Phantominstance)和URL(URL)的实例。我们将暂时地定义Phantomjs实例的细节,但是目前足以看到我们为触发特定动作奠定了基础。既然我们已经制定了一定的惯例,我们可以轻松地以定义和理智的方式添加新的动作。<span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
爬行
>每次我们通过CLI框架触发操作时,我们的输入脚本(RUN.JS)实例化骑士实例并将其传递到指定的操作模块。在伪代码中,它看起来像这样:
>
现在,当我们运行命令时,骑手实例和输入URL将传递到Hello_world模块,导致Phantomjs请求URL,捕获其状态代码并将状态打印到控制台。我们刚刚使用骑马者进行了第一个真正的善意爬行。 giddyup!
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
复合互动的骑士方法
到目前为止,我们已经研究了非常简单的骑士用法,但是当我们将其方法链接在一起以在浏览器中执行一系列操作时,包装可以做得更多。为了演示其中一些功能,让我们定义一个动作,该操作模拟了通过GitHub导航以创建新存储库的用户。
请注意:此示例纯粹是出于演示目的,不应被视为创建GitHub存储库的可行方法。这仅仅是一个人如何使用骑手与Web应用程序进行交互的示例。如果您有兴趣以自动方式创建存储库,则应使用官方的GitHub API。
让我们假设新的爬网会像这样触发:>按照我们已经制定的CLI框架的约定,我们需要在名为create_repo.js的操作目录中添加一个新模块。与我们以前的“ Hello World”示例一样,create_repo模块导出一个包含该动作的所有逻辑的单个函数。
$ <span>node run.js -x hello_world </span>
请注意,在此操作中,我们将更多的参数传递给导出的函数,而不是以前。这些参数包括用户名,密码和存储库。一旦用户成功完成了及时挑战,我们将从run.js传递这些值。
program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
>现在我们将此挂钩添加到run.js,当用户输入相关数据时,它将传递给操作,从而使我们可以继续进行爬网。
至于Create_repo爬网逻辑本身,我们使用骑手的方法来导航到GitHub登录页面,输入提供的用户名和密码,然后提交表单:<span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
我们通过等待表单提交页面加载来继续链条:
之后,我们使用jQuery来确定登录是否成功:
<span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
>在我们的个人资料页面上,我们将导航到我们的存储库标签:
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
在我们的存储库选项卡时,我们检查是否已经存在带有指定名称的存储库。如果是这样,那么我们会丢下错误。如果不是,那么我们继续我们的顺序:
$ <span>node run.js -x create_repo </span>
假设没有错误,我们通过编程单击“新存储库”按钮并等待下一页:
module<span>.exports = function (phantomInstance<span>, username, password, repository</span>) { </span> <span>if (!username || !password || !repository) { </span> <span>throw 'You must specify login credentials and a repository name'; </span> <span>} </span> <span>... </span><span>} </span>
之后,我们输入提供的存储库名称并提交表格:
<span>switch (program.actionToPerform) { </span> <span>case 'create_repo': </span> prompt<span>.get([{ </span> <span>name: 'repository', </span> <span>description: 'Enter repository name', </span> <span>required: true </span> <span>}, { </span> <span>name: 'username', </span> <span>description: 'Enter GitHub username', </span> <span>required: true </span> <span>}, { </span> <span>name: 'password', </span> <span>description: 'Enter GitHub password', </span> <span>hidden: true, </span> <span>required: true </span> <span>}], function (err<span>, result</span>) { </span> <span>performAction( </span> phantomInstance<span>, </span> result<span>.username, </span> result<span>.password, </span> result<span>.repository </span> <span>); </span> <span>}); </span> <span>break; </span> <span>... </span>
与任何骑马爬行一样,至关重要的是,我们结束了骑马的实例:
phantomInstance <span>.open('https://github.com/login') </span> <span>.type('input[name="login"]', username) </span> <span>.type('input[name="password"]', password) </span> <span>.click('input[name="commit"]') </span>
>未能关闭骑士实例可能会导致机器上的孤立phantomjs处理。
<span>.waitForNextPage() </span>
在这一点上,我们已经组装了一系列静态序列,以编程方式在GitHub上创建一个新的存储库。为此,我们链接了一系列的骑手方法。
这种方法对于事先已知的特定结构和行为模式可能很有用,但是,您可能会发现您需要在某个时候实现更灵活的脚本。如果您的动作序列有可能根据上下文变化或产生多个不同的结果,则可能是这种情况。如果您需要从DOM中提取数据,也将是这种情况。
在这种情况下,您可以使用Horseman的evaliate()方法,它允许您通过注入内联或外部链接JavaScript来执行浏览器中的自由形式交互。>
>本节演示了从页面中提取基本数据的示例(在这种情况下,锚点链接)。可能需要这种情况的一种情况是构建一个污损检测轨,以击中域上的每个URL。与我们的最后一个示例一样,我们必须首先在操作目录中添加一个新模块:
,然后在run.js中为新操作添加一个钩子:
$ <span>node run.js -x hello_world </span>
现在,此代码已经到位,我们可以通过运行以下命令来从任何给定的页面提取链接:
program <span>.version('1.0.0') </span> <span>.option('-x --action-to-perform [string]', 'The type of action to perform.') </span> <span>.option('-u --url [string]', 'Optional URL used by certain actions') </span> <span>.parse(process.argv); </span>
>此操作演示了从页面上提取数据,并且不会利用骑手内置的任何浏览器操作。它直接执行您在estuation()方法中放置的任何JavaScript,并且会像在浏览器环境中本地运行一样。
><span>var performAction = require('./actions/' + program.actionToPerform) </span> <span>switch (program.actionToPerform) { </span> <span>case 'hello_world': </span> prompt<span>.get([{ </span> <span>// What the property name should be in the result object </span> <span>name: 'url', </span> <span>// The prompt message shown to the user </span> <span>description: 'Enter a URL', </span> <span>// Whether or not the user is required to enter a value </span> <span>required: true, </span> <span>// Validates the user input </span> <span>conform: function (value) { </span> <span>// In this case, the user must enter a valid URL </span> <span>return validUrl.isWebUri(value); </span> <span>} </span> <span>}], function (err<span>, result</span>) { </span> <span>// Perform some action following successful input </span> <span>performAction(phantomInstance, result.url); </span> <span>}); </span> <span>break; </span><span>} </span>
>通过扩展上面的逻辑,您几乎可以在任何网站上执行任何操作。
><span>'use strict'; </span> <span>/** </span><span> * <span>@param Horseman phantomInstance </span></span><span> * <span>@param string url </span></span><span> */ </span>module<span>.exports = function (phantomInstance<span>, url</span>) { </span> <span>if (!url || typeof url !== 'string') { </span> <span>throw 'You must specify a url to ping'; </span> <span>} else { </span> <span>console.log('Pinging url: ', url); </span> <span>} </span> phantomInstance <span>.open(url) </span> <span>.status() </span> <span>.then(function (statusCode) { </span> <span>if (Number(statusCode) >= 400) { </span> <span>throw 'Page failed with status: ' + statusCode; </span> <span>} else { </span> <span>console.log('Hello world. Status code returned: ', statusCode); </span> <span>} </span> <span>}) </span> <span>.catch(function (err) { </span> <span>console.log('Error: ', err); </span> <span>}) </span> <span>// Always close the Horseman instance </span> <span>// Otherwise you might end up with orphaned phantom processes </span> <span>.close(); </span><span>}; </span>
>我想证明的最终用例是您将如何使用Horseman拍摄屏幕截图。我们可以使用Horseman的ScreenShotBase64()方法来完成此操作,该方法返回代表屏幕截图的base64编码字符串。
与我们上一个示例一样,我们必须首先在操作目录中添加一个新模块:
,然后在run.js中为新操作添加一个钩子:
>
<span>var phantomInstance = new Horseman({ </span> <span>phantomPath: '/usr/local/bin/phantomjs', </span> <span>loadImages: true, </span> <span>injectJquery: true, </span> <span>webSecurity: true, </span> <span>ignoreSSLErrors: true </span><span>}); </span> <span>performAction(phantomInstance, ...); </span>
>
$ <span>node run.js -x create_repo </span>
>
如果要保存实际映像,则使用屏幕截图()方法。module<span>.exports = function (phantomInstance<span>, username, password, repository</span>) { </span> <span>if (!username || !password || !repository) { </span> <span>throw 'You must specify login credentials and a repository name'; </span> <span>} </span> <span>... </span><span>} </span>
结论
本教程试图展示自定义的CLI微框架和一些基本的逻辑,用于使用Horseman软件包来利用Phantomjs,以爬Node.js爬网。虽然使用CLI框架可能会使许多项目受益,但爬行通常仅限于非常特定的问题域。一个共同的领域是质量保证(QA),可以将爬网用于功能和用户界面测试。另一个领域是安全性,例如,您可能想定期爬网,以检测到它是否已被污损或折衷。
>无论您的项目可能是什么情况,请确保清楚地定义您的目标并尽可能不引人注目。在可能的情况下获得许可,请在最大程度上礼貌,并注意永远不要DDOS。如果您怀疑自己正在产生大量的自动流量,那么您可能会重新评估您的目标,实施或许可水平。
经常询问的问题(常见问题解答)有关网络爬行的节点和phantomjs骑手Web爬网和Web刮擦之间有什么区别?
Web爬网和Web刮擦是两个不同的过程,尽管它们通常可以互换使用。网络爬行是系统浏览网络的过程,通常由机器人或蜘蛛进行。它涉及索引网站的内容和以下链接到其他网页。另一方面,网络刮擦是从网站提取特定数据的过程。它涉及解析网页的HTML以删除所需的数据。虽然网络爬网是关于导航和索引的,但网络刮擦是关于数据提取的。
异步性质。它允许并发处理,这意味着您可以同时爬网多页。这使其比同步执行的其他语言要快得多。此外,Node.js拥有一个丰富的生态系统,具有许多可以帮助网络爬行的库和工具,例如Phantomjs Horseman。 > Phantomjs Horseman是一个Node.js软件包,可为使用Phantomjs自动化Web浏览器提供高级API。它允许您在网页上执行操作,例如单击链接,填写表单和屏幕截图。这使其成为网络爬网的强大工具,因为它使您可以像人类用户一样与网页进行交互。
> JavaScript渲染如何影响Web爬行?>>我可以使用Web爬网来监视网站上的更改吗? ,网络爬行可用于监视网站上的更改。通过定期爬行网站并将当前状态与以前的状态进行比较,您可以检测任何更改。这对于各种目的可能很有用,例如在电子商务网站上跟踪价格变化或监视新闻网站上的更新。
网络爬行法律?
>>网络爬行的合法性取决于在包括您所处的管辖权以及您爬行的特定网站上的几个因素上。一些网站明确允许Web在其robots.txt文件中爬行,而另一些网站则禁止Web爬网。重要的是要尊重网站的robots.txt文件,并且不要在短时间内用太多请求超载网站的服务器。>
>我如何优化我的网络爬行过程?是优化网络爬行过程的几种方法。一种方法是使用广度优先搜索(BFS)算法,该算法可确保您在进入下一个深度级别之前,在一定深度爬网。另一种方法是根据页面的相关性优先考虑爬网。例如,如果您要抓取电子商务网站,您可能想在博客文章之前爬网。 >是的,使用Phantomjs Horseman,您可以自动登录网站的过程。这使您可以在登录后访问仅访问的页面。但是,您应该意识到这可能违反网站的服务条款。我如何处理网络爬网中的动态内容?>处理动态内容在Web Crawling中可能具有挑战性,作为传统Web爬网仅解析网页的静态HTML。但是,使用Phantomjs Horseman之类的工具,您可以像人类用户一样渲染JavaScript并与动态内容进行交互。这使您可以从严重依赖JavaScript进行内容生成的网站上爬网和提取数据。>>如何阻止我的网络爬行者被阻塞?一种方法是尊重网站的robots.txt文件,该文件提供了有关您允许爬网的哪些部分的指南。另一种方法是限制您将请求发送到网站的速率,以避免服务器超载。您也可以旋转IP地址和用户代理以避免被检测为机器人。>
>我可以使用Web爬网来监视网站上的更改吗? ,网络爬行可用于监视网站上的更改。通过定期爬行网站并将当前状态与以前的状态进行比较,您可以检测任何更改。这对于各种目的可能很有用,例如在电子商务网站上跟踪价格变化或监视新闻网站上的更新。
网络爬行法律?
>>网络爬行的合法性取决于在包括您所处的管辖权以及您爬行的特定网站上的几个因素上。一些网站明确允许Web在其robots.txt文件中爬行,而另一些网站则禁止Web爬网。重要的是要尊重网站的robots.txt文件,并且不要在短时间内用太多请求超载网站的服务器。>
>我如何优化我的网络爬行过程?是优化网络爬行过程的几种方法。一种方法是使用广度优先搜索(BFS)算法,该算法可确保您在进入下一个深度级别之前,在一定深度爬网。另一种方法是根据页面的相关性优先考虑爬网。例如,如果您要抓取电子商务网站,您可能想在博客文章之前爬网。 >是的,使用Phantomjs Horseman,您可以自动登录网站的过程。这使您可以在登录后访问仅访问的页面。但是,您应该意识到这可能违反网站的服务条款。我如何处理网络爬网中的动态内容?>处理动态内容在Web Crawling中可能具有挑战性,作为传统Web爬网仅解析网页的静态HTML。但是,使用Phantomjs Horseman之类的工具,您可以像人类用户一样渲染JavaScript并与动态内容进行交互。这使您可以从严重依赖JavaScript进行内容生成的网站上爬网和提取数据。>>如何阻止我的网络爬行者被阻塞?一种方法是尊重网站的robots.txt文件,该文件提供了有关您允许爬网的哪些部分的指南。另一种方法是限制您将请求发送到网站的速率,以避免服务器超载。您也可以旋转IP地址和用户代理以避免被检测为机器人。>
>如何阻止我的网络爬行者被阻塞?一种方法是尊重网站的robots.txt文件,该文件提供了有关您允许爬网的哪些部分的指南。另一种方法是限制您将请求发送到网站的速率,以避免服务器超载。您也可以旋转IP地址和用户代理以避免被检测为机器人。>
以上是网络与节点,phantomjs和骑手一起爬行的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...
