由于急于上线的功能要去客服系统里抓取数据进行验证,客服方面又没有时间开发EDI接口给到我,所以用了本办法:爬人家web系统上的数据进行分析。

由于客服的web系统用ASP.Net的__doPostBack控件进行数据分页。__doPostBack是通过__EVENTTARGET,__EVENTARGUMENT两个隐藏控件向服务端发送控制信息的。

这里我要分析的页面概况如下:

这里有个导出按钮,直接模拟导出按钮获取数据。模拟点击页面来获取我们要解析需要的参数:__VIEWSTATE、__EVENTVALIDATION

设计一个demo

 private void button1_Click(object sender, EventArgs e)
{
string strViewState = System.Web.HttpUtility.UrlEncode("/wEPDwUJOTEyODUyNDU3D2QWAgIBDw8WAh4EVGV4dAUMUGFsbGV0IExpc3Q6ZGQYAQUPZ3ZzeXNzdGF0dXNsaXN0DzwrAAwBCAIOZOMeKZkMrWymOLPLpoGaeUA09JXcMmBeiapHUaN/Gi/F");
string strEventValidation = System.Web.HttpUtility.UrlEncode("/wEdAA0xoT8jJS8wSLBSnnngxJ11LlhQ8m9UI3ZtBAB4T5ifli9v5Ab4i1r+ooL3Ki4G1V2mwGQwvscKG/slAoCqDXMdx+s83MyrFGOK+Bhp33qS53KOlIwqJuEKsQlYBBWX4thggho5YkoND4EeSEP5w92hCXHcK3jw5s4JUgUUp9F6PJLbP8X7bsfD4kS7SIahZoNk3kkOw9nHzhwCbKD2SjMJqipXHjkN/zBo3hFqKyPYi8LcXcQFP+NtnRoXzZkJPyDN+DvxnwFeFeJ9MIBWR693WMHe4rn0nQ4UPheoLGOgfsnsDvJMKKjfZWVoPlnQzPA=");
StringBuilder url = new StringBuilder();
url.Append("&__VIEWSTATE=" + strViewState);
url.Append("&__EVENTVALIDATION=" + strEventValidation);
url.Append("&Button1=导出");
byte[] data = System.Text.Encoding.ASCII.GetBytes(url.ToString());
Uri uri = new Uri(textBox1.Text.ToString());
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
request.Method = "post";
request.ContentType = "application/x-www-form-urlencoded";
//request.ContentType = "application/json";
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, , data.Length);
requestStream.Close();
System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(responseStream, System.Text.Encoding.Default);
string html = readStream.ReadToEnd().ToString();
readStream.Close();
var strReg = @"<table[^>]*>[\s\S]*</table>";
List<string> result = new List<string>();
MatchCollection mc = Regex.Matches(html, strReg);
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string)); //序号
dt.Columns.Add("SN", typeof(string)); //系统序列号
dt.Columns.Add("WO", typeof(string)); //工单号
dt.Columns.Add("NextStation", typeof(string)); //下一站别
dt.Columns.Add("RepairHeld", typeof(string)); //不良否
dt.Columns.Add("SKUNo", typeof(string)); //成品料号
dt.Columns.Add("Line", typeof(string)); //线别
dt.Columns.Add("LastEditTime", typeof(string)); //最后时间
dt.Columns.Add("Carton", typeof(string)); //卡通号
dt.Columns.Add("PalletNo", typeof(string)); //栈板号
dt.Columns.Add("Closed", typeof(string)); //完成否
dt.Columns.Add("ShipOrderNo", typeof(string)); //出货通知单号
dt.Columns.Add("ContainerNo", typeof(string)); //货柜号
dt.Columns.Add("TruckLoaded", typeof(string)); //出货否
string strhead = string.Empty;
Match m = mc[];
int rowindex = ;
foreach (Match mtr in Regex.Matches(m.Value, "(?is)(?<=<tr>).+?(?=</tr>)"))
{
if (rowindex == ) { rowindex++; continue; }
DataRow dr = dt.NewRow();
MatchCollection tds = Regex.Matches(mtr.Value, "(?is)(?<=<td>).+?(?=</td>)");
MatchCollection tds2 = Regex.Matches(mtr.Value, "(?is)(?<=target=\"_blank\">).+?(?=</a></td>)");
MatchCollection tds6 = Regex.Matches(mtr.Value, "(?is)(?<=@\">).+?(?=</td>)");
MatchCollection ids = Regex.Matches(tds[].Value, "(?is)(?<=\">).+?(?=</span>)");
dr["ID"] = FormatString(ids[].Value);
dr["SN"] = FormatString(tds2[].Value);
dr["WO"] = FormatString(tds[].Value);
dr["NextStation"] = FormatString(tds[].Value);
dr["RepairHeld"] = FormatString(tds[].Value);
dr["SKUNo"] = FormatString(tds6[].Value);
dr["Line"] = FormatString(tds[].Value);
dr["LastEditTime"] = FormatString(tds[].Value);
dr["Carton"] = FormatString(tds[].Value);
dr["PalletNo"] = FormatString(tds[].Value);
dr["Closed"] = FormatString(tds[].Value);
dr["ShipOrderNo"] = FormatString(tds[].Value);
dr["ContainerNo"] = FormatString(tds[].Value);
dr["TruckLoaded"] = FormatString(tds[].Value);
dt.Rows.Add(dr);
rowindex++;
}
gridControl1.DataSource = dt;
}
/// <summary>
/// 页面加载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
this.textBox1.Text = @"http://172.16.1.13/WIPDetail.aspx?location=PA-1112069";
}
private string FormatString(string str)
{
str = str.Replace("\r\n", "").Replace("&nbsp;", "").Trim();
return str;
}

