如何使用javascript导航获取页面上的所有链接?

时间:2014-02-06 18:54:03

标签: javascript web-scraping web-crawler phantomjs

在经典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,似乎无法做到)。

注意

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

<a onclick=tonsOfWeirdBlackBoxFunctionsYouCantChange>

2 个答案:

答案 0 :(得分: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()并在其上运行正则表达式函数:

Mabye之类的东西:

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

答案 1 :(得分:1)

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

但是,您必须将javascript片段注入到在任何其他脚本之前运行的每个页面。我一直致力于the Crawljax web crawler的类似功能。我使用相同类型的mechanism to detect clickables here