我想从this website获取数据并将它们放入字典中。
基本上这些是某些金融工具的价格和数量。
我有这个页面的源代码(这里只是整个文本的摘录):
<tr>
<td class="quotesMaxTime1414148558" id="notation115602071"><span>4,000.00</span></td>
<td><span>0</span></td>
<td class="icon red"><span id="domhandler:8.consumer:VALUE-2CCLASS.comp:PREV.gt:green.eq:ZERO.lt:red.resetLt:.resetGt:.resetEq:ZERO.mdgObj:prices-2Fquote-3FVERSION-3D2-26CODE_SELECTOR_PREVIOUS_LAST-3DLATEST-26ID_TYPE_PERFORMANCE-3D7-26ID_TYPE_PRICE-3D1-26ID_QUALITY_PRICE-3D5-26ID_NOTATION-3D115602071.attr:PERFORMANCE_PCT.wtkm:options_options_snapshot_1">-3.87%</span></td>
<td><span id="domhandler:9.consumer:VALUE-2CCLASS.comp:PREV.gt:green.eq:ZERO.lt:red.resetLt:.resetGt:.resetEq:ZERO.mdgObj:prices-2Fquote-3FVERSION-3D2-26CODE_SELECTOR_PREVIOUS_LAST-3DLATEST-26ID_TYPE_PERFORMANCE-3D7-26ID_TYPE_PRICE-3D1-26ID_QUALITY_PRICE-3D5-26ID_NOTATION-3D115602071.attr:PRICE.wtkm:options_options_snapshot_1">960.40</span></td>
</tr>
现在我想提供以下信息:
我尝试使用以下内容来提取第一个信息(值4000):
string url = "http://www.eurexchange.com/action/exchange-en/4744-19066/19068/quotesSingleViewOption.do?callPut=Put&maturityDate=201411";
var webGet = new HtmlWeb();
var document = webGet.Load(url);
var firstData = from x in document.DocumentNode.Descendants()
where x.Name == "td" && x.Attributes.Contains("class")
select x.InnerText;
但firstData不包含我想要的信息(值4000)但是:
System.Linq.Enumerable+WhereSelectEnumerableIterator`2[HtmlAgilityPack.HtmlNode,System.String]
我如何获取这些数据?我还需要多次重复此任务,因为在页面中有多行包含类似信息。 HTML Agility Pack在这种情况下有用吗?谢谢。
答案 0 :(得分:1)
那是因为您的LINQ没有执行。如果您检查调试器中的Results View
并运行查询,您将获得所有项目,第一项是您要查找的值。
所以,这会让你4,000.00
var firstData = (from x in document.DocumentNode.Descendants()
where x.Name == "td" && x.Attributes.Contains("class")
select x.InnerText).First();
如果您想要全部,请拨打ToList()
而不是First()
答案 1 :(得分:1)
如果您打开使用CSQuery ..然后尝试这个。
static void Main()
{
CsQuery.CQ cq = CsQuery.CQ.CreateFromUrl("http://www.eurexchange.com/action/exchange-en/4744-19066/19068/quotesSingleViewOption.do?callPut=Put&maturityDate=201411");
string str = cq["#notation115602071 span"].Text();
}
答案 2 :(得分:1)
您可以使用HtmlAgility Pack。与XmlDocument或XDocument不同,Html Agility包可以容忍格式错误的HTML(它存在于整个互联网上,可能存在于您尝试解析的网站上)。
并非所有HTML页面都可以被认为是有效的XML。
使用HTMLAgility包,您可以加载页面并使用XPath或类似于System.Xml的对象模型对其进行解析。
或者,您可以使用PDF到文本转换器并以更高的准确度解析文本文件,因为您链接的网站提供了相同数据的PDF导出,
答案 3 :(得分:1)
几年前我们做了一个类似的项目蜘蛛所有主要的在线博彩网站,并创建一个比较工具,以获得每种类型的事件的最佳价格,例如。以最佳回报的顺序显示所有主要博彩公司的特定足球比赛的赔率。
原来是一个完整的噩梦 - 网站的渲染html输出几乎每天都在变化,并且经常会生成格式不佳的html,有时会使蜘蛛守护程序崩溃,因此我们必须不断维护系统以保持其正常工作
通过这些类型的东西,订阅数据源通常是经济的,这需要更少的维护和更容易的集成。
答案 4 :(得分:1)
这可能有点难看,但它很快被抛到一起,可能会被大大清理,但它会从该页面上的价格/行情表中返回您要查找的所有值。希望它有所帮助。
var url = "http://www.eurexchange.com/action/exchange-en/4744-19066/19068/quotesSingleViewOption.do?callPut=Put&maturityDate=201411";
var webGet = new HtmlWeb();
var document = webGet.Load(url);
var pricesAndQuotesDataTable =
(from elem in
document.DocumentNode.Descendants()
.Where(
d =>
d.Attributes["class"] != null && d.Attributes["class"].Value == "toggleTitle" &&
d.ChildNodes.Any(h => h.InnerText != null && h.InnerText == "Prices/Quotes"))
select
elem.Descendants()
.FirstOrDefault(
d => d.Attributes["class"] != null && d.Attributes["class"].Value == "dataTable")).FirstOrDefault();
if (pricesAndQuotesDataTable != null)
{
var dataRows = from elem in pricesAndQuotesDataTable.Descendants()
where elem.Name == "tr" && elem.ParentNode.Name == "tbody"
select elem;
var dataPoints = new List<object>();
foreach (var row in dataRows)
{
var dataColumns = (from col in row.ChildNodes.Where(n => n.Name == "td")
select col).ToList();
dataPoints.Add(
new
{
StrikePrice = dataColumns[0].InnerText,
DifferenceToPreviousDay = dataColumns[9].InnerText,
LastPrice = dataColumns[10].InnerText
});
}
}