你如何抓取 AJAX 页面?
Posted
技术标签:
【中文标题】你如何抓取 AJAX 页面?【英文标题】:How do you scrape AJAX pages? 【发布时间】:2010-09-20 14:32:42 【问题描述】:请告知如何抓取 AJAX 页面。
【问题讨论】:
【参考方案1】:概述:
所有屏幕抓取首先需要手动检查您要从中提取资源的页面。在处理 AJAX 时,您通常只需要分析一些内容,而不仅仅是 html。
在处理 AJAX 时,这仅意味着您想要的值不在您请求的初始 HTML 文档中,而是将执行 javascript 请求服务器提供您想要的额外信息。
因此,您通常可以简单地分析 javascript 并查看 javascript 发出的请求,然后从一开始就调用此 URL。
示例:
以此为例,假设你要抓取的页面有如下脚本:
<script type="text/javascript">
function ajaxFunction()
var xmlHttp;
try
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
catch (e)
// Internet Explorer
try
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
catch (e)
try
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
catch (e)
alert("Your browser does not support AJAX!");
return false;
xmlHttp.onreadystatechange=function()
if(xmlHttp.readyState==4)
document.myForm.time.value=xmlHttp.responseText;
xmlHttp.open("GET","time.asp",true);
xmlHttp.send(null);
</script>
那么您需要做的就是向同一服务器的 time.asp 发出 HTTP 请求。 Example from w3schools.
使用 C++ 进行高级抓取:
对于复杂的用法,如果您使用 C++,您还可以考虑使用 firefox javascript 引擎SpiderMonkey 在页面上执行 javascript。
使用 Java 进行高级抓取:
对于复杂的用法,如果您使用 Java,您还可以考虑使用适用于 Java 的 firefox javascript 引擎Rhino
使用 .NET 进行高级抓取:
对于复杂的使用,如果您使用的是 .Net,您还可以考虑使用 Microsoft.vsa 程序集。最近替换为 ICodeCompiler/CodeDOM。
【讨论】:
哇,即使现在有了像 phantomjs 这样的工具,这也是非常有用的信息,一旦您调查了幕后发生的事情,知道如何使用所述方法自定义抓取页面会更加方便谢谢很多布莱恩+1【参考方案2】:在我看来,最简单的解决方案是使用Casperjs,这是一个基于 WebKit 无头浏览器 phantomjs 的框架。
整个页面加载完毕,很容易抓取任何与 ajax 相关的数据。 你可以查看这个基础教程来学习Automating & Scraping with PhantomJS and CasperJS
您还可以查看此示例代码,了解如何抓取 google 建议的关键字:
/*global casper:true*/
var casper = require('casper').create();
var suggestions = [];
var word = casper.cli.get(0);
if (!word)
casper.echo('please provide a word').exit(1);
casper.start('http://www.google.com/', function()
this.sendKeys('input[name=q]', word);
);
casper.waitFor(function()
return this.fetchText('.gsq_a table span').indexOf(word) === 0
, function()
suggestions = this.evaluate(function()
var nodes = document.querySelectorAll('.gsq_a table span');
return [].map.call(nodes, function(node)
return node.textContent;
);
);
);
casper.run(function()
this.echo(suggestions.join('\n')).exit();
);
【讨论】:
但是如何与 php 一起使用呢? 您使用 shell_exec 启动它。别无选择。【参考方案3】:如果可以,请尝试检查 DOM 树。 Selenium 将其作为测试页面的一部分。它还具有单击按钮和跟踪链接的功能,这可能很有用。
【讨论】:
在 selenium 客户端脚本中,您可以使用get_html_source()
函数,但它返回正常源,而不是生成的(AJAX 后)源。如果您知道如何访问生成的源代码,请告诉我们。【参考方案4】:
使用 Ajax 或一般使用 Javascript 抓取网页的最佳方法是使用浏览器本身或无头浏览器(没有 GUI 的浏览器)。目前phantomjs 是一款使用WebKit 推广的无头浏览器。我成功使用的替代方法是HtmlUnit(在Java 或.NET 中通过IKVM,这是一个模拟浏览器。另一个已知的替代方法是使用像Selenium 这样的网络自动化工具。
我写了很多关于这个主题的文章,比如web scraping Ajax and Javascript sites 和automated browserless OAuth authentication for Twitter。在第一篇文章的末尾,有很多我从 2011 年以来一直在编译的额外资源。
【讨论】:
【参考方案5】:我喜欢PhearJS,但这可能部分是因为我构建了它。
也就是说,它是您在后台运行的一项服务,它使用 HTTP(S) 并将页面呈现为 JSON,包括您可能需要的任何元数据。
【讨论】:
【参考方案6】:取决于 ajax 页面。屏幕抓取的第一部分是确定页面的工作方式。是否有某种变量可以迭代以从页面请求所有数据?我个人使用Web Scraper Plus 完成了很多与屏幕抓取相关的任务,因为它价格便宜,入门不难,非程序员也可以相对快速地使用它。
旁注:使用条款可能是您在执行此操作之前可能需要检查的地方。根据站点的不同,遍历所有内容可能会引发一些标志。
【讨论】:
【参考方案7】:我认为当源代码易于阅读时,Brian R. Bondy 的回答很有用。我更喜欢使用 Wireshark 或 HttpAnalyzer 等工具来捕获数据包并从“Host”字段和“GET”字段获取 url。
例如,我捕获如下数据包:
GET /hqzx/quote.aspx?type=3&market=1&sorttype=3&updown=up&page=1&count=8&time=164330
HTTP/1.1
Accept: */*
Referer: http://quote.hexun.com/stock/default.aspx
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: quote.tool.hexun.com
Connection: Keep-Alive
那么网址就是:
http://quote.tool.hexun.com/hqzx/quote.aspx?type=3&market=1&sorttype=3&updown=up&page=1&count=8&time=164330
【讨论】:
【参考方案8】:作为一种低成本的解决方案,您还可以尝试SWExplorerAutomation (SWEA)。该程序为使用 HTML、DHTML 或 AJAX 开发的任何 Web 应用程序创建自动化 API。
【讨论】:
【参考方案9】:Selenium WebDriver 是一个很好的解决方案:您编写浏览器并自动执行需要在浏览器中完成的操作。浏览器(Chrome、Firefox 等)提供了自己的与 Selenium 一起工作的驱动程序。由于它作为自动 REAL 浏览器工作,因此页面(包括 javascript 和 Ajax)会像使用该浏览器的人一样被加载。
缺点是速度很慢(因为您很可能希望等待所有图像和脚本加载完毕,然后再对单个页面进行抓取)。
【讨论】:
【参考方案10】:我之前链接到 MIT 的溶剂和 EnvJS 作为我刮掉 Ajax 页面的答案。这些项目似乎不再可用。
出于绝对必要,我发明了另一种实际刮掉 Ajax 页面的方法,它适用于像 findthecompany 这样具有查找无头 javascript 引擎并且不显示数据的方法的棘手网站。
技术是使用 chrome 扩展来进行抓取。 Chrome 扩展是删除 Ajax 页面的最佳位置,因为它们实际上允许我们访问 javascript 修改的 DOM。技术如下,我一定会在某个时候开源代码。创建一个 chrome 扩展(假设您知道如何创建一个,以及它的架构和功能。这很容易学习和实践,因为有很多示例),
-
使用内容脚本通过 xpath 访问 DOM。几乎可以将整个列表或表格或使用 xpath 动态呈现的内容作为字符串 HTML 节点放入变量中。 (只有内容脚本可以访问 DOM,但不能使用 XMLHTTP 联系 URL)
从内容脚本,使用消息传递,将整个剥离的 DOM 作为字符串发送到后台脚本。 (后台脚本可以与 URL 对话,但不能接触 DOM)。我们使用消息传递来让这些人说话。
您可以使用各种事件循环浏览网页并将每个剥离的 HTML 节点内容传递给后台脚本。
现在使用后台脚本与外部服务器(在本地主机上)对话,这是一个使用 Nodejs/python 创建的简单服务器。只需将整个 HTML 节点作为字符串发送到服务器,服务器会将发布到它的内容保存到文件中,并使用适当的变量来识别页码或 URL。
现在您已经抓取了 AJAX 内容(HTML 节点作为字符串),但这些是部分 html 节点。现在,您可以使用自己喜欢的 XPATH 库将它们加载到内存中,并使用 XPATH 将信息抓取到表格或文本中。
如果你看不懂请评论,我会写得更好。 ( 第一次尝试 )。另外,我正在尝试尽快发布示例代码。
【讨论】:
以上是关于你如何抓取 AJAX 页面?的主要内容,如果未能解决你的问题,请参考以下文章
scrapy实战4抓取ajax动态页面(以糗事百科APP为例子):