2

我正在尝试使用以下代码从使用 nodejs (带有cheerio)的 URL 获取打开的图形元数据。

我有这个东西要填写: var result={};

  for (var ogCounter = 0; ogCounter < metalist.length; ogCounter++) {
    if (!utils.isEmpty(metalist[ogCounter].attribs.property) && !utils.isEmpty(metalist[ogCounter].attribs.content)) {
        if (metalist[ogCounter].attribs.property.indexOf('og') == 0) {
            var ogname = metalist[ogCounter].attribs.property.split(':');
            var property = ogname[1];
            var content = metalist[ogCounter].attribs.content;

            if (utils.isEmpty(result[property])) {
                result[property] = content;
            } else {
                if (result[property].push) {
                    result[property].push(content);
                } else {
                   result[property] = [result[property], content];
                }
            }

        }
    }
}

填充结果后,我在 JSon 中进行了转换,并使用此代码得到如下信息:

type: "video",
image: "http://i3.ytimg.com/vi/fWNaR-rxAic/mqdefault.jpg",
video: [
"http://www.youtube.com/v/fWNaR-rxAic?version=3&amp;autohide=1",
"application/x-shockwave-flash",
"1920",
"1080"
]

但我想要的东西是这样的:

type: "video",
image: "http://i3.ytimg.com/vi/fWNaR-rxAic/mqdefault.jpg",
video: {
"http://www.youtube.com/v/fWNaR-rxAic?version=3&amp;autohide=1",
{ 
type:"application/x-shockwave-flash",
width:"1920",
height:"1080"
}
}

我正在尝试这个“如果”,但它不起作用:

 if (utils.isEmpty(result[property])) {
                    result[property] = content;
                } else {
                    if (result[property].push) {
                        result[property].push(content);
                    } else {
                        var subresult={};
                        subresult[name[2]]=content;
                        subresult[property]=result[property] ;

                        result[property] = subresult;
                    }
                }

我不想循环所有元 2 次,而且我不擅长 javascript 和 nodejs 功能......有什么建议吗?谢谢

4

2 回答 2

0

这是我的答案。@phwd 完全回答了这个问题,但我认为最好制定一个更通用的解决方案,将所有meta标签解析为n级别。

var cheerio = require('cheerio'),
  request = require('request'),
  url = 'http://philippeharewood.com/facebook/video.html',
  result = {},
  attr = function( tag, prop ){ return tag.attribs && tag.attribs[prop] || ""; }

request( url, function( err, res, body ) {

  var metas = cheerio.load(body)('meta')
  var keys = Object.keys(metas)

  keys.forEach(function(i){
    var meta = metas[i],
      property = attr(meta,'property'),
      parts = property.split(":");

    if ( property ) {
      var og = property.split(':'),
        parent = result;

      for ( var j = 0; j < og.length; j++ ){
        var token = og[j],
          current = parent[token],
          name;

        if ( j+1 == og.length ) { // leaf node

          // expected leaf is already a branch so append a name attr
          if ( current instanceof Object ) name = token;
          // leaf should take the value given
          else parent[token] = attr(meta,'content');

        } else { // branch node

          // if no such branch exists, make one
          if ( !(current instanceof Object) ) {
            // if the branch is already a leaf, move value to name attr
            if ( typeof current == "string" ) name = current;
            current = {};
            parent[token] = current;  
          }
        }
        if ( name ) current["name"] = name;
        name = undefined
        parent = current;
      }
    }
  });

  console.log(JSON.stringify( result.og, undefined, 2));

});
于 2012-10-29T10:00:24.907 回答
0

这很棘手,因为您希望如何显示og:video. 我不认为你可以那样做。例如,最简单的方法是为其分配一个标识符name并将其与og:video:width

示例结果

{
  "type": "video.other",
  "url": "http://philippeharewood.com/facebook/video.html",
  "title": "Simple Plan",
  "video": {
    "name": "http://www.youtube.com/v/Y4MnpzG5Sqc?version=3&amp;autohide=1",
    "type": "application/x-shockwave-flash",
    "width": "398",
    "height": "224",
    "release_date": "2012-05-29T21:30"
  }
}

怎么可能做到,

var cheerio = require('cheerio')
var request = require('request')

var url = 'http://philippeharewood.com/facebook/video.html';
var result = {};

request(url, function(error, response, body) {
  var $ = cheerio.load(body);

  var meta = $('meta')
  var keys = Object.keys(meta)

  keys.forEach(function(key){
    if ( meta[key].attribs 
         && meta[key].attribs.property 
         && meta[key].attribs.property.indexOf('og') == 0
       ) 
    {
      var og = meta[key].attribs.property.split(':');

      if(og.length > 2) {
        if(result[og[1]]) {
          if (typeof result[og[1]] == 'string' 
             || result[og[1]] instanceof String
             ) 
          {
            var set = {};
            set['name'] = result[og[1]];
            set[og[2]] = meta[key].attribs.content;
            result[og[1]] = set;
          }
          else {
            ex_set = result[og[1]];
            ex_set[og[2]] = meta[key].attribs.content;
            result[og[1]] = ex_set;
          }
        }
        else {
          var set = {};
          set[og[2]] = meta[key].attribs.content;
          result[og[1]] = set;
        }
      }
      else {
        result[og[1]] = meta[key].attribs.content;
      }
    }
  });

  console.log(JSON.stringify(result, undefined, 2));

});
于 2012-10-24T21:52:57.817 回答