如何使用 DuckDuckGo 的搜索自动完成建议

Posted

技术标签:

【中文标题】如何使用 DuckDuckGo 的搜索自动完成建议【英文标题】:How to use DuckDuckGo's search autocomplete suggestions 【发布时间】:2021-01-10 20:52:06 【问题描述】:

我正在将我的个人搜索建议从 google 转移到 dadduckgo,但我缺少一些简单的方法来使它工作。我正在使用jQuery-UI's autocomplete framework。

我的搜索表单

<form action="https://duckduckgo.com/?q=" method="post" id="search">
    <input type="text" name="query" value="" autocomplete="off">
    <button type="submit">Search</button>
</form>

我的 jQuery

$( "#search input[type=text]" ).autocomplete(

    delay: 0,
    minLength: 1,
    position:  my: "left top-3" ,
    source: function( request, response )
    
     // var suggestURL = "https://www.google.com/complete/search?client=firefox&q=%QUERY";
        var suggestURL = "https://duckduckgo.com/ac/?q=%QUERY&type=list";

        suggestURL = suggestURL.replace( "%QUERY", request.term );

        $.ajax(
            method: "GET",
            dataType: "jsonp",
            jsonpCallback: "jsonCallback",
            url: suggestURL,
            success: function( data )
            
                response( data[1] );
            ,
            error: function( jqXHR, textStatus, errorThrown )
            
                console.log( textStatus, errorThrown );
            
    
);

google 的查询返回:

https://suggestqueries.google.com/complete/search?client=firefox&q=foobar&callback=jsonCallback&_=1600956954436

jsonCallback && jsonCallback(["foobar",["foobar","foobar meaning","foobar google","foobar challenge","foobar2000 skins","foobar2k","foobar2000 themes","foobar2000 download","foobar2000 mac","foobar themes"],[],"google:suggestsubtypes":[[433],[],[],[],[],[],[],[],[],[]]])

duckduckgo 的查询返回:

https://ac.duckduckgo.com/ac/?q=foobar&type=list&callback=jsonCallback&_=1600956892202

["foobar",["foobar2000","foobar","foobar2000 download","foobar ape","foobar2000 layout","foobar2000 decoder","foobar2000 tak","foobar2000 dsp"]]

两者之间的区别似乎是jsonCallback &amp;&amp; jsonCallback([data]) 包含在谷歌查询中,我不明白它们为什么不同或如何解决。

编辑 1

在js中添加一些错误处理后,我得到的错误是:

parsererror Error: jsonCallback was not called

编辑 2

在深入研究之后,我认为 DDG 的服务器不允许这样做。据我了解,他们的服务器需要发送适当的响应,但我认为它不会这样做。

【问题讨论】:

你在哪里可以找到 duckduckgo 自动完成 api 文档?我正在寻找这个,但在他们的网站上我找不到任何有关的文档 遗憾的是没有。相信我。 我已经注意到了。获得一些信息的唯一方法是检查他们的搜索页面。我能够找到这个端点https://duckduckgo.com/ac/?q=param&amp;kl=wt-wt,但我不知道&amp;kl=wt-wt 参数的用途 &amp;kl=wt-wt 是 DDG 为其网站格式化 JSON 结果的内部方法。 CORS 问题与客户端有关。我过去处理过这个错误,你可以看看这个 developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch ,你需要将 credentials 参数设置为 includemode* 。如果这不起作用尝试使用将保存请求并将响应传回您的客户端应用程序的代理 【参考方案1】:

请看:https://duckduckgo.com/api

要自己使用它,您可以使用下面列出的语言库之一,或简单地将“&format=json”(或 xml,如果您愿意)添加到 api 子域中的任何查询 URL,例如

https://api.duckduckgo.com/?q=DuckDuckGo&format=json

以下是使用要求:

在您使用我们的 API 的每个地方对我们和任何基础来源进行归属。对于来源,您可以链接到来源的相关详细信息页面。对我们来说,您可以使用我们的徽标(并链接到特定结果页面)说出 DuckDuckGo 的结果。 非商业用途,除非您得到我们的电子邮件批准(尽管我们通常对任何不粗略的东西都很好)。 使用描述性的 t 参数,即将 &t=nameofapp 附加到您的请求中。

我们的总体目标是让更多人使用 DuckDuckGo,因此请记住这一点。

q: query

format: output format (json or xml)

If format=='json', you can also pass:
callback: function to callback (JSONP format)

这适用于 JSONP:https://jsfiddle.net/Twisty/rqdtv9sn/86/

这里的问题是这些不是建议,而那些的 URL,https://ac.duckduckgo.com/ac/ 不想与 CORS 配合得很好。您可以使用 FETCH API 来绕过它,但即使请求失败或无法解析,这也只是继续执行 Promise。

因此,在 DDG 提供 Suggestion API 之前,您大多不走运。

这里讨论了一些潜在的其他选项:https://www.sitepoint.com/jsonp-examples/

var script = $("<script />", 
    src: "https://ac.duckduckgo.com/ac/?q=" + req.term,
    type: "application/json"
  
);

虽然这行得通,但对我们帮助不大,因为我们无法获取其中包含的数据。

示例:https://jsfiddle.net/Twisty/rqdtv9sn/89/

浏览器显示响应,但随后出现解析错误。

【讨论】:

明天我将尝试您在 sitepoint.com 上链接的优秀文章中提到的代理示例。感谢您为我解决这个问题。【参考方案2】:

这适用于任何想要在其服务器上使用jQueryUI's autocomplete framework 设置 DuckDuckGo 的搜索自动完成建议的人。

默认情况下you're not allowed to scrape/get data across domains with javascript,所以我不得不在我的服务器上创建一个代理文件来绕过这些限制。

我在这种情况下的挂断是,如果您在请求中传递某些变量,谷歌的搜索自动完成建议服务器明确允许这些 CORS 违规。

这是我的代码,用于让 DuckDuckGo 的搜索自动完成建议在我的网页上运行:

index.php

<form action="https://duckduckgo.com/?q=" method="post" id="search">
    <input type="text" name="query" value="" autocomplete="off">
    <button type="submit">Search</button>
</form>

javascript.js

$( "#search input[type=text]" ).autocomplete(

    delay: 0,
    minLength: 1,
    position:  my: "left top-3" ,
    source: function( request, response )
    
        var suggestURL = "https://www.example.com/proxy-duckduckgo.php?q=%QUERY";

        suggestURL = suggestURL.replace( "%QUERY", request.term );
        suggestURL = suggestURL.replace( / /g, "+" )

        $.ajax(
            method: "GET",
            dataType: "json",
            url: suggestURL,
            success: function( data )
            
                 response( data[1] );
            ,
            error: function( jqXHR, textStatus, errorThrown )
            
                console.log( textStatus, errorThrown );
            
        );
    
);

proxy-duckduckgo.php

<?php

$query = isset( $_GET['q'] ) ? str_replace( ' ', '+', $_GET['q'] ) : 'example';

$url = 'https://duckduckgo.com/ac/?q='.$query.'&type=list';

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
$html = curl_exec( $ch );
curl_close( $ch );

echo $html;

【讨论】:

以上是关于如何使用 DuckDuckGo 的搜索自动完成建议的主要内容,如果未能解决你的问题,请参考以下文章

使用 json 数据自动完成建议和搜索

Angular 2/4 自动完成搜索框

创建一个基本的自动完成建议列表

如何格式化自动完成建议? [关闭]

程序员常用资源工具集合(建议收藏)

使用 Google PLACES Api 搜索查看自动完成建议