C# 无法从span获取正确的数据
我一直在为Jessecar的SteamBot制作一个自定义用户处理程序,这与我遇到的问题无关,但本质上我所做的是,我已经制作好了,这样你就可以通过应用程序ID设置机器人来玩特定的游戏,我一直在使用它来闲置Steam交易卡的游戏,唯一的问题是,我可以检查它是否完成,是通过检查它的库存和应该丢弃多少张卡,这不是一件太麻烦的事,但我创建这张卡的主要原因是为了效率,每次这样做都会有点违背它的目的 正因为如此,我尝试从游戏中机器人的徽章页面获取数据,这就是我目前所拥有的C# 无法从span获取正确的数据,c#,html-agility-pack,C#,Html Agility Pack,我一直在为Jessecar的SteamBot制作一个自定义用户处理程序,这与我遇到的问题无关,但本质上我所做的是,我已经制作好了,这样你就可以通过应用程序ID设置机器人来玩特定的游戏,我一直在使用它来闲置Steam交易卡的游戏,唯一的问题是,我可以检查它是否完成,是通过检查它的库存和应该丢弃多少张卡,这不是一件太麻烦的事,但我创建这张卡的主要原因是为了效率,每次这样做都会有点违背它的目的 正因为如此,我尝试从游戏中机器人的徽章页面获取数据,这就是我目前所拥有的 else if (message.
else if (message.StartsWith(".updateidle"))
{
var webGet = new HtmlWeb();
var SteamID64 = Bot.SteamClient.SteamID.ConvertToUInt64();
string htmlget = "http://www.steamcommunity.com/profiles/" + SteamID64 + "/gamecards/" + newgame;
var doc = webGet.Load(htmlget);
HtmlNode hoursNode = doc.DocumentNode.SelectSingleNode("//div[@class=\"badge_title_stats_playtime\"]");
string hours = Regex.Match(hoursNode.InnerText, @"[0-9\.,]+").Value;
var cards = doc.DocumentNode.SelectSingleNode("div[@class='badge_title_stats_drops']/span").InnerText;
if (hours == string.Empty)
{
hours = "0.0";
}
Bot.SteamFriends.SendChatMessage(OtherSID, type, "I have been idling for " + hours + " hours on game " + newgame + " and have " + cards + " card drops remaining.");
}
获取时间很好,如果机器人在游戏中没有时间,它就不会出现,因此我只需检查它是否为空,然后将其设置为0.0,然而,对于卡,它显示为“没有剩余的卡掉落”或“剩余的卡掉落”,但它也没有得到,我尝试使用与小时相同的方法,仅当它是一个数字时才获取它,它仍然返回“0”,同样的结果也适用于这个
我还再次尝试检查字符串是否为空,因为这可能意味着没有剩余的卡片丢弃,因为没有数字,我还在线查看了获取div中的span数据的方法,或者span data general,这两种方法都不起作用,它们只返回“0”。如果您还不知道,我有HTML敏捷包。您需要更具体地选择哪些节点。我强烈建议您不要使用正则表达式来尝试导航htmldocument的innertext或innerhtml。 查找HTmlNodes,了解是否还有牌要丢。尝试使用以下xpath:
"//span[@class='progress_info_bold']"
这些节点将包含以下文本:
“没有剩余的卡掉落”
或
number+“card drops remaining”因此,在我之前的回答中,我决定不进行编辑,因为这里的后续内容会很大。我觉得Selenium和Html敏捷包都很有趣。首先,我使用Selenium登录(我使用的是Mono btw)。之后,我手动输入授权我的电脑(如果您的电脑已经授权,则跳过此步骤),然后转到控制台并按任意键继续获取卡信息。在这种情况下,我将收集所有游戏的卡信息。我不能确定哪个游戏仍然有牌下降,因为它尚未实施
class MainClass
{
public static void Main(string[] args)
{
string userName = "username";
string password ="password";
string steamProfile = "steamprofile";
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
using (var driver = new FirefoxDriver())
{
// Go to the home page
driver.Navigate().GoToUrl("https://store.steampowered.com//login/?redir=0");
// Get the page elements
var userNameField = driver.FindElementById("input_username");
var userPasswordField = driver.FindElementById("input_password");
//var loginButton = driver.FindElementById("login_btn_signin");
var loginButton = driver.FindElementByXPath("//button[@class='btnv6_blue_hoverfade btn_medium']");
// Type user name and password
userNameField.SendKeys(userName);
userPasswordField.SendKeys(password);
// and click the login button
loginButton.Click();
System.Threading.Thread.Sleep(5000);
//Type authorization code and enter manually.
System.Console.ReadKey();
driver.Navigate().GoToUrl("http://steamcommunity.com/profiles/"+steamProfile+"/badges");
driver.GetScreenshot().SaveAsFile(@"screen.png", ImageFormat.Png); //Debuggin purposes, as I was first using PhantomJS
htmlDoc.LoadHtml(driver.PageSource);
Console.Clear();
}
HtmlNodeCollection col = htmlDoc.DocumentNode.SelectNodes("//span[@class='progress_info_bold']");
foreach (HtmlNode n in col)
{
Console.WriteLine(n.InnerText);
}
}
}
}
我的案例中的输出
5 of 29 tasks completed
No card drops remaining
No card drops remaining
No card drops remaining
4 card drops remaining
3 card drops remaining
此代码还提供徽章进度。您必须弄清楚如何在Html Agility Pack中过滤数据(请阅读)。我还建议您使用Selenium,因为您可以使用它从您的网页启动一个steamgame
请记住,我在第一个答案中给出的xpath,也用于上面的代码中,它找到了所有(“/”)类,这些类的值等于“progress\u info\u bold”。当我使用该xpath而不是我问题中的xpath时,我会收到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”而不是仅仅返回“0”。我在过去遇到过这个错误,并认为这是因为我的xpath不正确,因此我在问题中没有提到它。这表明我犯了一个错误。我两小时后下班。然后我会给你一些工作代码。你登录了吗?除非您登录该网站,否则您将无法获得正确的HtmlDocument。如果你没有,那么你就无法获得剩余的卡数。是的,如果它没有登录,我就没有时间了。已经有一个开源程序,可以通过SteamBot实现多个帐户,这允许我仍然使用我的主帐户。我尝试过这种方法,因为每次都需要Steam Guard,所以它不起作用,我没有为它设置cookie配置文件,但我意识到,当我之前获得网页时,机器人实际上没有登录到网站,这就是为什么它只获得小时数。我可以在SteamBot中获取cookies,但是有没有一种方法可以使用cookies执行HtmlDocument.Load()?我已经尝试过了,但是失败了,这里的一些人做了一个尝试,他扩展了WebClient和Browser类。我不知道它是否有效(如果有效,请报告。如果您使用Selenium,您不必担心Cookie,Selenium会为您这样做。因此,我尝试了很多方法来尝试使其有效,首先我尝试了使用HtmlWeb.Load()的原始方法但在cookies中,我还使用Selenium Firefox WebDriver测试了您的方法,它无法按照SteamGuard的要求工作,在浏览器中输入它时,它不会重定向到所需的位置进行web刮取。我在网上读到,您可以为它设置配置文件,我没有读太多,因为我认为这是一个麻烦和麻烦的问题回到HTML Agility Pack,它不再比你的方法有效,所以我决定回到Selenium方法。当我尝试使用Selenium方法时,我尝试添加sessionid、steamlogin和steamloginsecure cookies,这些cookies仍然需要SteamGuard,所以我决定研究向Firefox添加配置文件,并在这些程序用于阻止SteamGuard,但从您引用的站点登录,当重定向到我想要从中抓取网页的所需URL时,它将再次注销,因此我编辑了它在浏览器启动时进入的URL,以便在它登录后,它将直接重新指向游戏的徽章页面,这将阻止不要让它退出。