一般来说,制作自动提交留言信息的程序,要分为以下步骤:
一、分析填写留言页面的HTML代码,了解页面结构,重点是查找里面的form标记,因为那是提交数据的地方;
二、用抓包工具抓取数据包(如WSockExpert),总结有哪些数据要提交;
三、理顺思路,开工;
四、调试完成
如果要重复提交数据(什么?做连环炮?),最简单的方法是使用循环,没置一个条件可以在适当的时候结束循环就可以了,不要搞成死循环。当然,也可以使用定时器如Timer之类的组件,每隔一段时间提交一次。
在没有设置验证码的页面比较好处理,如果设置了验证码,可以尝试去识别,如果识别不了,也只能手动输入了。
为了确保能够每次顺利提交,最好每次的内容不太相同,如Email地址、名称等,有些页面做了限制的。
一、分析页面结构
打开指定页面,右击查看源文件,按Ctrl + F查找关键字“form”,找到FORM标记,形如
<form name="form1" action="sendmail.php" enctype="multipart/form-data" method="post" onSubmit="return funCheckContactUs(this,'8','')" style="margin:0px">
在这行代码中我们至少知道两个信息,1、提交的页面;2、提交方式为POST。
二、抓包分析
我觉得抓包工具比较好用的是WSockExpert,但使用的时候要把杀毒软件关掉,好像杀毒软件都不太喜欢它,老进行查杀。
用IE把开页面,填好留言内容,注意,不要点击提交。
把开WSockExpert,进程选择IE,尽量使用IE来抓包,因为其它浏览器有时候抓不到数据。开始抓包后,再回到IE,点击提交,再回到WSockExpert,就会看到所捕获的数据了,找到带有POST字样的数据记录。
POST /cn/sendmail.php HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/QVOD, application/QVOD, */*
Referer: http://www.xxxxxxx.com/xx/contact.php
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7da1029390348
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
Host: www.xxxxxxxxx.com
Content-Length: 961
Connection: Keep-Alive
Cache-Control: no-cache
-----------------------------7da1029390348
Content-Disposition: form-data; name="myname"
CheckCode
-----------------------------7da1029390348
Content-Disposition: form-data; name="mr"
Mr.
-----------------------------7da1029390348
Content-Disposition: form-data; name="company"
Microsoft
-----------------------------7da1029390348
Content-Disposition: form-data; name="phone"
88888888
-----------------------------7da1029390348
Content-Disposition: form-data; name="email"
[email protected]
-----------------------------7da1029390348
Content-Disposition: form-data; name="about"
General Enquiries
-----------------------------7da1029390348
Content-Disposition: form-data; name="message"
ThisisContent
-----------------------------7da1029390348
Content-Disposition: form-data; name="x"
25
-----------------------------7da1029390348
Content-Disposition: form-data; name="y"
17
-----------------------------7da1029390348--
上部分是HTTP头部,下部分才是内容,“-----------------------------7da1029390348”是随机生成的分隔符,用的时候直接连上,不用管它。
这里有两个字段,X和Y,我也不知道用来干吗的,反正每次提交都有,不用管它,不影响数据提交。上面提到了有一个随机生成的分隔符,提交的字段内容就是用这个分隔符来划分开来了,包括最后一个回车符也不能掉。
还有一个问题是,如何确定成功提交?从返回的数据看,页面有一个JS脚本,弹出一个对话框,上面有提示,也就是说,在程序中,我们只要找到返回的数据中有这句话的,就说明提交成功。
三、编写代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Net; using System.Threading; namespace PostTest { public partial class Form1 : Form { //变量 string strName = string.Empty;//名字 string strCompn = string.Empty;//公司名称 string strPhone = string.Empty;//电话 string strEmail = string.Empty;//电邮地址 string strContent = string.Empty;//内容 int tCount;//次数 HttpWebRequest rq = null;//向服务器发出请求 HttpWebResponse rp = null;//接收来自服务器的回应 Thread th = null;//线程 public Form1() { //为了能够 多线程访问,设置该属性 CheckForIllegalCrossThreadCalls = false; InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //初始化状态 lblMssge.Text = "准备就绪。"; } /// <summary> /// 在另一个线程上执行 /// </summary> private void Do() { int i = 0;//当前执行次数 while (i < tCount) { strName = strName + i.ToString(); strEmail =i.ToString() + strEmail; rq = (HttpWebRequest)WebRequest.Create(txtAddr.Text); rq.Accept = "image/*,application/*,*/*"; rq.Method = "POST"; rq.ContentType = @"multipart/form-data; boundary=---------------------------7daaa342201c4"; rq.UserAgent = @"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"; rq.Referer = "http://www.xxxxxxx.com/xx/contact.php"; string poststr = null; //分隔符 string s = "-----------------------------7daaa342201c4"; StringBuilder strb = new StringBuilder(); /*名字*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"myname/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append(strName + "/r/n"); /*先生*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"mr/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append("Mr." + "/r/n"); /*公司名称*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"company/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append(strCompn + "/r/n"); /*电话号码*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"phone/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append(strPhone + "/r/n"); /*电邮*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"email/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append(strEmail + "/r/n"); // strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"about/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append("General Enquiries" + "/r/n"); /*内容*/ strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"message/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append(strContent + "/r/n"); //这个我也不知道用来干吗? strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"x/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append("24" + "/r/n"); // strb.Append(s + "/r/n"); strb.Append("Content-Disposition: form-data; name=/"y/"" + "/r/n"); strb.Append(Environment.NewLine);//空白行 strb.Append("8" + "/r/n"); // strb.Append(s); strb.Append("--/r/n"); //strb.Append(Environment.NewLine); poststr = strb.ToString(); //*********************************************** try { byte[] data = Encoding.UTF8.GetBytes(poststr); rq.ContentLength = data.Length;//字节组长度 rq.GetRequestStream().Write(data, 0, data.Length); //返回 rp = (HttpWebResponse)rq.GetResponse(); StreamReader sr = new StreamReader(rp.GetResponseStream()); string res = sr.ReadToEnd();//读取结果 //关闭流 sr.Close(); rp.Close(); System.Diagnostics.Debug.WriteLine(res); //只要判断是否存在“Your email has been submitted. Thank you”, //就可以知道是否提交成功。 if (res.Contains("Your email has been submitted. Thank you")) { txtResult.AppendText(DateTime.Now.ToString() + " 提交成功。/r/n"); } i += 1; lblMssge.Text = "进行了 " + i.ToString() + " 次操作。"; } catch { lblMssge.Text = "出错啦 。"; } } button1.Enabled = true; } private void button1_Click(object sender, EventArgs e) { strName = txtName.Text; strCompn = txtComp.Text; strPhone = txtPhone.Text; strEmail = txtEmail.Text; strContent = txtContent.Text; tCount = int.Parse(txtTimes.Text); txtResult.Clear();//清空文本框 //线程是否已运行 if (th != null) { th = null; } th = new Thread(new ThreadStart(this.Do)); th.Start(); button1.Enabled = false; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //关闭前清理线程 if (th != null) th = null; } } }
四、调试
OK,完成了。