Unity C#解析Steam新闻页提取图片URL:返回数据异常
问题描述
尝试解析Steam新闻RSS中带图片链接的<enclosure>标签时遇到问题,目标是Steam应用1348750的英文US区新闻feed。用Unity的UnityWebRequest.Get获取数据,不管是取UTF-8字符串还是原始byte[],保存到文件或打印时数据都出现混乱。原以为返回的是XHTML格式,但不知道如何转成可读格式来解析图片URL。
预期结果
<item> <title>Update v1.3</title> <description>Changelog:<br><ul class="bb_ul"><li>Arry and Miri can now gain affection.<br></li><li>The player can now view Arry and Miri's epilogue scenes. (You will have to answer their proposal one more time.)<br></li><li>The Arry and Miri achievements have been fixed and should unlock when you reach the epilogue.<br></li><li>The ability management backend has been 100% REDONE, and all associated bugs should be fixed.<br></li><li>Specifically, ability use counts and levels will no longer reset if they're no longer in a player preset.</li></ul><br><div class="bb_h2">ACTION REQUIRED:</div>If you take one thing from this update, it's that <b>Arry and Miri's</b> conversation lines were <b>broken</b> before this update, with all their epilogue scenes being <b>hidden</b>. <br><br><b>If you've been stuck at their proposal, doing it one more time should unlock their achievements and lead you to their epilogue scenes.</b><br><br>Additionally, I've begun work on the logbook! It's coming along nicely.<br><br><img src="https://i.imgur.com/FBdDow9.png" /></description> <link><![CDATA[https://store.steampowered.com/news/app/1348750/view/3178989079011859448]]></link> <pubDate>Tue, 10 May 2022 02:28:06 +0000</pubDate> <author>niku_treat</author> <guid isPermaLink="true">https://store.steampowered.com/news/app/1348750/view/3178989079011859448</guid> <enclosure url="https://cdn.akamai.steamstatic.com/steamcommunity/public/images/clans/38198503/25733639d563297f7a04c4fd68537f5b9aba3d67.png" length="0" type="image/png" /> </item>
实际获取结果
获取到的数据片段混乱,混合了HTML内容与类似JSON的结构:
<?xml version="1.0"?> <string><!DOCTYPE html> <html class=" responsive" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="theme-color" content="#171a21"> <title>Hearts of the Dungeon List - Steam News Hub</title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
ot;:&quot;Changelog: [list] [*]Arry and Miri can now gain affection. [*]The player can now view Arry and Miri's epilogue scenes. (You will have to answer their proposal one more time.) [*]The Arry and Miri achievements have been fixed and should unlock when you reach the epilogue. [*]The ability management backend has been 100% REDONE, and all associated bugs should be fixed. [*]Specifically, ability use counts and levels will no longer reset if they're no longer in a player preset. [/list] [h2]ACTION REQUIRED:[/h2] If you take one thing from this update, it's that [b]Arry and Miri's[/b] conversation lines were [b]broken[/b] before this update, with all their epilogue scenes being [b]hidden[/b]. [b]If you've been stuck at their proposal, doing it one more time should unlock their achievements and lead you to their epilogue scenes.[/b] Additionally, I've begun work on the logbook! It's coming along nicely. [img]https://i.imgur.com/FBdDow9.png[/img]&amp;quot;,&amp;quot;commentcount&amp;quot;:1,&amp;quot;tags&amp;quot;:[&amp;quot;mod_reviewed&amp;quot;,&amp;quot;ModAct_870845553_1652150701_0&amp;quot;],&amp;quot;language&amp;quot;:0,&amp;quot;hidden&amp;quot;:0,&amp;quot;forum_topic_id&amp;quot;:&amp;quot;3274690571081137373&amp;quot;,&amp;quot;event_gid&amp;quot;:&amp;quot;3178989079011859448&amp;quot;,&amp;quot;voteupcount&amp;quot;:11,&amp;quot;votedowncount&amp;quot;:0,&amp;quot;ban_check_result&amp;quot;:0},&amp;quot;published&amp;quot;:1,&amp;quot;hidden&amp;quot;:0,&amp;quot;rtime32_visibility_start&amp;quot;:0,&amp;quot;rtime32_visibility_end&amp;quot;:0,&amp;quot;broadcaster_accountid&amp;quot;:0,&amp;quot;follower_count&amp;quot;:0,&amp;quot;ignore_count&amp;quot;:0,&amp;quot;forum_topic_id&amp;quot;:&amp;quot;3274690571081137373&amp;quot;,&amp;quot;rtime32_last_modified&amp;quot;:1653189104,&amp;quot;news_post_gid&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;rtime_mod_reviewed&amp;quot;:1652150697,&amp;quot;featured_app_tagid&amp;quot;:0,&amp;quot;referenced_appids&amp;quot;:[],&amp;quot;build_id&amp;quot;:0,&amp;quot;build_branch&quot
示例代码
public static IEnumerator GetCoroutine(string url, Action<string> OnError, Action<string> OnSuccess) { using (UnityWebRequest result = UnityWebRequest.Get(url)) { yield return result.SendWebRequest(); if (result.result == UnityWebRequest.Result.ConnectionError || result.result == UnityWebRequest.Result.ProtocolError) { OnError(result.error); } else { string rawUTF8Text = result.downloadHandler.text; FileStream file; string filePath = Application.persistentDataPath + "/xmlsave.xml"; file = File.Create(filePath); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(file, rawUTF8Text); file.Close(); OnSuccess(rawUTF8Text); } } }
解决方案
1. 修复数据保存错误
原代码用BinaryFormatter序列化字符串到文件是错误的,BinaryFormatter用于序列化.NET对象的二进制格式,直接保存字符串应该用File.WriteAllText并指定UTF-8编码:
// 替换原保存代码 string filePath = Application.persistentDataPath + "/steam_news.xml"; File.WriteAllText(filePath, rawUTF8Text, Encoding.UTF8);
2. 强制Steam返回XML格式
Steam可能根据请求头返回不同内容,添加请求头明确要求XML格式:
using (UnityWebRequest result = UnityWebRequest.Get(url)) { // 指定接受XML类型的响应 result.SetRequestHeader("Accept", "application/rss+xml, application/xml"); yield return result.SendWebRequest(); // 错误处理逻辑不变 if (result.result != UnityWebRequest.Result.Success) { OnError(result.error); yield break; } string rawXML = result.downloadHandler.text; File.WriteAllText(Application.persistentDataPath + "/steam_news.xml", rawXML, Encoding.UTF8); OnSuccess(rawXML); }
3. 解析<enclosure>标签
获取到正确的XML后,可用XmlDocument或XDocument解析:
用XmlDocument解析
public void ParseRSS(string rawXML) { XmlDocument doc = new XmlDocument(); doc.LoadXml(rawXML); XmlNodeList items = doc.SelectNodes("//item"); foreach (XmlNode item in items) { string title = item.SelectSingleNode("title").InnerText; XmlNode enclosure = item.SelectSingleNode("enclosure"); if (enclosure != null) { string imageUrl = enclosure.Attributes["url"].Value; Debug.Log($"新闻标题:{title},封面图URL:{imageUrl}"); } } }
用LINQ to XML解析
public void ParseRSSWithLINQ(string rawXML) { XDocument doc = XDocument.Parse(rawXML); foreach (var item in doc.Descendants("item")) { string title = item.Element("title").Value; XElement enclosure = item.Element("enclosure"); if (enclosure != null) { string imageUrl = enclosure.Attribute("url").Value; Debug.Log($"新闻标题:{title},封面图URL:{imageUrl}"); } } }
4. 还原转义字符
如果需要处理description中的转义HTML字符(如<对应<),可使用HttpUtility.HtmlDecode:
using System.Web; // Unity中需引用System.Web.dll string encodedDesc = item.SelectSingleNode("description").InnerText; string decodedDesc = HttpUtility.HtmlDecode(encodedDesc);
内容的提问来源于stack exchange,提问作者Katerlad
相关产品推荐
相关产品推荐

