如何使用 XMLHttpRequest 在后台下载 HTML 页面并从中提取文本元素?

dar*_*red 3 javascript greasemonkey xmlhttprequest cross-domain tampermonkey

我想制作一个 Greasemonkey 脚本,当您在 URL_1 中时,该脚本会在后台解析 URL_2 的整个 HTML 网页,以便从中提取文本元素。

具体来说,我想在后台下载整个页面的 HTML 代码(烂番茄getElementsByClassName[0]页面)并将其存储在一个变量中,然后使用它从类名为“critic_consensus”的元素中提取我想要的文本。


我在 MDN: HTML in XMLHttpRequest 中找到了这个,所以,我最终得到了这个不幸的不起作用的代码:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
  alert(this.responseXML.getElementsByClassName(critic_consensus)[0].innerHTML);
}
xhr.open("GET", "http://www.rottentomatoes.com/m/godfather/",true);
xhr.responseType = "document";
xhr.send();
Run Code Online (Sandbox Code Playgroud)

当我在 Firefox Scratchpad 中运行它时,它显示此错误消息:

跨源请求被阻止:同源策略不允许读取http://www.rottentomatoes.com/m/godfather/上的远程资源。这可以通过将资源移动到同一域或启用 CORS 来解决。


附言。我不使用烂番茄 API 的原因是他们删除了其中的评论家共识

Bro*_*ams 5

对于跨域请求,获取的站点没有帮助设置宽松的CORS 策略,Greasemonkey 提供了GM_xmlhttpRequest()功能。(大多数其他用户脚本引擎也提供此功能。)

GM_xmlhttpRequest明确设计为允许跨域请求。

要获取您的目标信息,请DOMParser在结果上创建一个。不要使用 jQuery 方法,因为这会导致加载无关的图像、脚本和对象、减慢速度或使页面崩溃。

这是说明该过程的完整脚本:

// ==UserScript==
// @name        _Parse Ajax Response for specific nodes
// @include     http://stackoverflow.com/questions/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant       GM_xmlhttpRequest
// ==/UserScript==

GM_xmlhttpRequest ( {
    method: "GET",
    url:    "http://www.rottentomatoes.com/m/godfather/",
    onload: function (response) {
        var parser  = new DOMParser ();
        /* IMPORTANT!
            1) For Chrome, see
            https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#DOMParser_HTML_extension_for_other_browsers
            for a work-around.

            2) jQuery.parseHTML() and similar are bad because it causes images, etc., to be loaded.
        */
        var doc         = parser.parseFromString (response.responseText, "text/html");
        var criticTxt   = doc.getElementsByClassName ("critic_consensus")[0].textContent;

        $("body").prepend ('<h1>' + criticTxt + '</h1>');
    },
    onerror: function (e) {
        console.error ('**** error ', e);
    },
    onabort: function (e) {
        console.error ('**** abort ', e);
    },
    ontimeout: function (e) {
        console.error ('**** timeout ', e);
    }
} );
Run Code Online (Sandbox Code Playgroud)