图书馆自动答题机器人

百度贴个代码都不方便 ,更諻论添加附件了
搬cnblogs了(囧,cnblogs开通博客还要申请)


因为图书馆迟还书要做题,故用C#写了个自动答题的软件,10秒钟答完
之所以用C#,因为C#封装了许多高级类,用来做与网络相关的程序非常方便

1.抓包分析
第一步先提交卡号,会返回一个做题的页面,

尝试做一道题,用fiddler2分析发现其提交了UserName,PayListId,RightCount,ErrorCount,QuestionCount,RepeatTimes,FinishedQuestionId,QuestionID,Answer等数据,查看网页源代码,发现其用一个hidden属性的input隐性提交的,UserName是校园卡号,Answer是答案,其他也不难推测。
2.编码
用C#最大的好处就是可以用它封装好的HttpWebRequest类HttpWebResponse类实现模拟浏览器的操作
(参考使用 HttpWebRequest 向网站提交数据
3.注意的问题:
编码中有一个问题就是回答问题错误过半数它的RepeatTimes会加1,要求重新开始答题,如果三次答题不通过再提示重新开始。
因此有必要提高我们再题的准确性,基于此,开辟一个Directory<string,string>的对象,存储题号和答案,在开始答题前从answers.txt读入题目与答案,如果某个问题有记录再采取它的答案,否则随机生成一个答案,回答下一题之前判断这个答案是否正确,若正确则存入Directory对象中,否则排除,最后答题完毕再把Directory写入answers.txt,越后越能提高答题准确性。

虽然只限中大图书馆,但网络编程的流程大致如上

代码如下:

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Web;
using System.IO;
using System.Collections.Generic;
using System.Threading;

namespace LIBROBOT
{

public partial class FormMain : Form
{

public FormMain()
{
InitializeComponent();
//CardNum.Text = "0000312121";
//CardNum.Text = "0000322618";
}

private void StartBtn_Click(object sender, EventArgs e)
{
String cardnum
=CardNum.Text;
if (cardnum.Trim().Length != 10) {
MessageBox.Show(
"请输入10位证件号!");
return;
}

UserName
= cardnum;

Init();
if (RightCount == null || ErrorCount == null || QuestionCount == null)
{
MessageBox.Show(
"您无过期记录!");
return;
}
while (!AnswerQuestion())
{
lblStatus.Text
= "答错:"+ErrorCount+"道,答对:"+RightCount+"";
}


}

private void ReadAnswers() {
RightAnswers
=new Dictionary<string,string>();
StreamReader sr;
try {
sr
=File.OpenText("answers.txt");
sr.ReadLine();
while (sr.Peek() != -1)
{
String str
= sr.ReadLine();

string q=str.Split(':')[0];
string a=str.Split(':')[1];
RightAnswers.Add(q, a);
}
sr.Close();
}
catch(Exception e){
//MessageBox.Show(e.Message);
}

}
private void WriteAnswers() {

StreamWriter sw;
sw
= File.CreateText("answers.txt");
foreach(var item in RightAnswers.Keys)
{
sw.WriteLine(item
+ ":" + RightAnswers[item]);

}
sw.Flush();
sw.Close();
//StreamWriter sw;
}
private String GetAnswer(String QID) {
if (!RightAnswers.ContainsKey(QID))
return "1";

return RightAnswers[QID];

}
private bool AnswerQuestion() {


Thread.Sleep(
10);
if (QuestionID == null) {
WriteAnswers();
MessageBox.Show(
"机器人学习失败导致三次未通过");
return true;
}

Answer
=GetAnswer(QuestionID);

string param = "UserName=" + UserName + "&PayListId=" + PayListId
+ "&RightCount=" + RightCount + "&ErrorCount=" + ErrorCount
+ "&QuestionCount=" + QuestionCount + "&RepeatTimes=" + RepeatTimes
+ "&FinishedQuestionId=" + FinishedQuestionId + "&QuestionID=" + QuestionID
+ "&Answer=" + Answer;
byte[] bs = Encoding.ASCII.GetBytes(param);

HttpWebRequest req
= (HttpWebRequest)HttpWebRequest.Create("http://202.116.65.77:8001/sysulib/html/LibEducateSystem.do?Command=CheckAnswer");
req.Method
= "POST";
req.ContentType
= "application/x-www-form-urlencoded";
req.ContentLength
= bs.Length;

using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs,
0, bs.Length);
}

HttpWebResponse res
= (HttpWebResponse)req.GetResponse();

//在这里对接收到的页面内容进行处理
if (res.StatusCode != HttpStatusCode.OK)
{
MessageBox.Show(
"页面出错!");
return true;
}
Stream resStream
= res.GetResponseStream();
StreamReader streamReader
= new StreamReader(resStream, Encoding.UTF8);
// streamReader = new StreamReader(resStream, Encoding.Default);
String htmlCont = streamReader.ReadToEnd();
streamReader.Close();

res.Close();



if(htmlCont.IndexOf("完成时间")!=-1){
WriteAnswers();
MessageBox.Show(
"答题完毕!");
return true;
}
Parser(htmlCont,
false);
return false;

}

private void Init()
{

ReadAnswers();
string param = "userName=" + UserName + "&x=49&y=19";//x,y不明所以
byte[] bs = Encoding.ASCII.GetBytes(param);

HttpWebRequest req
= (HttpWebRequest)HttpWebRequest.Create("http://202.116.65.77:8001/sysulib/html/LibEducateSystem.do?Command=CheckUserStatus");
req.Method
= "POST";
req.ContentType
= "application/x-www-form-urlencoded";
req.ContentLength
= bs.Length;

using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs,
0, bs.Length);
}

