使用 selenium 和 python 捕获 AJAX 响应
Posted
技术标签:
【中文标题】使用 selenium 和 python 捕获 AJAX 响应【英文标题】:Capture AJAX response with selenium and python 【发布时间】:2014-12-16 08:29:49 【问题描述】:我点击 Firefox 中的链接,网页使用 javascript 发送请求,然后服务器发送某种响应,其中包括网站地址。所以这个新网站然后在一个新窗口中打开。链接后面的html代码是(我省略了初始和最终<span>
标签):
> class="taLnk hvrIE6"
> onclick="ta.trackEventOnPage('AttractionContactInfo', 'Website',
> 2316062, 1); ta.util.cookie.setPIDCookie(15190);
> ta.call('ta.util.link.targetBlank', event, this,
> 'aHref':'LqMWJQiMnYQQoqnQQxGEcQQoqnQQWJQzZYUWJQpEcYGII26XombQQoqnQQQQoqnqgoqnQQQQoqnQQQQoqnQQQQoqnqgoqnQQQQoqnQQuuuQQoqnQQQQoqnxioqnQQQQoqnQQJMsVCIpEVMSsVEtHJcSQQoqnQQQQoqnxioqnQQQQoqnQQniaQQoqnQQQQoqnqgoqnQQQQoqnQQWJQzhYmkXHJUokUHnmKTnJXB',
> 'isAsdf':true)">Website
我想捕获服务器响应并使用 Python 和 Selenium 提取“新网站”。我一直在使用 BeautifulSoup 进行抓取,并且对 Selenium 很陌生。
到目前为止,我能够找到这个元素并使用 selenium 单击它,这会在新窗口中打开“新网站”。我不知道如何捕获服务器的响应。
【问题讨论】:
我认为问题的标题具有误导性——beautifulsoup 与您的问题无关。 “使用 Selenium 获得 AJAX 响应”或其他相关内容。 一位高级成员建议我这样重命名我的问题...我的实际标题确实与python和selenium有关 【参考方案1】:我曾经截获了一些使用 selenium 将 javascript 注入页面的 ajax 调用。历史的不利方面是硒有时可能是“脆弱的”。因此,在进行此注入时,我无缘无故地遇到了 selenium 异常。
无论如何,我的想法是拦截 XHR 调用,并将其响应设置为我创建的一个新的 dom 元素,我可以从 selenium 进行操作。在拦截的条件下,您甚至可以使用发出请求的 url 来拦截您真正想要的(self._url)
顺便说一句,我从intercept all ajax calls?得到这个想法
也许这会有所帮助。
browser.execute_script("""
(function(XHR)
"use strict";
var element = document.createElement('div');
element.id = "interceptedResponse";
element.appendChild(document.createTextNode(""));
document.body.appendChild(element);
var open = XHR.prototype.open;
var send = XHR.prototype.send;
XHR.prototype.open = function(method, url, async, user, pass)
this._url = url; // want to track the url requested
open.call(this, method, url, async, user, pass);
;
XHR.prototype.send = function(data)
var self = this;
var oldOnReadyStateChange;
var url = this._url;
function onReadyStateChange()
if(self.status === 200 && self.readyState == 4 /* complete */)
document.getElementById("interceptedResponse").innerHTML +=
'"data":' + self.responseText + '*****';
if(oldOnReadyStateChange)
oldOnReadyStateChange();
if(this.addEventListener)
this.addEventListener("readystatechange", onReadyStateChange,
false);
else
oldOnReadyStateChange = this.onreadystatechange;
this.onreadystatechange = onReadyStateChange;
send.call(this, data);
)(XMLHttpRequest);
""")
【讨论】:
感谢您分享您的经验。我没有可用的javascript知识。我只需要收集网站作为 ajax 调用响应发送的一些数据。该解决方案似乎使用 Python 自己的模块(例如 requests 或 urllib)来识别和模拟调用。这有助于我在没有任何 javascript 的情况下收集数据 如果你事先知道网站的url就不需要处理javascript,但在我的情况下,提前知道url的一些参数并不容易,所以我需要处理js。如果您的问题的解决方案是您之前发布的,请将其标记为您的问题的答案。 快两年过去了,这还是要走的路吗?我需要检索我的网站进行的 ajax 调用的 url,因为我事先不知道某些参数。另外,时间呢?我怎么能确定这个脚本是在任何 ajax 请求发生之前执行的?谢谢。【参考方案2】:当我尝试基于 AJAX 请求捕获 XHR 内容时,我来到了这个页面。 我最终找到了this 包
from seleniumwire import webdriver # Import from seleniumwire
# Create a new instance of the Firefox driver
driver = webdriver.Firefox()
# Go to the Google home page
driver.get('https://www.google.com')
# Access requests via the `requests` attribute
for request in driver.requests:
if request.response:
print(
request.url,
request.response.status_code,
request.response.headers['Content-Type']
)
这个包允许从任何请求中获取内容响应,例如json:
https://www.google.com/ 200 text/html; charset=UTF-8
https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png 200 image/png
https://consent.google.com/status?continue=https://www.google.com&pc=s×tamp=1531511954&gl=GB 204 text/html; charset=utf-8
https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png 200 image/png
https://ssl.gstatic.com/gb/images/i2_2ec824b0.png 200 image/png
https://www.google.com/gen_204?s=webaft&t=aft&atyp=csi&ei=kgRJW7DBONKTlwTK77wQ&rt=wsrt.366,aft.58,prt.58 204 text/html; charset=UTF-8
..
【讨论】:
【参考方案3】:我无法使用 selenium 捕获 AJAX 响应,但这是可行的,尽管没有 selenium:
1-通过监控浏览器中的网络分析工具找出XML请求
2= 识别请求后,使用 Python 的请求或 urllib2 模块重新生成它。我个人推荐 requests 因为它的附加功能,对我来说最重要的是 requests.Session。
您可以找到很多关于这两个步骤的帮助和相关帖子。
希望有一天它会对某人有所帮助。
【讨论】:
我正在抓取的网站正是这样做的。花了一段时间才弄清楚 Chrome 网络工具的实际调用是什么,但我找到了。然后我在浏览器中测试了响应,最后是请求。像魅力一样工作。在我的情况下,输出似乎是 JSON 和其他数据的混合 - 所有这些都易于解析。再次感谢。以上是关于使用 selenium 和 python 捕获 AJAX 响应的主要内容,如果未能解决你的问题,请参考以下文章
Selenium2+python自动化57-捕获异常(NoSuchElementException)
Selenium2+python自动化57-捕获异常(NoSuchElementException)转载
如何在 Python 上使用 selenium webdriver 和 browsermob 代理捕获网络流量?