【问题标题】:AWS lambda function to retrieve favicon url of a web site only gets partial html using node.js request module用于检索网站的 favicon url 的 AWS lambda 函数仅使用 node.js 请求模块获取部分 html
【发布时间】:2017-09-07 22:46:55
【问题描述】:

我正在尝试创建一个 Amazon Web Services lambda 函数,该函数将返回网站图标的 url。

lambda 函数使用 2 个 node.js 模块: 1) 请求 2) 快乐

作为一个测试用例,我使用了:event = { "url": "www.github.com" }。

代码没有执行失败,但它似乎只收集了网站的部分 html 并返回一个空字符串 ("") 而不是 GitHub 网站的 favicon url。

这里是 index.js 的代码:

'use strict';

const request = require("node_modules/request");
const cheerio = require("node_modules/cheerio");
var faviconUrl = "";

console.log('Loading lambda function');

function getFaviconUrl(url){
    var urlParts = url.replace('http://','').replace('https://','').split(/[/?#]/);
    var domain = "https://" + urlParts[0];
    var options = {
        url: domain,
        method: "GET",
        headers: {
            "Accept": "text/html"
        }
    };
    request(options, function (error, response, html){
        if (!error && response.statusCode == 200) {
            const $ = cheerio.load(html);
            console.log(html);
            $("link", "head", html).each(function(i, element){
                console.log(element);
                const rel = $(element).attr("rel");
                if (rel === "icon" || rel === "shortcut icon" || rel === "fluid-icon") {
                  faviconUrl = $(element).attr("href");
                  return false;
                }
            });
            if (faviconUrl.indexOf("/") === 0) { // If path returned is relative
                faviconUrl = "https://" + domain + faviconUrl;
            }
        }
    });
}

exports.handler = (event, context, callback) => {
    getFaviconUrl(event.url);
    callback(null, faviconUrl)
}

这是 Lambda 管理控制台中显示的结果:

</div>
  </div>
</div>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error">
    <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
    <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
    </button>
    You can't perform that action at this time.
  </div>


    <script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/compat-91f98c37fc84eac24836eec2567e9912742094369a04c4eba6e3cd1fa18902d9.js"></script>
    <script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-4b1b3e45ebb896ec5555a60b6a57072c698f1b4b86b76aa0b4fe1067f440b1f3.js"></script>
    
    <script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-ae14d253dbc91b402aece489d3993239e510fd1c15fc805402943b552f315d73.js"></script>
    
    
    
    
  <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
    <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
    <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
    <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
  </div>
  <div class="facebox" id="facebox" style="display:none;">
  <div class="facebox-popup">
    <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
    </div>
    <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
      <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
    </button>
  </div>
</div>


  </body>
</html>

【问题讨论】:

  • 你是怎么调用这个函数的?在我看来这是一个异步问题——你的回调将在 HTTP 请求开始时触发,而不是在它完成时触发。您需要在 HTTP 请求的成功回调中调用您的回调。
  • 同时,我只是通过单击 Lambda 管理控制台中的测试按钮进行测试。如果我将回调放在请求部分,那么它超出了范围!不知道请求完成后如何触发回调。

标签: javascript node.js amazon-web-services lambda


【解决方案1】:

您需要在request() 调用完成时触发回调。

更改您的exports.handler,以便将您的回调传递给异步函数:

exports.handler = (event, context, callback) => {
    getFaviconUrl(event.url, callback);
}

...然后在您的getFaviconUrl() 函数中,在设置faviconUrl 后触发回调。这应该意味着您的回调函数仅在网站图标设置为某项后才会执行。

【讨论】:

  • 原来我正在检索整个 HTML,但 Lambda 管理控制台上显示了部分日志!必须单击整个 CloudWatch 日志组才能查看整个日志!
  • 我从 HTML 中提取链接的方式也有错误。无论如何,您关于在哪里放置回调的建议起到了作用!它终于起作用了。非常感谢马特!
  • 没问题,很高兴为您提供帮助!
  • index.js 的工作版本可以在这里找到:github.com/odebroqueville/getFaviconUrl
  • 酷——不管怎样,你可以使用npm来安装你的依赖并将它们存储在一个package.json文件中,然后你不需要提交(巨大的)node_modules目录,在你的代码中你可以只写require('request') 就可以了。
猜你喜欢
  • 2017-06-12
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 2019-04-14
相关资源
最近更新 更多