1、 打开一家航空运输公司的查询网页,如http://www.skyteamcargo.com/en/tracking/,该页面有两个文本框,供用户输入业务代码,如180-36898035,

2、 然后单击“Go”按钮后,下一个页面显示查询出来的结果

现在要求以上步骤都用程序自动实现,并把查询结果提取出来,以备后面进一步处理。 
要完成这样的功能,首先要解决以下几个问题:

l 能够用程序在后台将数据Post到目标网页

l 能接收到对方返回的HTML结果页面

l 能够分析该页面,并将需要的结果提取出来

经过一番研究和实验,我解决了以上几个问题,下面分别描述。

1. 用程序将指定数据Post到目标网页,并接收结果网页

我先用一个网络嗅探器来捕获用IE手工查询时浏览器和对方网页的HTTP协议交互过程,这里推荐用Ultra Network Sniffer,它有个Connection Monitor功能,可以监视某个程序的所有连接,这样就避免了其他无关数据包的干扰。如图

当在查询页面里输入数据后,点击“Go”按钮,嗅探器捕捉到的数据包如下图

请注意第三行,有一个Post数据包,这个就是我们需要的,

它所发送的网页地址为:http://www.skyteamcargo.com/en/tracking/tra_result.php

它所Post的数据为:awbpre=180&awbnum=36898035&x=17&y=9

很显然,180和36898035是可以替换的,而且要注意的是发送的目标网页不再是我们在浏览器里直接输入的初始页面http://www.skyteamcargo.com/en/tracking/了

下面我们用程序来发送这段数据,代码如下

public static string GetPage(string url, string postData,string encodeType,out string err)

{

Stream outstream = null;

Stream instream = null;

StreamReader sr = null;

HttpWebResponse response = null;

HttpWebRequest request = null;

Encoding encoding = Encoding.GetEncoding(encodeType);

byte[] data = encoding.GetBytes(postData);

// 准备请求...

try

{

// 设置参数

request = WebRequest.Create(url) as HttpWebRequest;

CookieContainer cookieContainer = new CookieContainer();

request.CookieContainer = cookieContainer;

request.AllowAutoRedirect = true;

request.Method = "POST";

request.ContentType = "application/x-www-form-urlencoded";

request.ContentLength = data.Length;

outstream = request.GetRequestStream();

outstream.Write(data,0,data.Length);

outstream.Close();

//发送请求并获取相应回应数据

response = request.GetResponse() as HttpWebResponse;

//直到request.GetResponse()程序才开始向目标网页发送Post请求

instream = response.GetResponseStream();

sr = new StreamReader( instream, encoding );

//返回结果网页(html)代码

string content = sr.ReadToEnd();

err = string.Empty;

return content;

}

catch(Exception ex)

{

err = ex.Message;

return string.Empty;

}

}

上面的代码很好懂,就不多费口水了,只谈几点要注意的问题:

如果你的程序需要保留SessionID,如ASP.NET中的那个SessionID。比如说自动登录后,可能还要后继的处理,则你需要在向下一个页面发送请求之前将前一个request返回的cookieContainer赋值给新的request,因为在cookieContainer中保留了一个叫做ASPNETSessionID的Cookie。

如果你Post的目标页面是ASP.NET页面,则一般在要提交的Form里都有一个__ViewState隐藏Input字段,一个服务器返回的网页源码的ViewState的例子如下,

value="dDwtMzg4MDA0NzA7Oz7+jHQ0vF37/ga2CitRkQ3sfg+ePg==" />

然而在嗅探器中捕捉到的Post数据是:

__VIEWSTATE=dDwtMzg4MDA0NzA7Oz7%2BjHQ0vF37%2Fga2CitRkQ3sfg%2BePg%3D%3D&UserName=admin&Password=123&Submit=Button0

请大家注意,这里ViewState的数据和前面的有点不一样,差别是其中的”+/=”等符号都被转成了%2B,%2F,%3D等,这其实将ViewState的值进行了URL编码,大家可以用System.Web.HttpUtility.UrlEncode()方法来做这种转换

当然,如果你只需要对页面做一次性访问,则大可不必理会这些,只用根据嗅探器捕获的结果来发送数据就可以了,但是如果你需要根据页面返回的ViewState值动态处理,则需要注意这一点。

2. 从HTML网页代码中提取信息

