Próbuję pobrać dane z interfejsu API wyszukiwania Bing, a ponieważ istniejące biblioteki wydają się być oparte na starych, wycofanych interfejsach API, chciałem sam spróbować użyć biblioteki request
, która wydaje się być najczęstszą biblioteką do tego. Mój kod wyglądaKodowanie odpowiedzi za pomocą modułu "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 zwraca jakąś JSON i mogę z nim pracować, ale czasami jeśli ciało odpowiedź zawiera dużą ilość niezarejestrowanych znaków ASCII JSON.parse
skarży się, że łańcuch jest uszkodzony. Próbowałem przejść do typu zawartości ATOM, ale nie było różnicy, xml był nieprawidłowy. Sprawdzanie treści odpowiedzi, jaka jest dostępna w wywołaniu zwrotnym request()
, pokazuje zły kod.
Więc próbowałem tego samego żądania z pewnym kodem Pythona, który wydaje się działać dobrze cały czas. Dla porównania:
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())
nie jestem w stanie odtworzyć problemu z mniejszymi odpowiedzi (na przykład ograniczenie liczby wyników) oraz w stanie zidentyfikować pojedynczy wynik, który powoduje problem (poprzez intensyfikację offset). Mam wrażenie, że odpowiedź zostanie odczytana w kawałkach, w jakiś sposób transkodowana i złożona ponownie w zły sposób, co oznacza, że dane json/atom stają się nieważne, jeśli jakiś znak wielobajtowy zostanie podzielony, co dzieje się w przypadku większych odpowiedzi, ale nie małych.
Będąc nowym węzłem, nie jestem pewien, czy jest coś, co powinienem robić (ustawienie kodowania gdzieś? Bing zwraca UTF-8, więc nie wydaje się to konieczne).
Ktoś ma pojęcie o tym, co się dzieje?
FWIW, jestem na OSX 10.8, węzeł jest v0.8.20 zainstalowany przez macports, żądanie jest v2.14.0 zainstalowane przez npm.
TBH Próbowałem zrobić to w ten sposób (choć z użyciem 'https.get' zamiast' .request') zbyt ale nie mogłem go uruchomić, musiałem coś zepsuć. W każdym razie wydaje się, że działa teraz, więc i tak przyjmuję twoją odpowiedź, jeśli ktoś nie zapewni poprawki do używania modułu 'request'. Dzięki! – riffraff
Może to mieć więcej wspólnego z faktem, że JSON jest w rzeczywistości zniekształcony. Jeśli masz ciąg znaków zawierający znak wielobajtowy i przekazujesz 'Content-Length' jako' params.length', wtedy mówisz, że zawartość ma taką samą długość bajtu co liczba znaków w ciągu znaków. Nie dotyczy to znaków wielobajtowych. Zamiast '{" name ":" feeé "}', twój api prawdopodobnie otrzymuje '{" name ":" feeé "' – amsross