0

私はこのリンクを解析しようとしています: http://agent.bronni.ru/Result.aspx?id=c7a6a33a-174e-426d-b127-828ee612c36e&account=27178&page=1&pageSize=50&mr=true

しかし、フィドラーでわかるように、jsonの結果を使用した遅延読み込みメソッドがあるため、結果テーブルを取得できません。

私のコードは次のとおりです。

HtmlWeb hw = new HtmlWeb(); HtmlDocument doc = hw.Load("http://agent.bronni.ru/Result.aspx?id=c7a6a33a-174e-426d-b127-828ee612c36e&account=27178&page=1&pageSize=50&mr=true");

    // Get all tables in the document
    HtmlNodeCollection tables = doc.DocumentNode.SelectNodes("//table");

    // Iterate all rows in the first table
    HtmlNodeCollection rows = tables[0].SelectNodes(".//tr");

    var data = rows.Skip(1).ToList().Take(10).ToList().Select(x => new TableRow()
    {
        Price = x.SelectNodes(".//td").ToList()[4].InnerText,
        Operator = x.SelectNodes(".//td").ToList()[15].InnerText,
        DepartureDate = x.SelectNodes(".//td").ToList()[6].InnerText,
        DestinationRegion = x.SelectNodes(".//td").ToList()[7].InnerText
    }).ToList();

更新 2 番目のサイト: コード

 WebClient wc = new WebClient();
        wc.Headers.Add("Referer", "http://sletat.ru/");//MUST BE THIS HEADER
        string result = wc.DownloadString("http://module.sletat.ru/Main.svc/GetTours?cityFromId=832&countryId=35&cities=&meals=&stars=&hotels=&s_adults=1&s_kids=0&s_kids_ages=&s_nightsMin=6&s_nightsMax=16&s_priceMin=0&s_priceMax=&currencyAlias=RUB&s_departFrom=25%2F06%2F2012&s_departTo=31%2F07%2F2012&visibleOperators=&s_hotelIsNotInStop=true&s_hasTickets=true&s_ticketsIncluded=true&debug=0&filter=0&f_to_id=&requestId=19198631&pageSize=20&pageNumber=1&updateResult=1&includeDescriptions=1&includeOilTaxesAndVisa=1&userId=&jskey=1&callback=_jqjsp&_1340633427022=");
        result = result.Substring(result.IndexOf("{"), result.LastIndexOf("}") - result.IndexOf("{") + 1);
        JavaScriptSerializer js = new JavaScriptSerializer();
        dynamic json = js.DeserializeObject(result);
        var prices = json["GetToursResult"]["Data"]["aaData"] as object[];
        // var operators = ((object[])json["result"]["prices"]).Cast<Dictionary<string, object>>();
        var temp = prices.ToList().Take(20).Select(x => new TableRow
        {
            Operator = (x as object[])[40].ToString(),
            //Price = x["operatorPrice"].ToString(),
            //DepartureDate = x["checkinDate"].ToString(),
            //DestinationRegion = ((Dictionary<string, object>)x["country"])["englishName"].ToString()
        }).ToList();

        string str = "";

        foreach (var tableRow in temp)
        {
            str += tableRow.Operator + "<br />";
        }
        Response.Write(str);

このようにして、私はすべてうまくいきますが、問題は、このリンクが約 30 分間機能し、その後、別のリンクを再度配置する必要があることです。これを修正する方法はありますか?

4

1 に答える 1

0

データは実際にはここから来ています:

http://beta.remote.bronni.ru/LazyLoading.ashx/getResult?jsonp=jQuery17207647891761735082_1340131755603&id=c7a6a33a-174e-426d-b127-828ee612c36e&page=3&pageSize=50&_=1340131756631

ただし、page=#pageSize=#は動的に調整できます。

したがって、HTML を解析する代わりに、URL から JSON データを取得して解析することができます。例えば:

WebClient wc = new WebClient();
string result =wc.DownloadString("http://beta.remote.bronni.ru/LazyLoading.ashx/getResult?jsonp=jQuery17207647891761735082_1340131755603&id=c7a6a33a-174e-426d-b127-828ee612c36e&page=1&pageSize=1000&_=1340131756631");
result = result.Substring(result.IndexOf("{"),result.LastIndexOf("}")-result.IndexOf("{")+1);
JavaScriptSerializer js = new JavaScriptSerializer();
dynamic json =  js.DeserializeObject(result);
var prices = ((object[])json["result"]["prices"]).Cast<Dictionary<string,object>>();
var data = from p in prices 
           select new
{
  OperatorID = p["operatorID"],
  Price = p["operatorPrice"],
  Country = ((Dictionary<string,object>)p["country"])["englishName"],
  CheckinDate = p["checkinDate"]
};