HttpWebResponse res
= (HttpWebResponse)req.GetResponse();


//在这里对接收到的页面内容进行处理
if (res.StatusCode != HttpStatusCode.OK)
{
MessageBox.Show(
"页面出错!");
return;
}
Stream resStream
= res.GetResponseStream();
StreamReader streamReader
= new StreamReader(resStream, Encoding.UTF8);
// streamReader = new StreamReader(resStream, Encoding.Default);
String htmlCont = streamReader.ReadToEnd();
streamReader.Close();

//分析


Parser(htmlCont,
true);

res.Close();

}

private void Parser(String htmlCont,bool isInit)
{

if (!isInit)
{
if ((htmlCont.IndexOf("#FF0000") != -1) || htmlCont.IndexOf("#ff0000") != -1)
{
if (Answer == "1") Answer = "2";
else Answer = "1";

}
if (!RightAnswers.ContainsKey(QuestionID)) {
RightAnswers.Add(QuestionID, Answer);
}

}



int ptr = htmlCont.IndexOf("PayListId");
if (ptr < 0)
return;
htmlCont
= htmlCont.Substring(ptr, 700);
htmlCont
= htmlCont.Substring(18, htmlCont.Length - 18);
PayListId
= htmlCont.Substring(0, htmlCont.IndexOf("\""));

//"PayListId\" value=\"35649\" />\n\t\t"
ptr = htmlCont.IndexOf("RightCount");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(19, htmlCont.Length - 19);
RightCount
= htmlCont.Substring(0, htmlCont.IndexOf("\""));

ptr
= htmlCont.IndexOf("ErrorCount");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(19, htmlCont.Length - 19);
ErrorCount
= htmlCont.Substring(0, htmlCont.IndexOf("\""));

ptr
= htmlCont.IndexOf("QuestionCount");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(22, htmlCont.Length - 22);
QuestionCount
= htmlCont.Substring(0, htmlCont.IndexOf("\""));

ptr
= htmlCont.IndexOf("RepeatTimes");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(20, htmlCont.Length - 20);
RepeatTimes
= htmlCont.Substring(0, htmlCont.IndexOf("\""));

ptr
= htmlCont.IndexOf("FinishedQuestionId");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(27, htmlCont.Length - 27);
FinishedQuestionId
= htmlCont.Substring(0, htmlCont.IndexOf("\""));



ptr
= htmlCont.IndexOf("QuestionID");
if (ptr < 0) return;
htmlCont
= htmlCont.Substring(ptr, htmlCont.Length - ptr);
htmlCont
= htmlCont.Substring(19, htmlCont.Length - 19);
QuestionID
= htmlCont.Substring(0, htmlCont.IndexOf("\""));




}

private String UserName;
private String PayListId;
private String RightCount;
private String ErrorCount;
private String QuestionCount;
private String RepeatTimes;
private String FinishedQuestionId;
private String QuestionID;
private String Answer;
private Dictionary<string,string> RightAnswers;//存储正确答案的临时变量
}
}
原文地址:https://www.cnblogs.com/sunset/p/1761889.html