要从HTML网页中提取信息,首先得将网页代码格式化成XML形式的文件,然后可以用XPath很方便的提取出自己想要的信息,要将HTML格式化为XML形式,目前有几个选择

1、 Chris Lovett的SgmlReader:

http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=b90fddce-e60d-43f8-a5c4-c3bd760564bc

2、 Simon Mourier的.NET Html Agility Pack

http://blogs.msdn.com/smourier/archive/2003/06/04/8265.aspx

我选择了SgmlReader, 通过实际使用,发现SgmlReader也不是尽善尽美,格式化出来的XML有时候嵌套关系会搞错,但即使这样,根据他格式化出来的文本,用来提取数据也足够了。

public static DataSet ParsePage(string pageContent, string xpath, out string err)

{

err = string.Empty;

string pageContent = this.tbHTML.Text;

StreamReader streamReader = null;

StringWriter strWriter = null;

SgmlReader sgmlReader = null;

XmlTextWriter xmlWriter = null;

try

{

sgmlReader = new SgmlReader();

sgmlReader.DocType = "HTML";

sgmlReader.InputStream = new StringReader(pageContent);

strWriter = new StringWriter();

xmlWriter = new XmlTextWriter(strWriter);

xmlWriter.Formatting = Formatting.Indented;

while (sgmlReader.Read())

{

if (sgmlReader.NodeType != XmlNodeType.Whitespace)

{

xmlWriter.WriteNode(sgmlReader, true);

}

}

string wellFormedHTML = strWriter.ToString();

this.tbHTML.Text = wellFormedHTML;

string xpath = this.tbXPath.Text;

XPathDocument doc = new XPathDocument(new StringReader(wellFormedHTML));

XPathNavigator nav = doc.CreateNavigator();

XPathNodeIterator nodes = nav.Select(xpath);

while (nodes.MoveNext())

{

this.tbResult.Text += nodes.Current.Value+"/n";

}

}

catch (Exception exp)

{

string err = exp.Message;

MessageBox.Show("错误:"+err);

}

}

}

根据上面的代码来看,目前主要的问题就是要设置正确的XPath了,Code Project上有篇文章提供了一个简单的XPath查询工具,我对其作了一些修改,主要增加了在节点的正文中搜索某个字符串的功能,方便大家根据获得的HTML页面查询XPath

Debugging XPath Queries : http://www.codeproject.com/dotnet/xpath_visualizer.asp

例如下面是一个根据查询出来的结果格式化后的XML文本片断,该信息的XPath为

//div[@class=”content”]/DIV[@id=”tblwithbck”]/TABLE/TR/TD/TABLE/TR/TD/DIV[@class=”data”]

需要注意的是XPath中的每个路径是大小写敏感的,我就是一开始没注意这个问题,犯了些错误。

2 piece(s) 42 K departed on flight KE6316/04JUN from PVG to ICN

Actual Time of Flight-Departure : 19:20

Scheduled Time of Flight-Arrival : 21:55

2 piece(s) 42 K departed on flight 9S0910/06JUN from ICN to DFW

Actual Time of Flight-Departure : 22:15

Scheduled Time of Flight-Arrival : 05:35+1

2 piece(s) 42 K departed on flight 3A3617/07JUN from DFW to ELP

Actual Time of Flight-Departure : 22:00

2 piece(s) 42 K arrived in ELP from flight 3A3617

Scheduled arrival : 08 JUN

Goods checked in at : 11:00

Arrival docs delivered for 2 piece(s) 42 K on 09 JUN at 09:48 in ELP

转载于:https://www.cnblogs.com/songtzu/archive/2012/08/02/2620394.html

