C# CefSharp Winform抓取拼多多訂單
阿新 • • 發佈:2020-08-12
C# CefSharp Winform抓取拼多多訂單
前言
- 只支援查詢自己的買家訂單
- 支援Excel匯出,只支援部分欄位
- 純技術實戰分享
如何使用
- 直接執行專案
- 登入拼多多
- 點選全部訂單
- 等待頁面載入不跳轉了,點選 匯出訂單按鈕
登入驗證
基於CefSharp Winform載入Web瀏覽器(chrome核心),瀏覽器地址導航到http://mobile.yangkeduo.com/personal.html,然後用手機驗證碼方式登入
獲取訂單資料
if (request.Method.Equals("POST")&&request.Url.Contains("order_list")) { var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestJsonFilter; if (filter==null) { return; } ASCIIEncoding encoding = new ASCIIEncoding(); //這裡截獲返回的資料 var data = encoding.GetString(filter.DataAll.ToArray()); }
- 擷取到瀏覽器傳送的POST請求並且URL地址裡包含order_list的
- 得到url地址為:http://mobile.yangkeduo.com/proxy/api/api/aristotle/order_list?pdduid=你的使用者ID
- 得到post資料為json
但是由於採用了分頁獲取的仍然不是全部,這樣我們必須通過手動模擬Post請求來載入全部
嘗試抓取Post資料
將byte轉為string之後得到json
{"timeout":1300,"type":"all","page":1,"pay_channel_list":["9","30","31","35","38","52","97","122","135","322","-1"],"origin_host_name":"mobile.yangkeduo.com","size":10,"offset":"200725-031832966363189"}
看得出size為10條資料 所以嘗試更改post入參試試,offset應該是分頁的最後條記錄作為偏移量,理論我們可以傳空試試,從第一條記錄消費
結論是拼多多那邊做了驗證 返回了errorCode 300000
重新梳理!
獲取Post Json
Encoding.Default.GetString(request.PostData.Elements[0].Bytes);將Byte轉為String
- 第一頁json
{"timeout":1300,"type":"all","page":1,"pay_channel_list":["9","30","31","35","38","52","97","122","135","322","-1"],"origin_host_name":"mobile.yangkeduo.com","size":10,"offset":"200803-173139887143189"}
- 第二頁
{"timeout":1300,"type":"all","page":1,"pay_channel_list":["9","30","31","35","38","52","97","122","135","322","-1"],"origin_host_name":"mobile.yangkeduo.com","size":10,"offset":"200727-071906181943189"}
- 第三頁
{"timeout":1300,"type":"all","page":1,"pay_channel_list":["9","30","31","35","38","52","97","122","135","322","-1"],"origin_host_name":"mobile.yangkeduo.com","size":10,"offset":"200725-031832966363189"}
區別的只有offset,那麼offset是啥
由於offset是前端請求必然是在後端返回的訂單資料裡有,所以拿到offset值去搜索,可以找到為訂單order_sn欄位!
那麼下一步的思路清晰了,解析返回的json
解析返回json
- 根據json建立model
public class Order
{
public long server_time { get; set; }
public List<OrderItem> orders { get; set; }
}
public class OrderItem {
/// <summary>
/// 快遞單號
/// </summary>
public string tracking_number { get; set; }
/// <summary>
/// 訂單編碼
/// </summary>
public string order_sn { get; set; }
/// <summary>
/// 快遞公司ID
/// </summary>
public string shipping_id { get; set; }
/// <summary>
/// 訂單狀態 4為已收貨
/// </summary>
public int status { get; set; }
/// <summary>
/// 訂單金額
/// </summary>
public int display_amount { get; set; }
}
- 獲取返回json,拿到最後一個的訂單編碼然後重新請求,直到訂單查完
if (request.Method.Equals("POST")&&request.Url.Contains("order_list"))
{
var filter = FilterManager.GetFileter(request.Identifier.ToString()) as TestJsonFilter;
if (filter==null)
{
return;
}
ASCIIEncoding encoding = new ASCIIEncoding();
//這裡截獲返回的資料
var data = encoding.GetString(filter.DataAll.ToArray());
var orderList= JsonConvert.DeserializeObject<Order>(data);
if (orderList.orders!=null&& orderList.orders.Count!=0)
{
Thread.Sleep(1000);
FilterManager.AddOrder(orderList);
//反向排序
orderList.orders.Reverse();
//獲取第一個
var order=orderList.orders.FirstOrDefault();
string json = "{\"timeout\":1300,\"type\":\"all\",\"page\":1,\"pay_channel_list\":[\"9\",\"30\",\"31\",\"35\",\"38\",\"52\",\"97\",\"122\",\"135\",\"322\",\"-1\"],\"origin_host_name\":\"mobile.yangkeduo.com\",\"size\":10,\"offset\":\"#offset#\"}";
json=json.Replace("#offset#", order.order_sn);
chromiumWebBrowser.Navigate(Encoding.Default.GetBytes(json), request);
}
}
匯出Excel
引用NOPI進行匯出,將List轉為DataTable