暑假集训虽然很快乐,偶尔也会比较枯燥,,这个时候就需要自娱自乐...
然后看hdu的排行榜发现,除了一些是虚拟测评机的账号以外,有几个都是AC自动机器人
然后发现有一位作者是用网页填表然后按钮模拟,,,默默噗噗的笑了。。。
先来晒一下排行榜
要模拟网页,,当然POST大法好啊,直接模拟发送POST数据不就好了咩,,搞填表啥的多麻烦,完全可以写一个程序后台自动跑。
然后他说了一句AC率能达到50%以上的爬虫也是挺吊的,,于是激起了我试一试的决心(我是不是很wuliao)...
先解释一下POST大法是啥。。。。
貌似研究POST的话,,弄易语言的可能研究的会比较多,很多人会利用POST来实现注册机,采集机,发贴机等等,,这里面的利益关系也是很深的
但是易语言弄POST也会遇到一些局限,,毕竟是语言的局限,再怎样也无法跟C#大法来比较,虽说C#用来弄单纯的POST略有浪费。。。
网页与网页服务器是利用http协议传输数据,包括两种,一种是GET一种是POST
模拟浏览器的点击啥的,,其实最终的目的是让浏览器解析网页,然后发送对应的数据包反馈给服务器
然而我们为什么不直接发送对应的数据包给服务器呢?这样就不关浏览器的事情了,也增加了程序的鲁棒性
对于整个程序总体的思路是这样的:
1.首先在百度上搜索对应的题号,然后采集百度上来自csdn的链接
2.对之前采集的链接利用类直接获取网页源码,从中解析code部分
3.最重要的一个剪枝,获取这个网页中<title>和</title>中的内容,从里面查找是否含有题号!!通过这个剪枝,整个AC率可以上升N倍~
4.认证code部分中是否含有"#include"这个内容,,这样可以防止code边框中可能是其他内容而不是代码
5.去杭电提交代码,如果通过了就下一题,不通过继续在之前解析的csdn中找代码
然后我们来一条一条的分析。。
首先放一个我自己写好的类,里面封装了最基础的http类和一些常用的函数(其实http类和Regex类只是把C#中的WebRequest类和Regex类简化了一下,,这样写起来更方便,然后稍微增加了几个常用到的文本处理的静态函数,以方便调用 )
/*Exyao_http.cs*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace Exyao {
class Exyao_http {
public CookieContainer cookie = new CookieContainer();
public string encode;
public HttpWebResponse response;
public Exyao_http(string _Encoding) {
encode = _Encoding;
}
public string GET(string url) {
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(url);
http.Method = "GET";
http.CookieContainer = cookie;
HttpWebResponse res = (HttpWebResponse)http.GetResponse();
response = res;
Stream s = res.GetResponseStream();
StreamReader rs = new StreamReader(s, Encoding.GetEncoding(encode));
string ret = rs.ReadToEnd();
rs.Close();
s.Close();
return ret;
}
public string POST(string url, string data = "") {
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(url);
http.CookieContainer = cookie;
http.Method = "POST";
http.ContentType = "application/x-www-form-urlencoded";
Stream sd = http.GetRequestStream