Console.WriteLine(data);

私のLinqPadプログラムでは、次のようなものを生成します:

OperatorID Price Country CheckinDate 
0          1,27  Greece  2012-06-28 
0          55,90 Greece  2012-06-28 
0          67,34 Greece  2012-06-28 

そして、あなたが求める量に応じて、さらに多くの行...

: この行の理由はresult = result.Substring(result.IndexOf("{"),result.LastIndexOf("}")-result.IndexOf("{")+1);、jsonp の結果の先頭に次のようなゴミがあるためです。

jQuery17207647891761735082_1340131755603({"

})JavascriptSerializer が解析しようとすると、これで終了します。したがって、それを削除する必要があります。

アップデート:

興味深いことに、データを返す ASHX ハンドラーはReferer、要求にヘッダーを必要とするようです。そうしないと、応答にオペレーター情報が含まれません。http://agent.bronni.ru必要なRefererは、あなたが望むものではありません。実際には特に探しているようです。

基本的に、あなたがする必要があるのは次のことだけです:

WebClient wc = new WebClient();
wc.Headers.Add("Referer","http://agent.bronni.ru");//MUST BE THIS HEADER
string result =wc.DownloadString("http://beta.remote.bronni.ru/LazyLoading.ashx/getResult?jsonp=jQuery17207647891761735082_1340131755603&id=c7a6a33a-174e-426d-b127-828ee612c36e&page=1&pageSize=1000&_=1340131756631");
result = result.Substring(result.IndexOf("{"),result.LastIndexOf("}")-result.IndexOf("{")+1);
JavaScriptSerializer js = new JavaScriptSerializer();
dynamic json =  js.DeserializeObject(result);
var prices = ((object[])json["result"]["prices"]).Cast<Dictionary<string,object>>();
var data = from p in prices 
           select new
{
  OperatorID = p["operatorID"],
  Price = p["operatorPrice"],
  Country = ((Dictionary<string,object>)p["country"])["englishName"],
  Hotel = ((Dictionary<string,object>)p["hotel"])["englishName"],
  Operator = ((Dictionary<string,object>)p["operator"])["englishName"],//OPERATOR
  CheckinDate = p["checkinDate"]
};

OperatorID Price Country Hotel                           Operator          CheckinDate 
19681      1,27  Greece  Julia Hotel                     Mouzenidis Travel 2012-06-28 
19681      1,27  Greece  Forest Park                     Mouzenidis Travel 2012-06-28 
19681      1,27  Greece  Kassandra Mare (ï-îâ Êàññàíäðà) Mouzenidis Travel 2012-06-28 

更新 2:

すぐに使用できる Javascriptserializer とJSON.NET シリアライザーのパフォーマンスを比較することにしました。すべてのテストで、さまざまなレコード サイズ (50、1000、3000) で JSON.NET は Javascriptserializer よりも少なくとも 2 倍高速でした。小さいレコード セットでは、場合によっては 10 倍も速くなります。

JSON.NET ライブラリを使用することにした場合、上記のコードと同じ結果が得られるコードは次のとおりです。

WebClient wc = new WebClient();
wc.Headers.Add("Referer","http://agent.bronni.ru");
string result =wc.DownloadString("http://beta.remote.bronni.ru/LazyLoading.ashx/getResult?jsonp=jQuery17207647891761735082_1340131755603&id=c7a6a33a-174e-426d-b127-828ee612c36e&page=1&pageSize=50&_=1340131756631");
result = result.Substring(result.IndexOf("{"),result.LastIndexOf("}")-result.IndexOf("{")+1);
JObject o = JObject.Parse(result);
var data = from x in o["result"]["prices"]
select new
 {
  OperatorID = x["operatorID"],
  Price = x["operatorPrice"],
  Country = x["country"]["englishName"],
  Hotel = x["hotel"]["englishName"],
  Operator = x["operator"]["englishName"],
  CheckinDate = x["checkinDate"]
};

Console.WriteLine(data);
于 2012-06-19T18:55:53.127 に答える