7

我正在尝试从 Bing 搜索 API 获取数据,并且由于现有的库似乎是基于旧的已停产的 API,因此我会尝试使用该request库,这似乎是最常见的库。我的代码看起来像

var SKEY           =  "myKey...." , 
    ServiceRootURL =  'https://api.datamarket.azure.com/Bing/Search/v1/Composite';

function getBingData(query, top, skip, cb) {
    var params = {
         Sources: "'web'", 
         Query: "'"+query+"'", 
         '$format': "JSON", 
         '$top': top, '$skip': skip
       },
       req = request.get(ServiceRootURL).auth(SKEY, SKEY, false).qs(params);
    request(req, cb)
}

getBingData("bookline.hu", 50, 0, someCallbackWhichParsesTheBody)

Bing 返回一些 JSON,我有时可以使用它,如果响应正文包含大量非 ASCII 字符JSON.parse,则会抱怨该字符串格式错误。我尝试切换到 ATOM 内容类型,但没有区别,xml 无效。检查request()回调中可用的响应正文实际上显示了错误的代码。

所以我用一些 python 代码尝试了同样的请求,而且它似乎一直都可以正常工作。以供参考:

r = requests.get(
       'https://api.datamarket.azure.com/Bing/Search/v1/Composite?Sources=%27web%27&Query=%27sexy%20cosplay%20girls%27&$format=json', 
        auth=HTTPBasicAuth(SKEY,SKEY))
stuffWithResponse(r.json())

我无法用较小的响应重现问题(例如,限制结果的数量)并且无法识别导致问题的单个结果(通过增加偏移量)。我的印象是响应被分块读取,以某种方式转码并以错误的方式重新组装回来,这意味着如果某些多字节字符被拆分,则 json/atom 数据将变得无效,这发生在较大的响应上,而不是较小的响应上。

作为节点的新手,我不确定是否应该做些什么(在某处设置编码?Bing 返回 UTF-8,所以这似乎不需要)。

有人知道发生了什么吗?

FWIW,我在 OSX 10.8 上,节点是通过 macports 安装的 v0.8.20,请求是通过 npm 安装的 v2.14.0。

4

3 回答 3

1

我不确定请求库,但默认的 nodejs 对我来说效果很好。它似乎也比您的图书馆更容易阅读,并且确实以块的形式返回。

http://nodejs.org/api/http.html#http_http_request_options_callback 或 https (就像你的请求)http://nodejs.org/api/https.html#https_https_request_options_callback(虽然一样)

对于选项一点提示:使用 url parse

var url = require('url');

var params = '{}'

var dataURL = url.parse(ServiceRootURL);
var post_options = {  
    hostname: dataURL.hostname,
    port: dataURL.port || 80,
    path: dataURL.path,
    method: 'GET',  
    headers: {  
        'Content-Type': 'application/json; charset=utf-8',  
        'Content-Length': params.length  
    }  
};

显然 params 需要是您要发送的数据

于 2013-02-22T14:44:47.837 回答
0

我认为您的请求身份验证不正确。必须在 request.get 之前提供身份验证。请参阅请求 HTTP 身份验证的文档。qs是一个对象,必须像 url 和 auth 一样传递给请求选项。您也使用相同req的第二个请求。您应该知道 request.get 为给定的 url 返回一个流。您的下一个请求使用req将出错。

如果您只需要 HTTPBasicAuth,这也应该有效

//remove req = request.get and subsequent request
request.get('http://some.server.com/', {
  'auth': {
    'user': 'username',
    'pass': 'password',
    'sendImmediately': false
  }
 },function (error, response, body) {
});

回调参数有 3 个参数。第一个是适用时的错误(通常来自 http.Client 选项而不是 http.ClientRequest 对象)。第二个是 http.ClientResponse 对象。第三个是响应体 String 或 Buffer。第二个对象是响应流。要使用它,您必须使用事件“数据”、“结束”、“错误”和“关闭”。

请务必正确使用参数。

于 2013-02-22T19:18:25.110 回答
0

您必须传递选项 {json:true} 才能启用响应的 json 解析

于 2014-09-17T14:52:26.877 回答