2017-08-10 60 views
1

我的最终目标是让我的应用程序显示来自给定用户的500px.com帐户(这是一个摄影网站)的X最新图像的缩略图。就我所知,该网站没有API,但它确实有针对个人用户的rss订阅源,即https://500px.com/janedoe/rss,它会吐出xml。如何在Node.js中从xml中获取url?

使用xml2js,我可以将xml解析为一个js对象,然后导航到具有包含我想要的url的html的“description”容器,就像这样(这只是使用第一个项目的概念证明rss feed):

var express = require('express'); 
var router = express.Router(); 
var request = require('request'); 
var parseString = require('xml2js').parseString; 

var EventEmitter = require('events').EventEmitter; 
var body = new EventEmitter(); 

/* GET home page. */ 
router.get('/', function(req, res, next) { 


    request("https://500px.com/janedoe/rss", function(error, response, data) { 
     body.data = data; 
     body.emit('update'); 
    }); 

    body.on('update', function() { 
     parseString(body.data, function (err, result) { 
      var photoLink = result.rss.channel[0].item[0].description[0]; 
      res.render('index', { title: 'Express', photoName}); 
     }); 
    }); 



}); 

这会将“!CDATA”标记的整个html内容放入photoLink变量中。我想要做的是定位该html内的img src中的内容,以便我可以将网址作为字符串传递给页面。

我可以设想用字符串的方法来寻找第一个“IMG SRC”标签,然后读取直到地址结束,但是否有更优雅,更简便的方法来做到这一点?

+0

没什么大不了的,真的。使用XML解析器解析RSS并导航到有问题的元素以提取HTML文本。使用HTML解析器解析HTML并导航到所涉及的元素以提取属性值。你绝对不应该做的一件事是“使用字符串方法”。 – Tomalak

+0

由于您已经完成了第1步(RSS解析),所有剩下的就是第2步(HTML解析)。看看[cheerio](https://github.com/cheeriojs/cheerio)(基本上是jQuery for node)来帮助你。 – Tomalak

+0

谢谢!使用cheerio工作得很好。 – testingtesting

回答

2

试试这个:在这个例子中,我发现所有的图片网址

const transform = require('camaro') 
const cheerio = require('cheerio') 

const xml = require('fs').readFileSync('feed.xml', 'utf-8') 

const template = { 
    data: ['//item/description', '.'] 
} 

const result = transform(xml, template) 

const links = result.data.map(html => { 
    const $ = cheerio.load(html) 
    const links = $('img') 
    const urls = [] 
    $(links).each(function(i, link) { 
     urls.push($(link).attr('src')) 
    }) 
    return urls 
}) 

console.log(links) 

输出:

[ [ 'https://drscdn.500px.org/photo/629350/m%3D900/v2?webp=true&sig=4a9fa5788049efb196917cc3f1a55601af901c7157b59ec86c8aa3378c6ee557' ], 
    [ 'https://drscdn.500px.org/photo/625259/m%3D900/v2?webp=true&sig=55eab44535f05625ad25dae3e805b2559c1caeb4c97570d04ee0a77c52c7fb19' ], 
    [ 'https://drscdn.500px.org/photo/625253/m%3D900/v2?webp=true&sig=174d1b27e6f87e0a98192cf6ae051301681a51beb7297df9733956d2763af163' ], 
    [ 'https://drscdn.500px.org/photo/509064/m%3D900/v2?webp=true&sig=698e56114e1d8b67ad11823390f8456ae723d3a389191c43192718f18213caa8' ], 
    [ 'https://drscdn.500px.org/photo/509061/m%3D900/v2?webp=true&sig=2998212f82a1c3428cebb873830a99b908f463474045d4e5ebba3257808685dd' ], 
    [ 'https://drscdn.500px.org/photo/509060/m%3D900/v2?webp=true&sig=8082904fe1935c51fc301a0d10529475ee15124d3797f69cbaeac3fd6c5f0dcb' ], 
    [ 'https://drscdn.500px.org/photo/509056/m%3D900/v2?webp=true&sig=4b85086a7bf55709e77febb202636b0e09415c8ca3fc3657bfb889ad827b3cab' ] ] 
+0

谢谢 - 这种方法运作良好。它看起来像camaro执行与xml2js相同的功能,但速度更快。 – testingtesting

+0

@testingtesting是的,这是camaro的主要目的。并能够转换xml;不只是转换。 –

0

你并不需要为这个完整的解析器只是正则表达式做到这一点:

var links = []; 
var re = new RegExp("<img.*?src=['\"](.*?)['\"].*?>", "gmi"); 
var res; 

while(res = re.exec(body)) links.push(res[1]); 

实施例:

var a = '<div class="quote"><div class="quote-profile"><img alt="voyages-sncf.com logo" class="img-responsive img-circle" style="height: 80px" src="/img/app_website/index/logo.jpg"> </div><!--//profile--><img alt="voyages-sncf.com logo" class="img-responsive img-circle" style="height: 80px" src="/img/app_website/index/logo2.jpg" data-attr = "lkjlk"/>' 

var links = []; 
var re = new RegExp("<img.*?src=['\"](.*?)['\"].*?>", "gmi"); 
var res; 

while(res = re.exec(a)) links.push(res[1]); 
//["/img/app_website/index/logo.jpg", "/img/app_website/index/logo2.jpg"] 
+0

请不要推荐解析HTML的正则表达式。这已被驳回了一百万次。这是非常糟糕的建议。 *“但它避免了一个完整的解析器”*不是理由。 HTML解析器的方式比恰好正则表达式更复杂,因为正则表达式是不能够解析HTML的。 – Tomalak