如何解析 DOM(反应)

Posted

技术标签:

【中文标题】如何解析 DOM(反应)【英文标题】:How to parse DOM (REACT) 【发布时间】:2015-07-10 11:11:27 【问题描述】:

我正在尝试从网站上抓取数据。该网站使用 Facebook 的 React。因此,我可以使用 Jaunt 解析的源代码与我在使用 Chrome 的检查器检查元素时看到的代码完全不同。

我对这一切知之甚少,但做了一些研究后,我认为这与 DOM 而不是源代码有关。我需要一种方法来获取此 DOM 代码,因为原始源代码不包含我想要的任何内容,但我不知道从哪里开始(即使在这里阅读了很多答案)。

Here 是我要抓取的页面的一个示例。例如,要抓取描述,我想抓取标签之间的内容:

<span class="light-font extended-card-description list-group-item">Example description....</span>

但正如您所见,此元素仅在您“Inspect Element”时出现,而不是在我仅查看页面源时出现。

我对各位天才的问题是,我怎样才能获取这个 DOM 代码并开始抓取我真正想要的元素?

如果我的术语完全不正确,请原谅我,但正如我所说,这对我来说是一个全新的领域,我已经完成了我能做的研究。

非常感谢您!

【问题讨论】:

Jaunt 的网站称它是“不需要 javascript 支持时的理想工具”。如果您正在检查的元素不在源代码中,那么它们很可能是由 Javascript 动态创建的。我猜 Jaunt 是错误的工具。 ***.com/questions/10872382/… ***.com/questions/18539491/… 谢谢@ultranaut。但是,当我尝试使用我提供的链接创建一个 htmlPage 对象时,我得到了一个巨大的错误,你有使用 HtmlUnit 给我额外帮助的经验吗? 你也可以用 HTMLUnitDriver 试试 selenium - code.google.com/p/selenium/wiki/GettingStarted。 【参考方案1】:

ReactJS 与许多其他 Javascript 库/框架一样,使用客户端代码 (Javascript) 来呈现最终的 HTML。这意味着当您、Jaunt 或您的浏览器从服务器获取 HTML 源代码时,它还不包含用户将看到的最终代码。浏览器需要运行页面中包含的 Javascript 程序,以生成您希望抓取的最终内容。

我最喜欢这种工作的工具是CasperJS

它(或者更确切地说是 CasperJS 使用的 PhantomJS 工具)是一个无头浏览器,这意味着它是一个 Webkit 版本(如 Chrome 或 Safari),已经剥离了所有 GUI(窗口、按钮、菜单)。剩下的是可以从终端或 Java 程序运行的工具。它不会在屏幕上显示任何窗口,但会获取您要求它访问的网页;运行它们包含的任何 Javascript;然后响应您的命令,例如“单击此链接”、“给我该文本”、“捕获屏幕截图”等。

让我们从一个简单的ReactJS example开始:

我们想要抓取“Hello John”文本,但是如果您查看纯 HTML 源代码(Ctrl+UAlt +Ctrl+U) 你不会看到它。另一方面,如果您在浏览器中打开控制台并使用以下选择器,您将获得文本:

> document.querySelector('#helloExample .playgroundPreview').textContent
"Hello John"

这是一个简单的 CasperJS 脚本来做同样的事情:

var casper = require("casper").create();

casper.start("http://facebook.github.io/react/index.html", function() 
    this.echo(this.fetchText("#helloExample .playgroundPreview"));
);

casper.run();

您可以将其保存为hello.js 并在终端使用casperjs hello.js 执行它,或者使用等效的Java 代码Runtime.getRuntime().exec(...)

这是一个更好的脚本,它可以避免加载图像和第三方资源(例如 Facebook 按钮、Twitter 按钮、Google Analytics 等),从而将加载时间缩短一半。它还添加了一个waitForSelector 步骤,这样我们就不会冒险在 ReactJS 有机会创建文本之前尝试获取文本。

var casper = require("casper").create(
    pageSettings: 
        loadImages: false
    
);

casper.on('resource.requested', function(requestData, request) 
    if (requestData.url.indexOf("http://facebook.github.io/") != 0) 
        request.abort();
    
);

casper.start("http://facebook.github.io/react/index.html", function() 
    this.waitForSelector("#helloExample .playgroundPreview", function() 
        this.echo(this.fetchText("#helloExample .playgroundPreview"));
    );
);

casper.run();

如何安装 CasperJS

我在使用旧版本的 PhantomJS 和 CasperJS 抓取 ReactJS 和其他现代 Javascript 页面时遇到了一些麻烦,因此我建议从 GitHub 安装 PhantomJS 2.0 和最新的 CasperJS。

对于 PhantomJS,您只需下载 the official 2.0 package。

对于 CasperJS,由于它是一个 Python 脚本,因此您应该能够从 GitHub 上查看最新的提交并将 bin/casperjs 链接到您的 PATH 中。这是适用于 Linux 或 Mac OS X 的脚本:

> git clone git://github.com/n1k0/casperjs.git
> cd casperjs
> ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs

您可能还想从您的bin/bootstrap.js 文件中注释掉打印Warning PhantomJS v2.0 ... 的行。

【讨论】:

感谢所有这些!

以上是关于如何解析 DOM(反应)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用反应酶检查实际的 DOM 节点

使用反应渲染时如何访问现有的 dom 元素?

如何使 Material UI 反应按钮充当 react-router-dom 链接?

如何将来自反应路由器 dom 的链接放在 Material UI 表中

如何在反应路由器dom v4中获取组件中的参数?

优化反应: 虚拟dom解释