正则表达式分析解析出来的HTML文本即可。

其实针对上述既要分页又是隐藏控件分页的table不太好爬数据,如果解析不分页的table的话没那么复杂,可以直接获取整个页面的html元素然后进行解析

列如我需要知道如下页面的table表里面的数据:

首先根据URL,WebRequest请求该页面,IO流读取整个页面的HTML元素,首先正则定位table,然后遍历这些元素,按照<tr>,<th>解析

WebRequest request = WebRequest.Create("http://172.16.1.13/FGIMA.aspx?t=ssn&sno=" + str_Pallet);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
var html = reader.ReadToEnd();
var strReg = @"(?is)(?<=<table>).+?(?=</table>)";
List<string> result = new List<string>();
MatchCollection mc = Regex.Matches(html, strReg);
DataTable dt = new DataTable(); string strhead = string.Empty;
foreach (Match m in mc)
{
int rowindex = ;
foreach (Match mtr in Regex.Matches(m.Value, "(?is)(?<=<tr>).+?(?=</tr>)"))
{
if (rowindex == )
{
strhead = mtr.Value;
foreach (Match mtdh in Regex.Matches(mtr.Value, "(?is)(?<=<th>).+?(?=</th>)"))
{
if (!dt.Columns.Contains(mtdh.Value.Replace("\r\n", "").Trim()))
{
dt.Columns.Add(mtdh.Value.Replace("\r\n", "").Trim());
}
}
}
else
{
DataRow dr = dt.NewRow();
if (mtr.Value.Contains("累计数量")) continue;
if (mtr.Value.Contains("没有找到相关数据"))
{
return dt;
}
MatchCollection mtdds = Regex.Matches(mtr.Value, "(?is)(?<=<td>).+?(?=</td>)");
int colindex = ;
foreach (Match mtdh in Regex.Matches(strhead, "(?is)(?<=<th>).+?(?=</th>)"))
{
if (mtdh.Value.Contains("机器序列号"))
{
foreach (Match mtdhdd in Regex.Matches(mtr.Value, "(?is)(?<=target=\"_blank\">).+?(?=</a>)"))
{
dr["机器序列号"] = mtdhdd.Value.Replace("\r\n", "").Trim();
}
}
else
dr[mtdh.Value.Replace("\r\n", "").Trim()] = mtdds[colindex].Value.Replace("\r\n", "").Trim(); colindex++;
}
dt.Rows.Add(dr);
}
rowindex++;
}
}
if (dt.Columns.Contains("机器序列号"))
{
dt.Columns["机器序列号"].ColumnName = "SN";
}
if (dt.Columns.Contains("工单号码"))
{
dt.Columns["工单号码"].ColumnName = "WorkorderNo";
}
if (dt.Columns.Contains("成品料号"))
{
dt.Columns["成品料号"].ColumnName = "PartNo";
}
if (dt.Columns.Contains("栈板号码"))
{
dt.Columns["栈板号码"].ColumnName = "Pallet";
}
reader.Close();
reader.Dispose();
response.Close();
return dt;

