
简介这份源码面向具备一定C#基础的开发者聚焦淘宝商家订单数据的自动化提取场景。它基于WinForm实现淘宝登录与已卖出订单成功收货信息的POST抓取可作为订单管理、发货、评价等后续功能的二次开发起点帮助开发者省去登录与数据获取环节的重复搭建工作。压缩包共41个文件约425KB以cs源码文件为主辅以sln解决方案、csproj工程文件、resx资源文件、dll动态库及exe可执行程序另含少量配置与说明文本结构紧凑便于直接导入Visual Studio 2010打开调试数据库采用Access。目前已有216人学习下载。读者可从中获得完整的登录与订单提取实现思路、HTTP请求封装与界面交互代码并以此为骨架扩展打印订单、好评差评、发货等模块适合作为淘宝相关工具二次开发的参考范例。1. 从一份 WinForm 淘宝订单提取源码说起它到底能跑通什么手上这份PostTaoBaoOrder源码包第一眼看上去目录挺杂bin、obj、Properties、Resources、skins几个文件夹加上Form1.cs、HttpHelper.cs、Program.cs这几个核心文件还有一个SkinH_Net.dll和SkinH_CS.dll负责界面换肤。它做的事情很具体——用 C# WinForm 模拟淘宝登录POST 提交后把商家已卖出的订单成功收货信息抓回来落到本地 Access 数据库里。开发环境是 Visual Studio 2010数据库 Access源码里只实现了登录和订单提取两块其余像打印订单、好评差评、发货这些都要自己二次开发。适合谁看如果你手上有老版本的 WinForm 项目要维护或者想拿一个能跑通的 HTTP 请求 登录态维持 数据落库的最小闭环来改这份源码的参考价值在于它的结构足够简单没有过度封装HttpHelper.cs里能直接看到 Cookie 怎么带、POST 参数怎么拼。不适合指望开箱即用的人——淘宝的登录流程和接口字段是会变的这份代码更像一个骨架你得自己往里填肉。2. 拆开 HttpHelper.cs登录态维持与 POST 请求的骨架2.1 为什么用 HttpHelper 而不是直接 WebClientWinForm 里发 HTTP 请求新手最容易想到的是WebClient或者HttpWebRequest直接怼。但淘宝登录这件事有个绕不开的点登录成功后拿到的 Cookie 必须在后续每一次订单请求里带上否则服务端认不出你是谁。WebClient每次实例化都是新的连接上下文Cookie 得手动往Headers里塞代码会散得到处都是。这份源码把请求逻辑收进HttpHelper.cs常见做法是内部维护一个CookieContainer登录请求和订单请求共用同一个容器。这样登录时服务端Set-Cookie写进去的会话标识下一次请求自动带上不用手动搬运。我一般会把这个容器做成静态字段或者通过构造函数注入避免每次 new 一个 Helper 就把登录态丢了。public class HttpHelper { // 整个会话共用一个 CookieContainer登录态才不会丢 private static CookieContainer _cookie new CookieContainer(); public static string Post(string url, string postData, string referer) { HttpWebRequest request (HttpWebRequest)WebRequest.Create(url); request.Method POST; request.CookieContainer _cookie; // 关键复用登录后的 Cookie request.ContentType application/x-www-form-urlencoded; request.Referer referer; // 淘宝部分接口校验来源页 request.UserAgent Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1); byte[] data Encoding.UTF8.GetBytes(postData); request.ContentLength data.Length; using (Stream stream request.GetRequestStream()) { stream.Write(data, 0, data.Length); } using (HttpWebResponse response (HttpWebResponse)request.GetResponse()) using (StreamReader reader new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { return reader.ReadToEnd(); } } }逻辑说明_cookie声明为static保证同一个进程内所有请求共享会话。Referer这个头容易被忽略但淘宝的部分接口会校验请求来源缺了它可能返回登录页而不是数据。UserAgent这里用的是老 IE 的标识因为 VS2010 时代的代码大多按这个来换成现代 UA 有时反而触发风控。参数说明url是接口地址postData是keyvaluekeyvalue形式的表单串referer传订单页或登录页地址。如果你要扩展发货、评价功能直接复用这个Post方法把url和postData换掉即可Cookie 和 UA 不用动。2.2 登录流程里那几个必须对齐的参数淘宝登录不是一次 POST 就完事。源码里的做法是先用 GET 拉登录页从返回的 HTML 里正则抠出几个隐藏字段再带着这些字段去 POST 登录接口。这几个字段通常包括_tb_token_、umid、loginType之类名字会变但套路固定先拿页面再解析再提交。// 第一步GET 登录页拿隐藏 token string loginPage HttpHelper.Get(https://login.taobao.com/member/login.jhtml, ); string token Regex.Match(loginPage, _tb_token_\s*[:]\s*[]([^])).Groups[1].Value; // 第二步拼登录表单 string postData string.Format( username{0}password{1}_tb_token_{2}loginType3, HttpUtility.UrlEncode(userName), HttpUtility.UrlEncode(password), token); // 第三步POST 登录Cookie 自动写入 HttpHelper 的容器 string loginResult HttpHelper.Post( https://login.taobao.com/member/login.jhtml, postData, https://login.taobao.com/member/login.jhtml);逻辑说明_tb_token_是防跨站提交的一次性令牌必须从登录页 HTML 里现取现用写死会失败。loginType3是账号密码登录的类型标识不同时期值可能不同抓包确认。登录成功后不要急着解析loginResult的内容真正要确认的是HttpHelper里的 Cookie 容器有没有拿到会话标识可以打印_cookie.GetCookies(new Uri(...)).Count来验证。参数说明userName和password必须UrlEncode否则密码里有、#这类字符会截断表单。loginType按抓包结果填源码里给的是 3你实测时以浏览器开发者工具里看到的为准。3. 订单提取与 Access 落库从 HTML 到 DataTable 的完整链路3.1 订单列表接口的请求构造登录态拿到之后提取订单就是带着 Cookie 去请求订单列表页。源码里的思路是 POST 到卖出订单的查询接口参数里带分页和状态筛选。淘宝的订单接口返回的通常是 HTML 片段或者 JSON这份源码按 HTML 解析用正则或者字符串截取把订单号、买家昵称、收货信息、金额抠出来。// 请求卖出订单列表page 控制分页 string orderUrl https://trade.taobao.com/trade/itemlist/list_sold_items.htm; string orderPost string.Format(pageNum{0}statussuccess_tb_token_{1}, page, token); string orderHtml HttpHelper.Post(orderUrl, orderPost, orderUrl); // 用正则抠订单行实际字段名以抓包为准 MatchCollection rows Regex.Matches(orderHtml, tr[^]*data-orderid(\d)[^]*.*?td[^]*classbuyer[^]*([^])/td, RegexOptions.Singleline); foreach (Match row in rows) { string orderId row.Groups[1].Value; string buyer row.Groups[2].Value.Trim(); // 继续抠收货地址、金额等字段 }逻辑说明statussuccess表示只取交易成功的订单这是源码摘要里说的「成功收货信息」的来源。正则里的>string connStr ProviderMicrosoft.Jet.OLEDB.4.0;Data Sourceorder.mdb;; using (OleDbConnection conn new OleDbConnection(connStr)) { conn.Open(); string sql INSERT INTO Orders (OrderId, Buyer, Address, Amount) VALUES (?, ?, ?, ?); using (OleDbCommand cmd new OleDbCommand(sql, conn)) { // 顺序必须和 SQL 里的 ? 一一对应 cmd.Parameters.AddWithValue(p1, orderId); cmd.Parameters.AddWithValue(p2, buyer); cmd.Parameters.AddWithValue(p3, address); cmd.Parameters.AddWithValue(p4, amount); cmd.ExecuteNonQuery(); } }逻辑说明Microsoft.Jet.OLEDB.4.0适用于 32 位 Access 文件如果你编译成 x64 会报「未在本地计算机上注册」的错误这是最常见的翻车点。源码的bin目录下有x86文件夹说明它按 32 位编译你新建项目时也要把平台目标设成 x86。参数说明AddWithValue的顺序就是 SQL 里?的顺序不要按字段名去对应。order.mdb放在程序运行目录下或者写绝对路径。如果 Access 文件是.accdb格式Provider 要换成Microsoft.ACE.OLEDB.12.0并且装对应的 Access Database Engine。3.3 界面层 Form1 与换肤 DLL 的配合Form1.cs是主窗体Form1.Designer.cs里定义了控件布局。源码带了SkinH_Net.dll和SkinH_CS.dll这是第三方换肤库skins文件夹里放皮肤文件。调用方式一般是在Program.cs的Main里初始化或者在窗体构造函数里挂载。// Program.cs 里初始化换肤路径指向 skins 目录 static void Main() { Application.EnableVisualStyles(); SkinH_Net.SkinH_Init(Application.StartupPath \skins\skin.she); Application.Run(new Form1()); }逻辑说明SkinH_Init必须在任何窗体创建之前调用否则皮肤不生效。skins目录要随程序一起发布bin\Debug下如果没有这个目录运行时会报找不到皮肤文件。如果你不需要换肤把这两行和两个 DLL 引用去掉程序照样跑不影响订单逻辑。参数说明skin.she是皮肤文件名实际以skins目录里的文件为准。Application.StartupPath保证路径跟着 exe 走不要写死盘符。4. 二次开发避坑从编译报错到接口失效的排查清单4.1 平台目标不对导致 OleDb 报「未注册」现象程序编译通过一运行到conn.Open()就抛OleDbException提示Microsoft.Jet.OLEDB.4.0未在本地计算机上注册。原因Jet 引擎只有 32 位版本项目如果按 AnyCPU 或 x64 编译在 64 位系统上找不到对应的 Provider。解决右键项目 → 属性 → 生成 → 平台目标改成x86重新编译。源码bin下的x86文件夹就是证据照着设。4.2 登录返回的 HTML 里抠不到 token现象正则匹配_tb_token_返回空字符串后续 POST 登录直接失败。原因淘宝登录页结构改版token 不再以_tb_token_明文出现或者藏在 JS 变量里、需要执行脚本才能拿到。解决用浏览器开发者工具抓登录请求看实际提交的表单字段名。常见做法是搜token关键字把正则改成匹配新的变量名。如果 token 是 JS 动态生成的就得考虑用WebBrowser控件加载页面后从 DOM 取而不是纯 HTTP 请求。4.3 订单接口返回登录页而不是数据现象HttpHelper.Post返回的 HTML 里包含登录框而不是订单列表。原因Cookie 没带上或者会话已过期。也可能是Referer缺失被服务端拒绝。解决先确认_cookie是静态的、登录和订单请求用的是同一个实例。再检查Referer是否填了订单页地址。如果都正常打印 Cookie 数量数量为 0 说明登录那一步就没成功。4.4 Access 插入中文变问号现象订单里的买家昵称、收货地址写进 Access 后变成???。原因Access 数据库的字段编码或者连接字符串的字符集不对OleDb默认按系统 ANSI 处理。解决建表时把文本字段类型设为「备注」或确认是 Unicode 编码。连接字符串里可以加Jet OLEDB:Global Partial Bulk Ops2之类的参数但更稳的做法是确认 Access 文件本身没有编码问题用中文版 Access 创建。4.5 换肤 DLL 加载失败导致窗体打不开现象双击 exe 没反应或者弹「无法加载 DLL SkinH_Net.dll」。原因DLL 没随 exe 一起复制到输出目录或者位数不匹配32 位 DLL 配 64 位程序。解决检查bin\Debug下有没有这两个 DLL没有的话在项目引用里把「复制本地」设为 True。平台目标保持 x86和 DLL 位数一致。5. 把订单提取扩展成发货/评价模块的实操思路源码只做了登录和订单提取但摘要里明确说了「可以无限扩展打印订单、好评、差评、发货」。扩展的套路其实是一样的抓包拿到目标操作的请求地址和表单字段复用HttpHelper的 Cookie 容器把返回结果解析后落库或直接反馈到界面。我一般会先在一个独立的测试方法里把新接口跑通确认返回数据正确再往Form1里加按钮和 DataGridView 展示。以发货为例抓包会看到一个类似consign.htm的接口POST 参数里带订单号、物流公司编码、运单号。构造请求时把orderId换成从订单列表里选中的行物流公司编码查淘宝的编码表。返回通常是 JSON用JavaScriptSerializer或者Newtonsoft.Json反序列化后判断success字段。// 发货请求示例参数以实际抓包为准 string consignUrl https://trade.taobao.com/trade/consign/consign.htm; string consignPost string.Format( orderId{0}companyCode{1}outSid{2}_tb_token_{3}, orderId, YTO, trackingNo, token); string result HttpHelper.Post(consignUrl, consignPost, consignUrl); // result 一般是 JSON解析 success 字段判断是否成功验证扩展是否成功不要只看界面提示要去淘宝后台确认订单状态真的变了。我踩过的坑是接口返回success:true但实际没发货原因是缺少某个签名参数服务端静默忽略了。从那以后我每次扩展新接口都强制走一遍「抓包 → 构造请求 → 对比浏览器实际提交 → 后台核对结果」的流程少一步都可能白干。另一个实用技巧是把HttpHelper的请求和响应都写日志存到本地文本文件里。淘宝接口改版时翻日志能快速看出是请求参数变了还是返回结构变了比重新抓包省事。日志里记得把密码和 token 脱敏别把敏感信息落盘。这份源码的价值不在功能多全而在它把「登录态维持 POST 请求 数据落库」这条链路用最少的代码跑通了。你拿它当脚手架把HttpHelper留着把订单解析和 Access 写入按自己的表结构改掉再逐个扩展发货、评价模块比从零搭一个 WinForm 项目省很多事。希望帮到你。本文还有配套的精品资源点击获取