本站推出山寨版四六级查分服务(附源码)

标签:JavaScript, PHP, Python

首先不得不批一下99宿舍,丫的查个分还弄广告,还有30秒限制。采访时还说那30秒限制是为了避免查询量过大…
丫的我去看了下它的JavaScript,点击查询时,很快就拿到数据了,却到30秒才显示,这也叫避免查询量过大?真要这么做的话,应该在30秒后才查询。
至于看不懂JavaScript的,查询后在浏览器地址栏输入这行命令,就能显示分数了:
javascript:alert(score);
然后来研究下查询原理吧。
查看99宿舍的查分页的源代码,很容易就能发现这个JavaScript文件:http://img.99sushe.com/res/js/cet0902_noplugin_15.js
然后看到这个函数:
function search(){
   xmlHttp = createXMLHttpRequest();
   xmlHttp.onreadystatechange = handleStateChange;
   startRequest(xmlHttp,"cetscore_99sushe0902.html?t="+testtype+"&id="+testid);
}
哇塞,还用到AJAX啊。
嘛,不鸟它,直接关注地址:"cetscore_99sushe0902.html?t="+testtype+"&id="+testid
testtype就是4或6,testid就是准考证号,把这2个参数填上去,就能拿到一个URL了。
例如,假设有个人考4级,他的准考证号是1234567890,那么URL就是:
http://cet.99sushe.com/cetscore_99sushe0902.html?t=4&id=1234567890
可惜这个地址还不能直接拿到数据,你还得在HTTP header中加上Referer字段,把http://cet.99sushe.com/放进去。

下面给出代码:

Python版:
import urllib2

t = raw_input('Level(4 or 6): ')
id = raw_input('ID: ')

url = 'http://cet.99sushe.com/cetscore_99sushe0902.html?t=%s&id=%s' % (t, id)
req = urllib2.Request(url)
req.add_header("Referer", "http://cet.99sushe.com/")
result = urllib2.urlopen(req)

print result.read()
接着是Google App Engine版,由于新版的GAE不允许在header中更改Referer字段,所以就不能演示了。但老版本(如1.10)的本地开发服务器还是可以用的。

服务器端:
# -*- coding: gbk -*-

from google.appengine.api import urlfetch
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import logging

class CET(webapp.RequestHandler):
  def post(self):
    level = self.request.get('level')
    id = self.request.get('id')
    logging.info('%s' % self.request)

    if level and id:
      url = 'http://cet.99sushe.com/cetscore_99sushe0902.html?t=%s&id=%s' % (level, id)
      result = urlfetch.fetch(url, headers={'Referer': 'http://cet.99sushe.com/'})
      if result.status_code == 200 and result.content:
        list = result.content.split(',')
        self.response.out.write(u"""
      姓名:%s<br />
      学校:%s<br />
      总分:%s<br />
      听力:%s<br />
      阅读:%s<br />
      综合:%s<br />
      写作:%s<br />""" % (unicode(list[6], "gbk"), unicode(list[5], "gbk"), list[4], list[0], list[1], list[2], list[3]))
      else:
        self.response.out.write(u'未找到该考号')
    else:
      self.response.out.write(u'参数错误')

application = webapp.WSGIApplication([
  ('.*$', CET),
])

def main():
  run_wsgi_app(application)

if __name__ == '__main__':
  main()
客户端代码其实和下面的PHP版基本相同,所以这里就不写了。

PHP版:

服务器端:
<?php
header("Content-Type:text/html; charset=gbk");

$level = $_POST['level'];
$id = $_POST['id'];

if (!$id || $level == 'undefined') {
  print('准考证号或考试类型未填');
  exit();
}

$fp = fsockopen('cet.99sushe.com', 80, $errno, $errstr, 10) or exit($errstr.'--->'.$errno);
$header = "GET: /cetscore_99sushe0902.html?t=".$level."&id=".$id." HTTP/1.0 \r\n"
    . "Host: cet.99sushe.com \r\n"
    . "Referer: http://cet.99sushe.com/ \r\n"
    . "Connection: Close\r\n\r\n";

fputs($fp, $header);
$inheader = True;
while (!feof($fp)) {
  $line = fgets($fp);
  if ($inheader && ($line == "\n" || $line == "\r\n")) {
    $inheader = False;
  }
  if (!$inheader) {
    $content.=$line;
  }
}
fclose($fp);

if (strlen($content) < 10) { //查不到好像也会传2个字节过来,所以我就给多点
  print('准考证号或考试类型输入错误');
  exit();
}

$result = explode(',', $content);
printf("姓名:%s<br />学校:%s<br />总分:%s<br />听力:%s<br />阅读:%s<br />综合:%s<br />写作:%s<br />与你临近的同学:%s、%s、%s", $result[6], $result[5], $result[4], $result[0], $result[1], $result[2], $result[3], $result[7], $result[8], $result[9]);
?>
客户端:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
    <title>とも大家族☆山寨四六级查分站点</title>
    <meta name="keywords" content="四六级,四六级查分,山寨" />
    <meta name="description" content="四六级查分山寨站点" />
    <meta name="author" content="keakon" />
    <meta name="copyright" content="とも大家族" />
    <link rel="canonical" href="http://www.keakon.cn/cet/" />
    <script src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("jquery", "1.3.1");
    </script>
    <script type="text/javascript">
      $(document).ready(
        function(){
          $("form").submit(
          function (){
            var id = $("#id").val()
            if (!id || !/^\d+$/.exec(id)){ //判断是否全为数字,我也不知道准考证号是否位数都一样
              $("#result").html('准考证号输入错误').hide().fadeIn(3000); //加了点动画效果
              return false; //不返回false就会提交,没有AJAX效果
            }
            $("#result").load("cet.php",
              {level: $("input:radio[name=level]:checked").val(), id: id}
            ).hide().fadeIn(3000);
            return false;
          });
        }
      );
    </script>
  </head>
  <body>
    <form method="post" action="cet.php">
      准考证号:<input id="id" maxlength="30" size="16" /><br />
      考试类型:四级<input type="radio" name="level" value="4">&nbsp六级<input type="radio" name="level" value="6" /><br />
      <input type="submit" name="submit" id="sm" value="提交" /> <input type="reset" name="reset" value="重填" />
    </form>
    <div id="result" style="padding: 20px 0;color: blue"></div>
    <p style="color: red">本站点仅供查询2008年12月CET考试成绩,数据来自99sushe。</p>
  </body>
</html>
其实最复杂的就是那段jQuery的AJAX代码了,弄了半天才知道怎么获得radio,原来1.3以后版本改了语法…

1条评论 你不来一发么↓ 顺序排列 倒序排列

    向下滚动可载入更多评论,或者点这里禁止自动加载

    想说点什么呢?