无法从Goodreads RSS Feed的Element Extensions提取图片URL
Goodreads RSS Feed 提取
book_image_url问题解决 问题描述
读取Goodreads RSS Feed时,标题等基础信息可正常获取,但无法从book_image_url元素提取图片URL。以下是Feed中单个item的XML示例:
<item> <guid><![CDATA[https://www.goodreads.com/review/show/5692294949?utm_medium=api&utm_source=rss]]></guid> <pubDate><![CDATA[Sun, 23 Jul 2023 11:28:33 -0700]]></pubDate> <title>Supergirl: Woman of Tomorrow</title> <link><![CDATA[https://www.goodreads.com/review/show/5692294949?utm_medium=api&utm_source=rss]]></link> <book_id>59854151</book_id> <book_image_url><![CDATA[https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1639946077l/59854151._SY75_.jpg]]></book_image_url> <book_small_image_url><![CDATA[https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1639946077l/59854151._SY75_.jpg]]></book_small_image_url> <book_medium_image_url><![CDATA[https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1639946077l/59854151._SX98_.jpg]]></book_medium_image_url> <book_large_image_url><![CDATA[https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1639946077l/59854151.jpg]]></book_large_image_url> <book_description><![CDATA[<b>It’s Supergirl like you’ve never seen her before, in a character-defining sci-fi/fantasy masterpiece from Mister Miracle writer Tom King and Wonder Woman artist Bilquis Evely!</b><br /><br />Kara Zor-El has seen some epic adventures over the years, but she now finds her life without meaning or purpose. Here she is, a young woman who saw her planet destroyed and was sent to Earth to protect a baby cousin who ended up not needing her. What was it all for? Wherever she goes, people only see her through the lens of Superman’s fame.<br /><br />Just when Supergirl thinks she’s had enough, everything changes. An alien girl seeks her out for a vicious mission. Her world has been destroyed, and the bad guys responsible are still out there. She wants revenge, and if Supergirl doesn’t help her, she’ll do it herself, whatever the cost. Now a Kryptonian, a dog, and an angry, heartbroken child head out into space on a journey that will shake them to their very core. <br /> <br />This volume collects <i>Supergirl: Woman of Tomorrow #1-8.</i>]]></book_description> <book id="59854151"> <num_pages>224</num_pages> </book> <author_name>Tom King</author_name> <isbn>1779515685</isbn> <user_name>Robert</user_name> <user_rating>5</user_rating> <user_read_at><![CDATA[Sun, 21 May 2023 00:00:00 -0700]]></user_read_at> <user_date_added><![CDATA[Sun, 23 Jul 2023 11:28:33 -0700]]></user_date_added> <user_date_created><![CDATA[Fri, 14 Jul 2023 10:10:46 -0700]]></user_date_created> <user_shelves></user_shelves> <user_review></user_review> <average_rating>4.30</average_rating> <book_published>2022</book_published> <description> <![CDATA[ <a href="https://www.goodreads.com/book/show/59854151-supergirl?utm_medium=api&utm_source=rss"><img alt="Supergirl: Woman of Tomorrow" src="https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1639946077l/59854151._SY75_.jpg" /></a><br/> author: Tom King<br/> name: Robert<br/> average rating: 4.30<br/> book published: 2022<br/> rating: 5<br/> read at: 2023/05/21<br/> date added: 2023/07/23<br/> shelves: <br/> review: <br/><br/> ]]> </description> </item>
使用的C#代码如下:
var reader = XmlReader.Create(_goodreadsSettings.GoodreadsProfileUrl); var feed = SyndicationFeed.Load(reader); var feedItems = limit > 0 ? feed.Items.Take(limit) : feed.Items; var items = feedItems.Select(i => { //NOTE: I'm doing this in this way because there is no namespace on these elements var syndicationElementExtensions = i.ElementExtensions .Where(e => e.OuterName == "book_image_url" && e.OuterNamespace == "").ToList(); //cannot preview the value of this variable in Visual Studio at all, so I can't tell what's happening var imageUrl = syndicationElementExtensions .Select(e => e.GetObject<XmlElement>().SelectSingleNode("book_image_url")?.InnerText) .FirstOrDefault(); var link = i.Links.FirstOrDefault()?.Uri.AbsoluteUri; return new GoodreadsItem { Title = i.Title.Text, Summary = i.Summary.Text, Url = link, ImageUrl = imageUrl, }; }); return items;
即时窗口显示syndicationElementExtensions存在对应元素,但无法提取图片URL。
问题原因
调用e.GetObject<XmlElement>()后,得到的就是<book_image_url>元素本身,此时再用SelectSingleNode("book_image_url")去查找子节点,自然找不到匹配项,因为当前节点就是目标元素。
修正方案
直接获取XmlElement的InnerText即可,它会自动解析CDATA中的内容:
var reader = XmlReader.Create(_goodreadsSettings.GoodreadsProfileUrl); var feed = SyndicationFeed.Load(reader); var feedItems = limit > 0 ? feed.Items.Take(limit) : feed.Items; var items = feedItems.Select(i => { var imageUrl = i.ElementExtensions .FirstOrDefault(e => e.OuterName == "book_image_url" && e.OuterNamespace == "") ?.GetObject<XmlElement>()?.InnerText; var link = i.Links.FirstOrDefault()?.Uri.AbsoluteUri; return new GoodreadsItem { Title = i.Title.Text, Summary = i.Summary.Text, Url = link, ImageUrl = imageUrl, }; }); return items;
额外优化
- 无需先将元素转为列表再取FirstOrDefault,直接用
FirstOrDefault简化代码 - 若需要提取其他尺寸的图片(如
book_large_image_url),只需替换OuterName的值即可
内容的提问来源于stack exchange,提问作者muttley91
相关产品推荐
相关产品推荐