解析ASPX网页__doPostBack分页的网页table数据的更多相关文章

  1. 抓取Js动态生成数据且以滚动页面方式分页的网页

    代码也可以从我的开源项目HtmlExtractor中获取. 当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢? 如类似今日头条这样的网 ...

  2. 可以Ping通和DNS解析,但打不开网页的解决办法

    一. 网络故障表现为: 1.Ping地址正常,能ping通任何本来就可以ping通地址,如网关.域名. 2.能DNS解析域名. 3.无法打开网页,感觉是网页打开的一瞬间就显示无网络连接. 4.只需要连 ...

  3. Django学习(5)优雅地分页展示网页

    在我们平时浏览网页时,经常会遇到网页里条目很多的情形,这时就会用到分页展示的功能.那么,在Django中,是如何实现网页分类的功能的呢?答案是Paginator类. 本次分享讲具体展示如何利用Djan ...

  4. 利用pandas库中的read_html方法快速抓取网页中常见的表格型数据

    本文转载自:https://www.makcyun.top/web_scraping_withpython2.html 需要学习的地方: (1)read_html的用法 作用:快速获取在html中页面 ...

  5. 博客代码:iframe—网页中嵌入其他网页

    iframe 是一个可以把另外一个网页嵌入到一个网页里的代码,非常有用.对于一个内容不错的网页,要方便地把它搬到自己的博客里,用这个代码最合适.而对于在新浪博客里不支持的一些网页效果和代码,可先把他们 ...

  6. HTML-图片热点、网页内嵌、网页拼接、快速切图

    图片热点 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果.与图片链接不同,热点是图片上的某一个区域或多个区域. 我们用魔兽世界图片来做一个图片热点,点击logo.区域和不 ...

  7. C# 网络编程之webBrowser获取网页url和下载网页中图片

    该文章主要是通过C#网络编程的webBrowser获取网页中的url并简单的尝试瞎子啊网页中的图片,主要是为以后网络开发的基础学习.其中主要的通过应用程序结合网页知识.正则表达式实现浏览.获取url. ...

  8. ifram的使用 左边是<a>链接 右边是对应网页嵌套的显示网页链接内容 和toggle的收放用法

    1.ifram的使用 左边是<a>链接  右边是对应网页嵌套的显示网页链接内容 <div class="container"> <div class= ...

  9. 网页手机wap2.0网页的head里加入下面这条元标签......

    网页手机wap2.0网页的head里加入下面这条元标签,在iPhone的浏览器中页面将以原始大小显示,并不允许缩放. <meta name="viewport" conten ...

随机推荐

  1. jquery 选择器的总结

    元素选择 $("input") id选择 $('#id') class选择 $('.id') 属性选择 $('[prop]')或者$('[prop=“value1”]')或者$(' ...

  2. C#中索引器Indexer的学习使用

    索引器 顾名思义,是用来索引的,那么C#中索引器是用来索引什么的呢 首先我们知道,C#中的数组是本身就可以索引的,那么C#中的类和结构呢,类和结构的实例是无法索引的,如果我们想让C#中类或者结构的实例 ...

  3. 以后尽量不用cin、cout啦

    cout输出有问题(对于double,不同OJ处理的结果不一样),cin读入机制较scanf繁琐.慢!!!!!!!!

  4. C#----接口与多继承

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 接口 { ...

  5. rest framework 节流

    一.简单节流示例 所谓节流就是控制用户访问频率,这里分为匿名用户(非登录用户)和登录用户的限制. 匿名用户:根据其 IP 限制其频率 登录用户:IP.用户名都 OK 获取用户请求 IP:request ...

  6. Maven核心知识

    什么是Maven? Maven是基于项目对象模型(POM), 可以通过一小段描述信息来管理项目的构建和文档的软件项目管理工具 目录结构如下 src main java package test jav ...

  7. 如何在MySQL中设置外键约束

    引用:http://blog.sina.com.cn/s/blog_53729e4601011wja.html MySql外键设置详解   (1) 外键的使用: 外键的作用,主要有两个:    一个是 ...

  8. 微信小程序小结(3) -- 使用wxParse解析html及多数据循环

    wxParse-微信小程序富文本解析组件:https://github.com/icindy/wxParse 支持Html及markdown转wxml可视化 使用 1.copy下载好的文件夹wxPar ...

  9. OTRS 二次开发笔记

    公司使用otrs系统处理业务工单,各种事件流.因为是开源免费系统,因此需要在上面做一些功能补充或定制的二次开发. otrs是什么? OTRS 是一个功能强大的工单系统.完美适用于服务台(Help De ...

  10. Oracle 11g 数据类型

    1.     字符类型 数据类型 长度 说明 CHAR(n BYTE/CHAR) 默认1字节,n值最大为2000 末尾填充空格以达到指定长度,超过最大长度报错.默认指定长度为字节数,字符长度可以从1字 ...