gpt4 book ai didi

ajax - 使用 Java 脚本跟踪网页中是否发生 Ajax 请求或通过 Selenium Web 驱动程序拦截 XMLHttpRequest

转载 作者:行者123 更新时间:2023-12-02 13:16:29 26 4
gpt4 key购买 nike

我正在使用Selenium WebDriver用于爬行 web site (仅作为示例,我也会抓取其他网站!)它具有无限滚动。

问题陈述:

向下滚动无限滚动页面,直到使用 Selenium Web 驱动程序停止加载内容。

我的方法:目前我正在这样做 -

第 1 步:滚动到页面底部

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.onload=toBottom();"+
"function toBottom(){" +
"window.scrollTo(0,Math.max(document.documentElement.scrollHeight," +
"document.body.scrollHeight,document.documentElement.clientHeight));" +
"}");

然后我等待一段时间让 Ajax 请求完成,如下所示 -

第 2 步:显式等待 Ajax 请求结束

Thread.sleep(1000);

然后我给出另一个java脚本来检查页面是否可滚动

第3步:检查页面是否可滚动

//Alternative to document.height is to be used which is document.body.clientHeight
//refer to https://developer.mozilla.org/en-US/docs/DOM/document.height

if((Long)js.executeScript("return " +
"(document.body.clientHeight-(window.pageYOffset + window.innerHeight))")>0)

如果上述条件为真,则重复步骤 1 - 3,直到步骤 3 中的条件为假。

问题:我不想给Thread.sleep(1000);在步骤 2 中,我想使用 Java 脚本检查后台 Ajax 请求是否结束,然后进一步向下滚动,如果步骤 3 中的条件为 true 。

PS:我不是该页面的开发人员,因此我无权访问运行该页面的代码,我只能在网络中注入(inject)java脚本(如步骤1和3)页。而且,我必须为无限滚动期间具有 Ajax 请求的任何网站编写通用逻辑。

如果有人能在这里抽出一些时间,我将不胜感激!

编辑:好吧,经过两天的努力,我发现我通过 Selenium WebDriver 爬行的页面可以有这些 JavaScript libraries 中的任何一个。我将不得不根据不同的库进行池化,例如,如果 Web 应用程序使用 jQuery api,我可能正在等待

(Long)((JavascriptExecutor)driver).executeScript("return jQuery.active")

返回零。

同样,如果 Web 应用程序使用 Prototype JavaScript 库我必须等待

(Long)((JavascriptExecutor)driver).executeScript("return Ajax.activeRequestCount")

返回零。

现在问题是如何编写可以处理大多数可用 JavaScript 库的通用代码?

我在实现此操作时遇到的问题-

1。如何找到 Web 应用程序中正在使用哪个 JavaScript 库(在 Java 中使用 Selenium WebDriver),以便我可以编写相应的等待方法?目前我正在使用这个

Code

2。这样我就必须为单独的 JavaScript 库编写多达 77 个方法,因此我还需要一种更好的方法来处理这种情况。

简而言之,我需要弄清楚浏览器是否正在通过 Selenium Web Driver 的 java 实现使用或不使用任何 JavaScript 库进行任何调用(Ajax 或简单)

PS:Chorme 的 JavaScript Lib detector 有附加组件和 Firefox 的 JavaScript Library detector它检测正在使用的 JavaScript 库。

最佳答案

对于在无限滚动期间使用 Ajax 响应并使用 jQuery API(或其他操作)的网页,在开始打开网页之前。

    //Inject the pooling status variable
js.executeScript("window.status = 'fail';");

//Attach the Ajax call back method
js.executeScript( "$(document).ajaxComplete(function() {" +
"status = 'success';});");

第 1 步:与原始问题中的内容相同

第 2 步 汇集以下脚本(这是消除 Thread.Sleep() 的需要并使逻辑更加动态的脚本)

String aStatus = (String)js.executeScript("return status;");

if(aStatus!=null && aStatus.equalsIgnoreCase("success")){
js.executeScript("status = 'fail';");
break poolingLoop;
}

第 3 步:现在不需要!

结论:不需要给出生硬的Thread.sleep();使用 Selenium WebDriver 时一次又一次!!

仅当 Web 应用程序中使用 jQuery api 时,此方法才有效。

编辑:根据 @jayati 给出的链接,我注入(inject)了 javascript-

Javascript一:

