代码之家  ›  专栏  ›  技术社区  ›  Robin Rodricks

从AJAX加载的页面中删除HTML

  •  3
  • Robin Rodricks  · 技术社区  · 16 年前

    请建议如何刮除AJAX页面。

    0 回复  |  直到 7 年前
        1
  •  55
  •   Brian R. Bondy    16 年前

    概述:

    所有屏幕抓取首先需要手动查看您想要从中提取资源的页面。在处理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,那么您还可以考虑使用firefox javascript引擎For Java Rhino

    使用.NET进行高级刮片:

    对于复杂的用法,如果您使用的是.Net,也可以考虑使用Microsoft.vsa程序集。最近被ICodeCompiler/CodeDOM取代。

        2
  •  8
  •   mattspain    11 年前

    在我看来,最简单的解决办法是 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();
    });
    
        3
  •  7
  •   sblundy    16 年前

    如果可以,请尝试检查DOM树。 Selenium 这是测试页面的一部分。它还具有单击按钮和跟踪链接的功能,这可能很有用。

        4
  •  4
  •   sw.    12 年前

    使用Ajax或通常使用Javascript刮取web页面的最佳方法是使用浏览器本身或无头浏览器(没有GUI的浏览器)。目前 phantomjs 是一款使用WebKit的无头浏览器。我成功的另一个选择是 HtmlUnit (在Java或.NET中,通过 IKVM ,这是一个模拟浏览器。另一个已知的替代方法是使用一个像 Selenium .

    我写了很多关于这个主题的文章,比如 web scraping Ajax and Javascript sites automated browserless OAuth authentication for Twitter 。在第一篇文章的结尾,有很多额外的资源,我已经从2011年开始编译。

        5
  •  2
  •   wonderchook    16 年前

    取决于ajax页面。屏幕抓取的第一部分是确定页面的工作方式。是否有某种类型的变量可以通过迭代来请求页面中的所有数据?就我个人而言 Web Scraper Plus 对于很多与屏幕抓取相关的任务,因为它便宜,不难启动,非程序员可以让它相对快速地工作。

    附带说明:使用条款可能是您在执行此操作之前需要检查的地方。根据站点的不同,遍历所有内容可能会产生一些标志。

        6
  •  2
  •   TTT    9 年前

    我喜欢 PhearJS ,但这可能部分是因为我建造了它。

    也就是说,这是一个在后台运行的服务,它可以说HTTP(s),并将页面呈现为JSON,包括您可能需要的任何元数据。

        7
  •  2
  •   m0nhawk Pasqui    9 年前

    我认为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
    

    那么URL是:

    http://quote.tool.hexun.com/hqzx/quote.aspx?type=3&market=1&sorttype=3&updown=up&page=1&count=8&time=164330
    
        8
  •  1
  •   Alex    14 年前

    作为一个低成本的解决方案,您也可以尝试 SWExplorerAutomation (瑞典)。该程序为使用HTML、DHTML或AJAX开发的任何Web应用程序创建自动化API。

        9
  •  1
  •   Asclepius    7 年前

    Selenium WebDriver是一个很好的解决方案:您可以编写一个浏览器,并自动执行需要在浏览器中执行的操作。浏览器(Chrome、Firefox等)提供了它们自己的驱动程序,可以使用Selenium。因为它是自动的 真正的浏览器 ,页面(包括javascript和Ajax)的加载方式与使用该浏览器的用户相同。

    缺点是速度很慢(因为您很可能希望等待所有图像和脚本加载,然后再对该页面进行抓取)。

        10
  •  0
  •   Deepan Prabhu Babu    7 年前

    我之前曾链接到麻省理工学院的solvent和EnvJS作为我刮除Ajax页面的答案。这些项目似乎已无法访问。

    出于绝对的必要性,我发明了另一种方法来实际删除Ajax页面,而且它也适用于像findthecompany这样的困难站点,这些站点有方法查找无头javascript引擎,并且不显示任何数据。

    该技术是使用铬合金扩展来做刮擦。Chrome扩展是去除Ajax页面的最好地方,因为它们实际上允许我们访问javascript修改的DOM。技术如下,我一定会在某个时候开放源代码。创建一个chrome扩展(假设您知道如何创建一个扩展,以及它的架构和功能)。这很容易学习和实践,因为有很多样本,

    1. 通过使用xpath,使用内容脚本访问DOM。几乎可以使用xpath将整个列表或表或动态呈现的内容作为字符串HTML节点添加到变量中。(只有内容脚本可以访问DOM,但它们不能使用XMLHTTP联系URL)
    2. 从内容脚本,使用消息传递,将整个剥离的DOM作为字符串发送到后台脚本。(后台脚本可以与url对话,但不能触及DOM)。我们用信息传递来让他们说话。
    3. 您可以使用各种事件在web页面中循环,并将每个剥离的HTML节点内容传递到后台脚本。
    4. 现在使用后台脚本与外部服务器(在本地主机上)对话,这是一个使用Nodejs/python创建的简单脚本。只需将整个HTML节点作为字符串发送到服务器,服务器只需将发布到服务器的内容持久化到文件中,并使用适当的变量来标识页码或url。
    5. 现在,您已经抓取了AJAX内容(HTML节点作为字符串),但这些是部分HTML节点。现在,您可以使用您最喜欢的XPATH库将它们加载到内存中,并使用XPATH将信息刮到表或文本中。

    如果你听不懂,请留言,我可以写得更好。(第一次尝试)。另外,我正试图尽快发布示例代码。