有没有一种方法可以让YQL返回HTML?

11

我正在尝试使用YQL从一系列网页中提取HTML部分。这些页面本身具有略微不同的结构(因此Yahoo Pipes的“获取页面”和其“剪切内容”功能效果不佳),但我感兴趣的片段始终具有相同的class属性。

如果我有这样的HTML页面:

<html>
  <body>
    <div class="foo">
      <p>Wolf</p>
      <ul>
        <li>Dog</li>
        <li>Cat</li>
      </ul>
    </div>
  </body>
</html>

然后使用这样的 YQL 表达式:

SELECT * FROM html 
WHERE url="http://example.com/containing-the-fragment-above" 
AND xpath="//div[@class='foo']"

我得到的是(看起来是无序的?)DOM元素,而我想要的是HTML内容本身。我也尝试过使用 SELECT content,但那只会选择文本内容。我想要HTML。这可能吗?

3个回答

8
您可以编写一个小型的开放数据表格,以发送常规的YQL html表查询并将结果字符串化。以下是示例代码:
<?xml version="1.0" encoding="UTF-8" ?>
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
  <meta>
    <sampleQuery>select * from {table} where url="http://finance.yahoo.com/q?s=yhoo" and xpath='//div[@id="yfi_headlines"]/div[2]/ul/li/a'</sampleQuery>
    <description>Retrieve HTML document fragments</description>
    <author>Peter Cowburn</author>
  </meta>
  <bindings>
    <select itemPath="result.html" produces="JSON">
      <inputs>
        <key id="url" type="xs:string" paramType="variable" required="true"/>
        <key id="xpath" type="xs:string" paramType="variable" required="true"/>
      </inputs>
      <execute><![CDATA[
var results = y.query("select * from html where url=@url and xpath=@xpath", {url:url, xpath:xpath}).results.*;
var html_strings = [];
for each (var item in results) html_strings.push(item.toXMLString());
response.object = {html: html_strings};
]]></execute>
    </select>
  </bindings>
</table>

您可以使用YQL查询来查询该自定义表格,例如:

您可以使用类似以下的YQL查询:

use "http://url.to/your/datatable.xml" as html.tostring;
select * from html.tostring where 
  url="http://finance.yahoo.com/q?s=yhoo" 
  and xpath='//div[@id="yfi_headlines"]/div[2]/ul/li'

编辑:刚刚意识到这是一个相当久远的问题,但至少对于任何偶然发现这个问题的人来说,最终还是有答案的。 :)


太好了!谢谢。我现在唯一的问题是如何将Yahoo Pipes变量传递到YQL表达式中。例如,select * from html.tostring where url=item.link and xpath='//div[@id="foo"]'返回错误“无效的标识符item.link。在此上下文中,me是唯一支持的标识符。”你有什么想法吗?(很抱歉代码片段被搞砸了,看起来评论不允许太多格式) - Joe Shaw
找到了答案:创建一个单独的管道,它接受URL输入,将其插入到字符串构建器中构建YQL查询,并将其附加为YQL小部件的查询。然后在您的主管道中,使用这个新管道并将URL作为其输入传递给它。我想我可能会专门为此开一个新问题,这样人们就不必在本问题的评论中寻找它了。 - Joe Shaw
已打开:http://stackoverflow.com/questions/2889406/how-do-i-pass-a-yahoo-pipes-item-into-a-yql-query - Joe Shaw
2
有点晚了,但是 datatables.org 上提供了类似的东西,如果你想要一个更“官方”的解决方案:http://www.datatables.org/data/htmlstring.xml - esm
我注意到YQL表模式实际上允许produces="HTML"(和CSV),尽管可能没有记录,而且我还没有进行过实验,但可能有更直接的方法来实现这个问题的目标。 - hippietrail
1
@hippietrail:模式允许的内容和目前可用的内容并不总是匹配的。 :) - salathe

2

我曾经遇到过完全相同的问题。解决办法是避免使用YQL,而是使用正则表达式来匹配起始标签和结束标签 :/。这不是最好的解决方案,但如果HTML相对不变,并且模式只是从 <div class='name'><div class='just_after'>`,那么你可以用这个方法。然后你就可以获得中间的HTML。


是的,这也是我最终采取的方法。不幸的是,页面的结构取决于条目的类型,因此我不得不多次拆分源以处理所有不同的类型,并将它们合并/排序回来。真的很麻烦,但它能够工作。 - Joe Shaw

0

YQL将页面转换为XML,然后在其上执行XPath,然后获取DOMNodeList并将其序列化回XML以进行输出(如果需要,则转换为JSON)。您无法访问原始数据。

为什么不能处理XML而不是HTML?


我在使用Yahoo Pipes的上下文中,所以我想将HTML插入到RSS源中,以便由feed阅读器/浏览器呈现。插入XML可能有效,但Pipes YQL模块似乎只是将DOM元素插入文档中;我没有看到获取XML源的方法。 - Joe Shaw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接