c#自动向网页Post信息并提取返回的信息相关推荐

  1. Java基础练习题5--[给定一段字符串,将里面的信息进行提取,(注意:需要考虑信息是可变的)String s=“张三:上机成绩=90,笔试成绩=78“+“李四:上机成绩=68,笔试成绩......]

    题目:给定一段字符串,将里面的信息进行提取,(注意:需要考虑信息是可变的) String s = "张三:上机成绩=90,笔试成绩=78;" + "李四:上机成绩=68, ...

  2. php apk包信息,php提取apk包信息

    最近在项目中需要使用 php 提取 apk 包的主要信息如包名.应用名称.版本号.入口地址和应用 Icon 等.安卓 apk 的大部分信息都保存在包内的 AndroidManifest.xml 文件中 ...

  3. react骨架屏自动生成_用纯 DOM 的方式结合 Puppeteer 自动生成网页骨架屏

    骨架屏是在页面数据尚未加载完成前先给用户展示出页面的大致结构,直到请求数据返回后再显示真正的页面内容:随着单页应用( SPA )的越来越流行,单页应用的用户体验也越来越得到前端开发者的关注:为了优化用 ...

  4. python生成表格并显示在浏览器_python自动打开浏览器下载zip并提取内容写入excel...

    前言 佬们轻喷,里面有些代码都是现学现写的,一些细节没处理好的地方还请指出来~~~ 首先贴上效果图:有些部分我没有放进来,比如浏览器的启动,但我详细聪明的你们那个玩意肯定一学就会.有些东西我没放进来 ...

  5. 使用Python爬虫示例-自动下载网页音频文件

    使用Python爬虫示例-自动下载网页音频文件 使用库 目标网站 获取并解析网页源代码 访问下载链接 使用库 requests 用来发送http请求. BeautifulSoup 一个灵活又方便的网页 ...

  6. java获取页面标签_java获取网页源代码后,提取标签内容……

    java获取网页源代码后,提取标签内容-- 关注:245  答案:2  mip版 解决时间 2021-02-01 09:11 提问者咏bù琂败 2021-01-31 13:49 import java ...

  7. 金融数据分析之公司年报会计师事务所信息批量提取

    金融数据分析之PDF年报中词频率统计 阅读本文之前可以看浏览一下上面这篇文章,对大数据分析和年报处理有一个大概的了解. 目录 一.前言 二.需求分析 三.数据特征分析 四.代码实现 五.提取结果示列 ...

  8. 使用selenium自动爬取斗鱼直播平台的所有房间信息

    使用selenium自动爬取斗鱼直播平台的所有房间信息 文章目录 使用selenium自动爬取斗鱼直播平台的所有房间信息 使用selenium实现动态页面模拟点击 什么是selenium? selen ...

  9. 企业什么喜欢做电视看板,电视看板浏览网页的必备工具 电视看板浏览器 电视看板自动打开网页

    企业喜欢做电视看板主要是因为它可以提供以下几个方面的优势: 增强企业形象:电视看板可以将企业的信息和广告以更加生动.直观的方式呈现出来,提高企业形象和知名度. 提高工作效率:电视看板可以在企业内部作为 ...

最新文章

  1. python异常包_python异常处理与导入模块与导入包
  2. [转]关于数据中台、数据平台、数据仓库、数据湖等数据概念的对比解析
  3. python OSError: [Errno 24] Too many open files | HTTPConnectionPool(host=‘‘, port=80): Max retries e
  4. Struts2的标签概述
  5. VS2017编写C++多文件时,出现LNK2005、LNK1169报错的解决方法
  6. C语言编程>第八周 ③ 请编写一个函数void fun(char orig[],char result[],int flg),其功能是:删除一个字符串中指定下标的字符。其中,orig指向……
  7. react 日期格式 排序
  8. .Net Core的优势
  9. 秒解UTF-8带来的烦恼
  10. 使用DLL封装应用程序的资源
  11. 用小姐姐的声音为你指路,实时语音导航功能如何实现?
  12. 管理咨询的甲方和乙方
  13. 服务器如何防御攻击?
  14. 人工神经网络与神经网络,神经网络最新研究方向
  15. 刘晓燕核心词汇趣讲笔记-第八课
  16. iframe基础入门使用
  17. 在mysql中er是什么模型_er模型是反映数据库应用系统的什么模型
  18. 《蓝海战略》让你竞争中获得优势
  19. SCLS封面:水稻微生物组时间序列分析
  20. skynet服务的缺陷 lua死循环

热门文章

  1. 使用node来搭建简单的后台业务
  2. mysql 关联关系
  3. linux挂载windows共享的远程目录
  4. MySQL 在 LIMIT 条件后注入
  5. 一步一图一代码之排序二叉树
  6. 生成各种统计图的C#方法
  7. shell 读mysql内数据
  8. applet操作本地文件
  9. Win64 驱动内核编程-11.回调监控进线程句柄操作
  10. hdu4993(水题)