YQL: HTML表格不再受支持。

18
我使用YQL来获取一些html页面并从中读取信息。从今天起,我收到了返回消息“不再支持HTML表。请参见https://policies.yahoo.com/us/en/yahoo/terms/product-atos/yql/index.htm以获取有关YQL使用条款的信息。
例如,在控制台中: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.htmlhttps://developer.yahoo.com/yql/ 一段时间以前,我在雅虎的YQL论坛上发帖,现在这个论坛已经不存在了(或者至少我找不到了)。如何联系雅虎以确定这项服务是否真的停止了?
此致, hebr3

是的,对我也不起作用。他们给了我们一个“YQL使用条款”页面的链接,但没有帮助。似乎YQL服务仍在运行,但正如错误消息所述,“HTML表格”查询不再受支持。因此,我正在尝试找到另一种从网页中抓取HTML表格的方法。也许还有其他的YQL服务可以帮助从网页中提取表格,或者有一些替代的YQL查询可以尝试。我想我将不得不阅读关于YQL的文档来找出答案。 - user1467483
这里也有同样的问题。我的脚本出了问题,花了一些时间才发现这个表格不再受支持。还有其他公共代理(https://dev59.com/tmUp5IYBdhLWcg3w1qMi),但它们都有一些限制,并且如果请求太多,它们可能会被阻止,不像 Yahoo 那样具有缓存功能。 - Sergey Novikov
@user1467483 错误不是由于HTML表格引起的。它与名为“html”的YQL表相关。将YQL视为任何其他查询语言--信息存储在表结构中。关于寻找替代YQL的问题,这并不是必要的。您只需要找到一个替代的YQL表即可。请参阅我的答案。 - blakeo_x
我正在使用YQL HTML表格JSON输出在GAE上,并打算使用lxml重构爬虫。为了不破坏现有代码的接口,最好随手准备一些YQL输出样本,特别是JSON格式,因为它相当奇特。XML-to-JSON转换文档并不是一个完整的规范(例如如何处理混合节点?)。请分享HTML与JSON的示例,例如这个 - vicmortelmans
这里有一个Python要点,可用于重构使用lxml模块和XPATH查询将YQL html查询返回JSON,并将输出转换为YQL的JSON格式,以避免破坏其他代码的接口:https://gist.github.com/vicmortelmans/5ee79080249ed5e0a173bc9e6fd426b1 - vicmortelmans
4个回答

18

据我的错误日志显示,雅虎于2017年6月8日确实结束了对html库的支持。目前还没有任何官方公告。

幸运的是,有一个YQL社区库可以用来替代正式的html库,而且只需要对您的代码库进行少量更改。请参见YQL控制台中的htmlstring表

将您的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";

3
非常感谢您提供的提示。我只使用YQL的公共版本,要获取htmlstring,我需要使用需要身份验证的版本。无论如何,我已经放弃使用Yahoo YQL了 - 我在稳定性、可用性等方面遇到了多个问题。(虽然它是一个免费服务,但我需要可靠性,而这似乎并不存在)。我现在已经搭建了自己的服务器,并使用自己的 Web 服务来获取所需的 html 页面。 - hebr3
我能够在没有身份验证的情况下使用htmlstring。我想知道为什么你不能。另外,如果我的回答合适,请考虑将其标记为接受的答案。 - blakeo_x
2
htmlstring 的功能表现不稳定,有时能正常工作,有时会失败。 - Muhammad Faisal Iqbal
我遇到了htmlstring有时工作,有时不工作的情况。似乎是50%/50%的概率。我们是否有更可靠的服务解决方案? - folktrash
显示剩余6条评论

0
非常感谢您的代码。
它帮助我创建了自己的脚本来阅读我需要的那些页面。之前我从未编写过 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) {
           }
}); 

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

0

尽管YQL不再支持HTML表格,但我意识到,与其进行一次网络调用并解析结果,不如进行多次调用。例如,我的调用之前看起来是这样的:

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

这应该给我以下信息

enter image description here

现在我必须使用这两个:

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"

.. 才能得到我想要的。我不知道为什么他们会废弃这样的东西,而没有明确列出回退,但你应该能够以这种方式获取数据。


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

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