html嵌套?使用谷歌fetchurl

jas*_*son 0 html dom web-scraping google-apps-script

我正试图从以下网页中获取一个表格

http://www.bloomberg.com/markets/companies/country/hong-kong/

我有一些示例代码,由Phil Bozak友情提供:

使用Google脚本从html中获取表格

它抓住了这个网站的表格:

http://www.airchina.com.cn/www/en/html/index/ir/traffic/

从Phil的代码中可以看出,代码中有很多"getElement()".如果我看一下国航网站的html代码.看起来它嵌套了四次?这就是为什么字符串.getElement?

现在我看一下Bloomberg页面的源代码,用"div"加载它...

问题是有人可以告诉我如何从Bloomberg页面中获取表格吗?

只是对该理论的简要解释也是有用的.谢谢一堆.

Mog*_*dad 6

让我们颠倒你的问题,从理论开始.方法可能是一个更好的词.

您希望获得结构化页面中的特定内容.要做到这一点,你需要一种方法来直接触发元素(如果它以我们可以访问的独特方式标记,可以完成),或者您需要手动或多或少地导航结构.您已经知道如何查看页面的来源,因此您熟悉此步骤.这是Firefox Inspector的屏幕截图,突出显示了我们感兴趣的元素.

截图 -  Firefox Inspector

我们可以看到导致表格的元素的层次结构:html,body,div,div,div.ticker,table.ticker_data.我们还可以看到来源:

<table class="ticker_data">
Run Code Online (Sandbox Code Playgroud)

整齐!它贴上了标签!不幸的是,当我们在脚本中处理HTML时,类信息会被删除.游民.如果是这样的话id="ticker_data",我们可以使用此答案中getElementByVal()实用程序来实现它,并使自己对将来重构页面有一定的免疫力.放一针 - 我们会回来的.

它可以帮助在调试器中可视化.这是一个实用程序脚本 - 在调试模式下运行它,你将准备好你的HTML文档来探索:

/**
 * Debug-run this in the editor to be able to explore the structure of web pages.
 *
 * Set target to the page you're interested in.
 */
function pageExplorer() {
  var target = "http://www.bloomberg.com/markets/companies/country/hong-kong/";
  var pageTxt = UrlFetchApp.fetch(target).getContentText();
  var pageDoc = Xml.parse(pageTxt,true);
  debugger;  // Pause in debugger - explore pageDoc
}
Run Code Online (Sandbox Code Playgroud)

这是我们的页面在调试器中的样子:

截图 - 调试器

您可能想知道编号元素是什么,因为您在源中看不到它们.当XML文档中的同一级别存在多个元素类型时,解析器将它们显示为数组,编号0..n.因此,当我们在调试器中看到0a div时,它告诉我们<div>在该级别的HTML源代码中有多个标记,例如,我们可以将它们作为数组访问.div[0].

好吧,我们背后的理论,让我们继续看看我们如何通过蛮力访问桌子.

知道了层次结构,包括调试器中显示的div数组,我们可以做到这一点,ala Phil先前的答案.我会做一些奇怪的缩进来说明文档结构:

...
var target = "http://www.bloomberg.com/markets/companies/country/hong-kong/";
var pageTxt = UrlFetchApp.fetch(target).getContentText();
var pageDoc = Xml.parse(pageTxt,true);
var table = pageDoc.getElement()
             .getElement("body")
               .getElements("div")[0]      // 0-th div under body, shown in debugger
                 .getElements("div")[5]    // 5-th div under there
                   .getElement("div")      // another div
                     .getElement("table"); // finally, our table
Run Code Online (Sandbox Code Playgroud)

作为所有这些.getElement()调用的更紧凑的替代方案,我们可以使用点符号进行导航.

var table = pageDoc.getElement().body.div[0].div[5].div.table;
Run Code Online (Sandbox Code Playgroud)

就是这样.

让我们回到那个固定的想法.在调试器中,我们可以看到元素附加了各种属性.特别是,div [5]上有一个"id",它包含包含表格的div.请记住,在源代码中我们看到了"类"属性,但请注意它们并没有这么做.

截图 - 调试器2

尽管如此,一个善意的程序员将这个"id"放在适当的位置意味着我们可以做到这一点,getDivById()从之前的问题:

var contentDiv = getDivById( pageDoc.getElement().body, 'content' );
var table = contentDiv.div.table;
Run Code Online (Sandbox Code Playgroud)

如果他们走动的东西,我们可能仍然能够找到该表,而无需更改代码.

一旦你拥有了table元素,你就已经知道该怎么做了,所以我们在这里完成了!