2013-02-22 3 views
7

Я пытаюсь получить данные из API поиска Bing, а поскольку существующие библиотеки, по-видимому, основаны на старых API-интерфейсах, которые я прекратил использовать, хотя я бы попытался использовать библиотеку request, который, как представляется, является наиболее распространенной библиотекой для этого. Мой код выглядитКодирование ответа с помощью модуля «request» node.js

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, узел v0.8.20 установлен через macports, запрос v2.14.0 установлен через npm.

ответ

1

Я не уверен в библиотеке запросов, но по умолчанию nodejs работает хорошо для меня. Это также кажется намного легче читать, чем ваша библиотека, и действительно возвращается в куски.

http://nodejs.org/api/http.html#http_http_request_options_callback или HTTPS (как ваш REQ) http://nodejs.org/api/https.html#https_https_request_options_callback (то же самое на самом деле, хотя)

Для вариантов немного подсказка: использование URL разбора

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 должен быть данные, которые вы хочу отправить

+0

ТБХ я пытался сделать это таким образом (хотя с помощью 'https.get' вместо' .request') слишком но я не мог заставить его работать, должно быть, у меня что-то не так. В любом случае, похоже, он работает сейчас, поэтому я буду принимать ваш ответ в любом случае, если кто-то не предоставит исправления для использования модуля 'request'. Благодаря! – riffraff

+1

Возможно, это связано скорее с тем, что JSON на самом деле искажен. Если в нем есть строка с многобайтовым символом, и вы передаете 'Content-Length' как' params.length', то вы говорите, что содержание имеет ту же длину байта, что и количество символов в строке. Это неверно для многобайтовых символов. Вместо '{" name ":" feeé "}', ваш api, вероятно, получает '{" name ":" feeé "' – amsross

0

Я думаю, что ваша аутентификация вашего запроса неверна. Аутентификация должна быть предоставлена ​​перед request.get. См. Документацию для request HTTP authentication. qs - это объект, который должен быть передан в request options так же, как url ​​и auth. Также вы используете тот же req для второго запроса. Вы должны знать, что request.get возвращает поток для 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. Второй объект - это поток ответов. Чтобы использовать его, вы должны использовать данные событий ',' end ',' error 'и' close '.

Обязательно используйте аргументы правильно.

+0

нет, свободный синтаксис правильно задает параметры, он довольно плохо документирован. Моя проблема заключается не в проверке подлинности, я вижу, что она работает, и я получаю аутренированный ответ. Моя проблема - это искаженное тело ответа. – riffraff

0

Вы должны пройти опцию {JSon: истинно}, чтобы включить JSon синтаксический разбор ответа

+0

Проблема заключается в кодировке, а не в формате, если вы читаете вопрос, который я также пробовал с ATOM. Но вопрос - 18 месяцев, поэтому, надеюсь, они его исправили. – riffraff

Смежные вопросы