【问题标题】:YQL: html table is no longer supportedYQL:不再支持 html 表
【发布时间】:2017-06-08 09:02:09
【问题描述】:

我使用 YQL 获取一些 html 页面以从中读取信息。 从今天开始,我收到返回消息“不再支持 html 表。有关 YQL 使用条款,请参阅 https://policies.yahoo.com/us/en/yahoo/terms/product-atos/yql/index.htm

控制台中的示例:https://developer.yahoo.com/yql/console/#h=select+*+from+html+where+url%3D%22http%3A%2F%2Fwww.google.de%22

雅虎是否停止了这项服务?有人知道雅虎的公告吗?我想知道这是否只是一个错误,或者他们是否真的停止了这项服务......

所有文档仍然存在(html 抓取): https://developer.yahoo.com/yql/guide/yql-select-xpath.html , https://developer.yahoo.com/yql/

不久前我在雅虎的一个 YQL 论坛上发帖,现在这个论坛已经不存在了(或者至少我没有找到它)。您如何联系雅虎以查明该服务是否真的停止了?

最好的问候, 希伯来语3

【问题讨论】:

  • 是的,也不适用于我。他们为我们提供了“YQL 使用条款”页面的链接,但这无济于事。似乎 YQL 服务仍在运行,但由于错误消息指出“HTML 表”查询不再受支持。所以,我试图找到另一种从网页中抓取 HTML 表格的方法。也许还有另一个 YQL 服务可以帮助从网页中提取表格,或者我可以尝试使用 YQL 中的一些替代查询。我想我必须阅读 YQL 上的文档才能找到答案。
  • 这里有同样的问题。破坏了我的脚本并花了一些时间发现不再支持该表。还有其他公共代理(stackoverflow.com/questions/15005500/…),但它们都有一些限制,如果请求太多,可以被阻止,不像雅虎那样有缓存。
  • @user1467483 错误不是由 HTML 表格引起的。它与名为“html”的 YQL 表有关。将 YQL 与任何其他查询语言一样考虑——信息存储在表结构中。关于寻找 YQL 的替代品,这不是必需的。你只需要找到一个替代的 YQL 表。看我的回答
  • 我在 GAE 上使用 YQL html 表 JSON 输出并打算使用 lxml 重构抓取。为了不破坏现有代码的接口,手头有示例 YQL 输出会很有用,尤其是 JSON,它非常奇特。 XML-to-JSON-transformation documentation 不是一个完整的规范(例如,它是如何处理混合节点的?)。请分享示例 html 与 json,例如 this one
  • 这是一个 Python 要点,可用于重构返回 JSON 的 YQL html 查询,方法是使用带有 XPATH 查询的 lxml 模块并将输出转换为 YQL 的 JSON 格式,以避免破坏与其他代码的接口:https://gist.github.com/vicmortelmans/5ee79080249ed5e0a173bc9e6fd426b1

标签: yql


【解决方案1】:

从 2017 年 6 月 8 日起,雅虎似乎确实终止了对 html 库的支持(根据我的错误日志)。似乎还没有任何官方公告。

幸运的是,有一个 YQL 社区库可以用来代替官方 html 库,只需对您的代码库进行少量更改。请参阅htmlstring table in the YQL Console

将您的 YQL 查询更改为引用 htmltable 而不是 html,并在您的 REST 查询中包含社区环境。例如:

/*/ Old code /*/

var site = "http://www.test.com/foo.html";

var yql = "select * from html where url='" + site + "' AND xpath='//div'";

var resturl = "https://query.yahooapis.com/v1/public/yql?q="
    + encodeURIComponent(yql) + "&format=json";

 

/*/ New code /*/

var site = "http://www.test.com/foo.html";

var yql = "select * from htmlstring where url='" + site + "' AND xpath='//div'";

var resturl = "https://query.yahooapis.com/v1/public/yql?q="
    + encodeURIComponent(yql) + "&format=json"
    + "&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

【讨论】:

  • 非常感谢您的提示。我只使用公共版本的 YQL,对于 htmlstring,我必须使用一个进行身份验证。无论如何,我已经完成了 Yahoo YQL - 我现在在稳定性、可用性等方面遇到了几个问题(尽管它是一项免费服务,但我需要可靠性,而这似乎不存在)。我现在确实设置了自己的服务器并使用自己的 Web 服务来获取所需的 html 页面。
  • 我可以在没有身份验证的情况下使用 htmlstring。我想知道你为什么不是。 PS,如果我的答案合适,请考虑将其标记为接受的答案。
  • @blakeo_x 你的答案是正确的,唯一的问题是Yahoo APIs 必须在https 上提供服务,而不是html
  • @user6589814 我可以通过 http 访问 API。尝试时是否收到错误消息?此外,html 表仅作为旧查询的示例提供。我建议的解决方案是使用htmlstring
  • htmlstring 的东西随机工作,有时工作,有时失败
