提问人:Aloehart 提问时间:8/6/2013 最后编辑:Aloehart 更新时间:2/14/2021 访问量:104586
从网页中提取数据,解析特定部分,然后显示数据
Pulling data from a webpage, parsing it for specific pieces, and displaying it
问:
我已经使用这个网站很长时间来寻找问题的答案,但我无法找到这个问题的答案。
我正在与一个小组一起完成一个班级项目。我们将建立一个小型的“游戏交易”网站,允许人们注册,放入他们想要交易的游戏,并接受他人的交易或请求交易。
我们让网站提前很久运行,因此我们正试图向网站添加更多内容。我自己想做的一件事是将放入 Metacritic 的游戏联系起来。
这是我需要做的。我需要(在 Visual Studio 2012 中使用 asp 和 c#)在 metacritic 上获取正确的游戏页面,提取其数据,解析特定部分,然后在我们的页面上显示数据。
从本质上讲,当您选择要交易的游戏时,我们希望显示一个小的div,其中包含游戏的信息和评级。我想以这种方式来学习更多,并从这个项目中得到一些东西,我不必开始。
我想知道是否有人可以告诉我从哪里开始。我不知道如何从页面中提取数据。我仍在试图弄清楚我是否需要尝试写一些东西来自动搜索游戏的标题并以这种方式找到页面,或者我是否可以找到某种直接进入游戏页面的方法。一旦我拿到数据,我就不知道如何从中提取我需要的具体信息。
让这变得不容易的一件事是,我正在学习 c++ 以及 c# 和 asp,所以我一直在交叉我的电线。如果有人能为我指出正确的方向,那将是一个很大的帮助。谢谢
答:
这个小示例使用 HtmlAgilityPack,并使用选择器来获取所需的元素。XPath
protected void Page_Load(object sender, EventArgs e)
{
string url = "http://www.metacritic.com/game/pc/halo-spartan-assault";
var web = new HtmlAgilityPack.HtmlWeb();
HtmlDocument doc = web.Load(url);
string metascore = doc.DocumentNode.SelectNodes("//*[@id=\"main\"]/div[3]/div/div[2]/div[1]/div[1]/div/div/div[2]/a/span[1]")[0].InnerText;
string userscore = doc.DocumentNode.SelectNodes("//*[@id=\"main\"]/div[3]/div/div[2]/div[1]/div[2]/div[1]/div/div[2]/a/span[1]")[0].InnerText;
string summary = doc.DocumentNode.SelectNodes("//*[@id=\"main\"]/div[3]/div/div[2]/div[2]/div[1]/ul/li/span[2]/span/span[1]")[0].InnerText;
}
获取给定元素的一种简单方法是使用您的 Web 浏览器(我使用 Chrome)开发人员工具:XPath
- 打开开发人员工具(在 Windows 上为 + +,在 Mac 上为 + +)。F12CtrlShiftCCommandShiftC
- 在页面中选择要为其使用 XPath 的元素。
- 右键单击“元素”选项卡中的元素。
- 单击“复制为 XPath”。
您可以像在 c# 中一样粘贴它(如我的代码所示),但请确保对引号进行转义。
您必须确保使用一些错误处理技术,因为如果 Web 抓取更改页面的 HTML 格式,可能会导致错误。
编辑
根据 @knocte 的建议,下面是指向 HTMLAgilityPack 的 Nuget 包的链接:
https://www.nuget.org/packages/HtmlAgilityPack/
评论
我看了看,Metacritic.com 没有 API。
可以使用 HttpWebRequest 以字符串形式获取网站的内容。
using System.Net;
using System.IO;
using System.Windows.Forms;
string result = null;
string url = "http://www.stackoverflow.com";
WebResponse response = null;
StreamReader reader = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
response = request.GetResponse();
reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
result = reader.ReadToEnd();
}
catch (Exception ex)
{
// handle error
MessageBox.Show(ex.Message);
}
finally
{
if (reader != null)
reader.Close();
if (response != null)
response.Close();
}
然后,您可以利用 Metacritic 对元标记的使用来解析所需数据的字符串。以下是他们在元标记中提供的信息:
- og:标题
- og:类型
- og:网址
- og:图像
- og:site_name
- og:描述
每个标签的格式为:meta name="og:title" content="In a World..."
评论
我推荐Dcsoup。它有一个 nuget 包,它使用 CSS 选择器,所以如果你使用 jquery,它会很熟悉。我尝试过其他方法,但它是我发现的最好和最容易使用的。没有太多的文档,但它是开源的,并且是 java jsoup 库的端口,有很好的文档。(此处提供了 .NET API 的文档。我非常喜欢它。
var timeoutInMilliseconds = 5000;
var uri = new Uri("http://www.metacritic.com/game/pc/fallout-4");
var doc = Supremes.Dcsoup.Parse(uri, timeoutInMilliseconds);
// <span itemprop="ratingValue">86</span>
var ratingSpan = doc.Select("span[itemprop=ratingValue]");
int ratingValue = int.Parse(ratingSpan.Text);
// selectors match both critic and user scores
var scoreDiv = doc.Select("div.score_summary");
var scoreAnchor = scoreDiv.Select("a.metascore_anchor");
int criticRating = int.Parse(scoreAnchor[0].Text);
float userRating = float.Parse(scoreAnchor[1].Text);
评论
float.Parse()
CultureInfo.InvariantCulture
System.Globalization
table:nth-child(1) tr:nth-child(1) td:nth-child(1)
table:nth-child(1)>tbody>tr:nth-child(1)>td:nth-child(1)
我向你推荐 WebsiteParser - 它基于 HtmlAgilityPack(Hanlet Escaño 提到),但它通过属性和 css 选择器使 Web 抓取更容易:
class PersonModel
{
[Selector("#BirdthDate")]
[Converter(typeof(DateTimeConverter))]
public DateTime BirdthDate { get; set; }
}
// ...
PersonModel person = WebContentParser.Parse<PersonModel>(html);
上一个:如何在服务器端处理多个提交
下一个:Meteor:在服务器端调试
评论