如何使用 C# 在 Html Agility Pack 中使用查询参数更新 table

How to update table using query parameter in Html Agility Pack using C#

我一直在用 Html 敏捷包解析此 Url:

http://www.cmegroup.com/trading/energy/crude-oil/light-sweet-crude_quotes_settlements_options.html"

显示的默认table始终是最接近的合同日期和当前日期。

我解析上面的完整页面没有问题,但如果我要求另一个日期,当我添加查询参数以获取另一个日期时,我似乎无法获得新的 table:

例如。 http://www.cmegroup.com/trading/energy/crude-oil/light-sweet-crude_quotes_settlements_options.html?tradeDate=03/07/2018"

这仍然是 returns 当前日期的 table。 IE。 2018 年 3 月 8 日

但是,如果我也为合约月份添加另一个查询,它确实有效:

例如。 http://www.cmegroup.com/trading/energy/crude-oil/light-sweet-crude_quotes_settlements_options.html?optionExpiration=190-M18&tradeDate=03/07/2018"

但是如果我再查询:

例如。 http://www.cmegroup.com/trading/energy/crude-oil/light-sweet-crude_quotes_settlements_options.html?optionExpiration=190-M18&tradeDate=03/06/2018"

..它不会给我 03/06/2018 的 table。

当我在 Url 中更改两个或更多 查询参数时,似乎只为我 更新 html。我是 Html 的菜鸟,所以我不确定这是否与我请求的实际网站 'blocking' 有关。或者它期望一些 'user interaction'?

我代码的 'basic' 核心是:

    using HtmlAgilityPack;

    HtmlDocument htmlDoc = new HtmlDocument { OptionFixNestedTags = true };         
    HtmlWeb web = new HtmlWeb();           
    htmlDoc = web.Load(url);

朝正确的方向迈出一步就好了。

谢谢。

它是一个 ajax 站点。 WepPage 包含 JS,它通过完成过滤进行 Ajax 查询。 因此你不需要 html-agility-packJSON.NET.

URL 是: http://www.cmegroup.com/CmeWS/mvc/Settlements/Options/Settlements//190/OOF?monthYear=LOM18&strategy=DEFAULT&tradeDate=03/08/2018&pageSize=50&_=1520581128693

您需要构建 url 查询字符串,使用 WebClient.DownloadString 下载文本并使用 JSON.NET 将其转换为 POCO。

好的,所以我已经 post 为阅读这篇文章的其他人编辑了这个答案 post。请随时发表评论或编辑 post。再次感谢 Dovid 的建议。我不能保证绝对的语法有效性,但它非常接近。该代码以 Json 格式加载网页 table,然后保存到文件中。还有一种从 Json 文件加载的方法。代码是 'as-is',并不意味着复制和粘贴工作,只是参考我是如何做到的。

using Newtonsoft;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

private string _jsonStr;
private string _tableUrlStr = "http://www.cmegroup.com/CmeWS/mvc/Settlements/Options/Settlements//190/OOF?monthYear=LOM18&strategy=DEFAULT&tradeDate=03/08/2018&pageSize=50&_=1520581128693";

using (WebClient wc = new WebClient)
{
    wc.BaseAddress = @"http://www.cmegroup.com/";
    wc.Headers[HttpRequestHeader.ContentType] = "application/json";
    wc.Headers[HttpRequestHeader.Accept] = "application/json";

    _jsonStr = wc.DownloadString(_tableUrlStr);
}

if (_jsonStr.IsNullOrEmpty())
    return; 

JObject jo = JObject.Parse(_jsonStr);

//## Add some more detail to the Json file.
jo.Add("instrumentName", "my instrument name");
jo.Add("contract", "my contract name");

//## For easier debugging but larger file size.
_jsonStr = jo.ToString(Formatting.Indented);


//## Json to file:
string path = directoryString + fileString + ".json";

if (!Directory.Exists(directoryString))
{
    Directory.CreateDirectory(directoryString);
}

if (File.Exists(path))
{        
    return;
}

using (FileStream fileStream = new FileStream(path, FileMode.CreateNew,  FileAccess.Write))
{   
     using (var streamWriter = new StreamWriter(fileStream, Encoding.UTF8))
    {
        streamWriter.WriteLine(_jsonStr);
        streamWriter.Close();
    }   
}

//## Json file to collection:
//## Can copy and paste your Json at 'www.json2csharp.com'.

public class Settlement
{
    public string strike { get; set; }
    public string type { get; set; }
    public string open { get; set; }
    public string high { get; set; }
    public string low { get; set; }
    public string last { get; set; }
    public string change { get; set; }
    public string settle { get; set; }
    public string volume { get; set; }
    public string openInterest { get; set; }
}

public class RootObject
{
    public List<Settlement> settlements { get; set; }
    public string updateTime { get; set; }
    public string dsHeader { get; set; }
    public string reportType { get; set; }
    public string tradeDate { get; set; }
    public bool empty { get; set; }
//## New added entries
    public string instrumentName { get; set; }
    public string contract { get; set; }
}

private static IEnumerable<Settlement> JsonFileToList(string directoryString, string fileString)
{
    if (directoryString == null)
    {
        return null;
    }

    string path = directoryString + fileString + ".json";

    if (!Directory.Exists(directoryString))
    {
        Directory.CreateDirectory(directoryString);
    }

    if (!File.Exists(path))
    {
        return null;
    }

    RootObject ro = JsonConvert.DeserializeObject<RootObject>(File.ReadAllText(path));

    var settlementList = ro.settlements;

    foreach (var settlement in settlementList)
    {
    //## Do something with this data.
        Console.Writeline(String.Format("Strike: {0}, Volume: {1}, Last: {2}", settlement.strike, settlement.volume, settlement.last));
    }

    return settlementList;

}