使用Bing图像API JavaScript搜索图像

3

我正在尝试使用Bing Search Image API搜索一个我称之为names的项目数组。我已经使用了文档https://learn.microsoft.com/en-us/azure/cognitive-services/bing-image-search/quickstarts/nodejs来开始发送JSON解析请求。当单独调用名称时,我能够收到图像URL,但是当我通过for循环运行bing_image_search函数时,控制台会打印出找不到图像结果的信息,如果它确实找到其中一些图像,则这些图像未按照bing_image_search函数调用每个名称的顺序返回。以下是目前我所做的代码,感谢任何帮助。

  var imagesArr = [];
  let num_results = 1;
  var names = []; // assume already filled with names

  let response_handler = function (response) {
    let body = '';
    response.on('data', function (d) {
        body += d;
    });
    response.on('end', function () {
        let imageResults = JSON.parse(body);
          if (imageResults.value) {
            let imageLink = imageResults.value[0].thumbnailUrl;
            //console.log(`Image result count: ${imageResults.value.length}`);
            //imagesArr.push(imageLink);
            //console.log(imageLink);
            return imageLink;
          }
          else {
            console.log("Couldn't find image results!");
          }
        
          });
    response.on('error', function (e) {
        console.log('Error: ' + e.message);
    });
  
  };

  let bing_image_search = function (search) {
    console.log('Searching images for: ' + search);
    let request_params = {
          method : 'GET',
          hostname : host,
          path : path + '?q=' + encodeURIComponent(search) + '&count=' + num_results,
          headers : {
              'Ocp-Apim-Subscription-Key' : subscriptionKey,
          }
      };
  
      let req = https.request(request_params, response_handler);
      req.end();
    }

  for(index in names) {
    bing_image_search(names[index]);
  }
1个回答

1
您可能想考虑将 bing_image_search 的逻辑包装在一个 Promise 中,以便更轻松地控制流程...看看下面的示例是否能帮助您:
const { RateLimiter } = require("limiter");
const limiter = new RateLimiter({ tokensPerInterval: 3, interval: "second" });

var imagesArr = [];
let num_results = 1;
var names = []; // assume already filled with names

function bing_image_search(search) {
    return new Promise(async (resolve,reject)=>{
        const remainingMessages = await limiter.removeTokens(1);
        console.log('Searching images for: ' + search);
        let request_params = {
            method : 'GET',
            hostname : host,
            path : path + '?q=' + encodeURIComponent(search) + '&count=' + num_results,
            headers : {
              'Ocp-Apim-Subscription-Key' : subscriptionKey,
            }
        };
  
        let req = https.request(request_params, (response)=>{
            let body = '';
            response.on('data', function (d) {
                body += d;
            });
            response.on('end', function () {
                let imageResults = JSON.parse(body);
                if (imageResults.value) {
                    let imageLink = imageResults.value[0].thumbnailUrl;
                    //console.log(`Image result count: ${imageResults.value.length}`);
                    //imagesArr.push(imageLink);
                    //console.log(imageLink);
                    resolve(imageLink);
                }
                else {
                    resolve("Couldn't find image results!");
                }
            });
            response.on('error', function (e) {
                reject(e);
            });       
        });
      
        req.on('error', (e) => {
            reject(e);
        });
      
        req.end();
    })
}

(async()=>{
    let imgUrls = []
    for (const name of names){
        let imgurl = await bing_image_search(name)
        imgUrls.push(imgurl)
    }   
})()

嗨Sully,感谢您的评论。在尝试您的代码时,我遇到了以下语法错误?对此有什么建议吗?"let results = await Promise.all(names.map(bing_image_search)); SyntaxError: await is only valid in async function" - Rajat Khare
抱歉 - 你本可以添加一个.then处理程序,或将其包装在IIFE中(我更新了示例以显示IIFE) - Sully
如果您确定每个200个名称都应该得到响应,那么您可能会在API上达到速率限制。请检查文档以查看是否在时间范围内限制请求的数量...然后您需要添加类似于p-limit或以下内容的东西:https://www.npmjs.com/package/limiter - Sully
我已经更新了示例代码,并提出了一个关于如何整合限制器的建议。它需要进行一些清理,但应该对你有用。 - Sully
你可以在响应处理程序中添加一些日志,看看返回了什么吗? 让req = https.request(request_params, (response)=>{ console.log(response) let body = ''; response.on('data', function (d) { console.log(d) body += d; }); - Sully
显示剩余4条评论

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