【问题标题】:How to get all links on page with javascript navigation?如何使用 javascript 导航获取页面上的所有链接?
【发布时间】:2014-02-06 18:54:03
【问题描述】:

在经典 HTML 中很容易

$('a').map(function(){return this.href}).toArray()

但是,如果导航是通过 JavaScript 完成的,例如:

<a href='#' onclick='someFn()'>Some link</a>

如果不执行 someFn 函数,就不可能知道 url,如果你执行它 - 它不会返回 url,而是导航页面(我无法控制 someFn 函数并且不知道里面有什么或如何改变它)。

因此,为了从页面中获取所有 N 个链接,您必须加载所有这些 N 个页面。这是非常缓慢且低效的。

如何解决?

可能的解决方案 - 如果可以拦截对 window.location 的调用 - 问题已解决。您只需单击所有这些链接并检查window.location 的值,而无需加载新页面。但我不知道这是否可以做到(我使用 phantomjs 似乎无法做到)。

注意

HTML 中没有 URL,即使在 JavaScript 执行之后也是如此。是的,在某些情况下,您可以使用浏览器模拟器来执行 JS,然后解析在浏览器中动态生成的 HTML。但事实并非如此,我使用浏览器模拟器(phantomjs),但即使在 JS 执行之后,HTML 中也没有 URL 和导航,所有导航都在纯 JS 中完成,使用

<a onclick=tonsOfWeirdBlackBoxFunctionsYouCantChange>

【问题讨论】:

  • 你想用那个存档什么?也许还有另一种方法可以做到这一点。例如,您可以只解析链接的整个代码,无论它们出现在什么上下文中。
  • 基本上,我需要访问网站的一些页面,我无法访问所有页面,因为它们太多了。我可以通过 URL 检测它是否是我需要访问的页面。我需要获取要分析的 URL 列表并选择要访问的 URL(无需全部加载)。
  • 所以只解析源代码寻找任何看起来像 URL 的东西没有错,对吧?忽略上下文。这仍然不会为您提供动态创建的 URL,但是,如果不执行 javascript,这是不可能的。
  • 不,URL 不是动态创建的,即使在执行 JS 之后,HTML 中也没有 URL,所有导航都在 JavaScript 中完成,在那些黑框 someFn 函数中。如果不对每个链接执行 URL,就不可能知道 URL。

标签: javascript web-scraping web-crawler phantomjs


【解决方案1】:

如果您尝试解析页面上已执行的源代码,则需要使用正则表达式函数来对这些 URL 进行字符串搜索。

如果您尝试在运行时解析代码以查找位置并将它们保存到数组或其他东西 --- JavaScript 中的每个对象都有一个 toString 函数。

那就是 --- 如果您将 functions 定义为对象:

//Although you should really be using a parameter for this...
//...I'm trying to hold context with your use case.
var redirectToContact = function(){
  window.location = "/contact.html";
}

您可以redirectToContact.toString() 并在其上运行正则表达式函数:

大概是这样的:

var url = redirectToContact.toString();
console.log( url.match( 'window.location = "(.*)";' )[1] );

【讨论】:

  • 执行 JS 后 HTML 中没有 URL。而且,我无权访问代码,也无法更改它。
  • @AlexeyPetrushin 如果您可以在浏览器中运行代码,您就可以访问它。此时,您可以在平面文件上运行正则表达式函数 --- 或使用无头浏览器运行代码并拦截 HTTP 事务以派生“未知”URL 名称。
  • """此时你可以在一个平面文件上运行正则表达式函数""" 有 20k+ 行的 JS 和导航代码。至于拦截 HTTP 调用 - 谢谢,好主意,我需要检查一下!
  • @AlexeyPetrushin 您可以使用现代处理器在不到一秒的时间内对 20,000 行任何内容运行正则表达式函数。
  • 是的,但首先你必须分析几十个这样的站点并为每个站点编写不同的 RE,我什至无法想象需要多少时间 :)。特别是如果每​​个都有大约 5-15 个这样的功能,这些功能很大并且具有不同的逻辑。
【解决方案2】:

我认为您想要做的是覆盖 window.location 的原型。这篇 SO 帖子解释了如何做到这一点:Is it possible to override window.location.hostname in Javascript?

但是,您必须在任何其他脚本之前运行的每个页面中注入一个 javascript sn-p。我一直在为the Crawljax web crawler 开发类似的功能。我用的是同一种mechanism to detect clickables here。

【讨论】:

    猜你喜欢
    • 2021-04-16
    • 2019-02-27
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    相关资源
    最近更新 更多