【解决方案2】:

非常感谢您的代码。

它帮助我创建了自己的脚本来阅读我需要的那些页面。我以前从未编写过 PHP,但是通过您的代码和互联网的智慧,我可以根据需要更改您的脚本。

PHP

<?
    header('Access-Control-Allow-Origin: *'); //all
    $url = $_GET['url'];
    if (substr($url,0,25) != "https://www.xxxx.yy") {
       echo "Only https://www.xxxx.yy allowed!";
       return;
    }
    $xpathQuery = $_GET['xpath'];

    //need more hard check for security, I made only basic
   function check($target_url){
       $check = curl_init();
       //curl_setopt( $check, CURLOPT_HTTPHEADER, array("REMOTE_ADDR: $ip", "HTTP_X_FORWARDED_FOR: $ip"));
        //curl_setopt($check, CURLOPT_INTERFACE, "xxx.xxx.xxx.xxx");
        curl_setopt($check, CURLOPT_COOKIEJAR, 'cookiemon.txt');
        curl_setopt($check, CURLOPT_COOKIEFILE, 'cookiemon.txt');
        curl_setopt($check, CURLOPT_TIMEOUT, 40000);
        curl_setopt($check, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($check, CURLOPT_URL, $target_url);
        curl_setopt($check, CURLOPT_USERAGENT,   $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($check, CURLOPT_FOLLOWLOCATION, false);
        $tmp = curl_exec ($check);
        curl_close ($check);
        return $tmp;
    } 

    // get html
    $html = check($url);
    $dom = new DOMDocument();
    @$dom->loadHTML($html);

    // apply xpath filter
    $xpath = new DOMXPath($dom);
    $elements = $xpath->query($xpathQuery);
    $temp_dom = new DOMDocument();
    foreach($elements as $n)   $temp_dom->appendChild($temp_dom->importNode($n,true));
    $renderedHtml = $temp_dom->saveHTML();

    // return html in json response
    // json structure: 
    // {html: "xxxx"}
    $post_data = array(
      'html' => $renderedHtml
    );  
    echo json_encode($post_data); 

?>

Javascript

$.ajax({
    url: "url of service",
    dataType: "json", 
    data: { url: url,
            xpath: "//*"
          },
    type: 'GET',
    success: function() {
             },
    error: function(data) {
           }
}); 

【讨论】:

  • 这可能不是适合所有人的解决方案,因为拥有自己的代理所有请求最终都将来自您的服务器的目标站点。对于某些任务,这可能是不可取的。 YQL 的美妙之处在于您可以访问缓存(有时不是)版本的页面,并且可以访问目标站点,这将看起来像是所需的搜索索引流量。并且要模仿缓存版本以减少您必须存储的请求,有时会存储大量数据。它将不止一个屏幕大小的脚本。所以我认为这不是一个通用的答案。
  • 我同意 SerrNovik。此解决方案是 YQL 的浅层替代方案,而不是使 YQL 按要求运行的方法。值得贡献,但不是对原始问题的合适答案。此外,许多开发人员使用 YQL 从等式中消除 CORS。您的解决方案仅适用于同一主机上的文档。
  • 是的,你没问题,我也喜欢 YQL html 表 - 但 YQL 没有任何警告就停止了服务(至少我没有收到警告),因此我的服务不再工作 - > 从我的角度来看,YQL 不再可靠,我需要更换
【解决方案3】:

尽管 YQL 不再支持 html 表,但我已经意识到,可以进行多次调用,而不是进行一次网络调用并解析结果。例如,我之前的调用如下所示:

select html from rss where url="http://w1.weather.gov/xml/current_obs/KFLL.rss"

这应该给我下面的信息

现在我必须使用这两个:

select title from rss where url="http://w1.weather.gov/xml/current_obs/KFLL.rss"

select description from rss where url="http://w1.weather.gov/xml/current_obs/KFLL.rss"

.. 得到我想要的。我不知道为什么他们会在没有明确列出后备的情况下弃用这样的东西,但您应该能够以这种方式获取数据。

【讨论】:

    【解决方案4】:

    我最近构建了一个名为CloudQuerysource code)的开源工具,提供与yql类似的功能。它能够通过一些点击将大多数网站转换为 API。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 2018-05-17
      • 2012-06-11
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多