//XMLHttpRequest instrumentation/wrapping
var startTracing = function (onnew) {
var OldXHR = window.XMLHttpRequest;

// create a wrapper object that has the same interfaces as a regular XMLHttpRequest object
// see http://www.xulplanet.com/references/objref/XMLHttpRequest.html for reference on XHR object
var NewXHR = function() {
var self = this;
var actualXHR = new OldXHR();

// private callbacks (for UI):
// onopen, onsend, onsetrequestheader, onupdate, ...
this.requestHeaders = "";
this.requestBody = "";

// emulate methods from regular XMLHttpRequest object
this.open = function(a, b, c, d, e) {
self.openMethod = a.toUpperCase();
self.openURL = b;
ajaxRequestStarted = 'open';

if (self.onopen != null && typeof(self.onopen) == "function") {
self.onopen(a,b,c,d,e); }
return actualXHR.open(a,b,c,d,e);
}
this.send = function(a) {
ajaxRequestStarted = 'send';

if (self.onsend != null && typeof(this.onsend) == "function") {
self.onsend(a); }
self.requestBody += a;
return actualXHR.send(a);
}
this.setRequestHeader = function(a, b) {
if (self.onsetrequestheader != null && typeof(self.onsetrequestheader) == "function") { self.onsetrequestheader(a, b); }
self.requestHeaders += a + ":" + b + "\r\n";
return actualXHR.setRequestHeader(a, b);
}
this.getRequestHeader = function() {
return actualXHR.getRequestHeader();
}
this.getResponseHeader = function(a) { return actualXHR.getResponseHeader(a); }
this.getAllResponseHeaders = function() { return actualXHR.getAllResponseHeaders(); }
this.abort = function() { return actualXHR.abort(); }
this.addEventListener = function(a, b, c) { return actualXHR.addEventListener(a, b, c); }
this.dispatchEvent = function(e) { return actualXHR.dispatchEvent(e); }
this.openRequest = function(a, b, c, d, e) { return actualXHR.openRequest(a, b, c, d, e); }
this.overrideMimeType = function(e) { return actualXHR.overrideMimeType(e); }
this.removeEventListener = function(a, b, c) { return actualXHR.removeEventListener(a, b, c); }

// copy the values from actualXHR back onto self
function copyState() {
// copy properties back from the actual XHR to the wrapper
try {
self.readyState = actualXHR.readyState;
} catch (e) {}
try {
self.status = actualXHR.status;
} catch (e) {}
try {
self.responseText = actualXHR.responseText;
} catch (e) {}
try {
self.statusText = actualXHR.statusText;
} catch (e) {}
try {
self.responseXML = actualXHR.responseXML;
} catch (e) {}
}

// emulate callbacks from regular XMLHttpRequest object
actualXHR.onreadystatechange = function() {
copyState();

try {
if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); }
} catch (e) {}

// onreadystatechange callback
if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") { return self.onreadystatechange(); }
}
actualXHR.onerror = function(e) {

ajaxRequestComplete = 'err';
copyState();

try {
if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); }
} catch (e) {}

if (self.onerror != null && typeof(self.onerror) == "function") {
return self.onerror(e);
} else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") {
return self.onreadystatechange();
}
}
actualXHR.onload = function(e) {

ajaxRequestComplete = 'loaded';
copyState();

try {
if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); }
} catch (e) {}

if (self.onload != null && typeof(self.onload) == "function") {
return self.onload(e);
} else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") {
return self.onreadystatechange();
}
}
actualXHR.onprogress = function(e) {
copyState();

try {
if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); }
} catch (e) {}

if (self.onprogress != null && typeof(self.onprogress) == "function") {
return self.onprogress(e);
} else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") {
return self.onreadystatechange();
}
}

if (onnew && typeof(onnew) == "function") { onnew(this); }
}

window.XMLHttpRequest = NewXHR;

}
window.ajaxRequestComplete = 'no';//Make as a global javascript variable
window.ajaxRequestStarted = 'no';
startTracing();

Javascript 2:

var startTracing = function (onnew) {
window.ajaxRequestComplete = 'no';//Make as a global javascript variable
window.ajaxRequestStarted = 'no';

XMLHttpRequest.prototype.uniqueID = function() {
if (!this.uniqueIDMemo) {
this.uniqueIDMemo = Math.floor(Math.random() * 1000);
}
return this.uniqueIDMemo;
}

XMLHttpRequest.prototype.oldOpen = XMLHttpRequest.prototype.open;

var newOpen = function(method, url, async, user, password) {

ajaxRequestStarted = 'open';
/*alert(ajaxRequestStarted);*/
this.oldOpen(method, url, async, user, password);
}

XMLHttpRequest.prototype.open = newOpen;

XMLHttpRequest.prototype.oldSend = XMLHttpRequest.prototype.send;

var newSend = function(a) {
var xhr = this;

var onload = function() {
ajaxRequestComplete = 'loaded';
/*alert(ajaxRequestComplete);*/
};

var onerror = function( ) {
ajaxRequestComplete = 'Err';
/*alert(ajaxRequestComplete);*/
};

xhr.addEventListener("load", onload, false);
xhr.addEventListener("error", onerror, false);

xhr.oldSend(a);
}

XMLHttpRequest.prototype.send = newSend;
}
startTracing();

并检查java代码中的状态变量ajaxRequestStarted、ajaxRequestComplete的状态,可以确定ajax是否已启动或已完成。

现在我有办法等待 Ajax 完成,我还可以发现 Ajax 是否被某些操作触发

关于ajax - 使用 Java 脚本跟踪网页中是否发生 Ajax 请求或通过 Selenium Web 驱动程序拦截 XMLHttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11755186/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com