• Facebook
  • google
  • linkedin
  • skype
  • twitter
  • 人人
  • 新浪微博
  • 邮箱
  • QQ
微信PHP开发指南(一)——模拟网站登录获取信息

微信PHP开发指南(一)——模拟网站登录获取信息

官方文档当然是最重要的:http://mp.weixin.qq.com/wiki/index.php

首先是一个官方的PHP的接入示例,里面包含了一个最简单的验证和自动回复的示例。这整个结构都是今后开发的一个基础。我们可以在上面继续开发。

我们来看一下官方给出的代码:

<?php
/**
  * wechat php test
  */
 
//define your token
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();
 
class wechatCallbackapiTest
{
	public function valid()
    {
        $echoStr = $_GET["echostr"];
 
        //valid signature , option
        if($this->checkSignature()){
        	echo $echoStr;
        	exit;
        }
    }
 
    public function responseMsg()
    {
		//get post data, May be due to the different environments
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
 
      	//extract post data
		if (!empty($postStr)){
 
              	$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                $fromUsername = $postObj->FromUserName;
                $toUsername = $postObj->ToUserName;
                $keyword = trim($postObj->Content);
                $time = time();
                $textTpl = "<xml>
							<ToUserName><![CDATA[%s]]></ToUserName>
							<FromUserName><![CDATA[%s]]></FromUserName>
							<CreateTime>%s</CreateTime>
							<MsgType><![CDATA[%s]]></MsgType>
							<Content><![CDATA[%s]]></Content>
							<FuncFlag>0</FuncFlag>
							</xml>";             
				if(!empty( $keyword ))
                {
              		$msgType = "text";
                	$contentStr = "Welcome to wechat world!";
                	$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;
                }else{
                	echo "Input something...";
                }
 
        }else {
        	echo "";
        	exit;
        }
    }
 
	private function checkSignature()
	{
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];	
 
		$token = TOKEN;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr, SORT_STRING);
		$tmpStr = implode( $tmpArr );
		$tmpStr = sha1( $tmpStr );
 
		if( $tmpStr == $signature ){
			return true;
		}else{
			return false;
		}
	}
}
 
?>

在修改开发者模式中服务器配置时,微信服务器会向你所填写的URL发送验证,验证是否是你所定义的Token值,如果你的服务器能够正常响应并返回值,则验证成功。以上代码中的checkSignature()函数就是用来响应这个验证过程的。

changeServerConfig

而responseMsg()函数自然是用来响应用户发送的消息的了。

我们可以在这个函数中大做文章。根据用户回复过来的消息,我们进行回复,而回复怎样的信息,中间经历过如何的流程,是我们可以决定的。这也是我们使用开发模式的原因。虽然有诸多限制,但是我们仍然能在这里大展拳脚。

我目前是在替我们学校做微信公众平台。目前实现了晨跑查询、成绩查询、聊天机器人对接。下面我以成绩查询为例,仔细描述一下实现过程,并给出关键代码。

由于直接访问学校的数据库缺乏安全性,政策也不允许。所以曲线救国,我们采取模拟用户登录并用正则表达式抓取页面上所需结果的方法。

我们采取cURL。cURL可能在某些PHP的发行版中没有默认打开,我们需要编辑php.ini手动打开。

首先我们解决如何模拟登录。由于学校教务处的网站是ASP .NET的,无法简单的POST表单值给服务器,因为ASP .NET自身POST了很多其它数据。我们需要手动抓取下,看它POST的完整的数据。

抓取采用Firefox的Live HTTP Headers插件。这个插件的项目主页:http://livehttpheaders.mozdev.org/

然后在页面正常登录,查看Live HTTP Headers抓取的数据。下面高亮处是页面向服务器POST的数据。

Live HTTP Headers

我们将这段字符串复制出来。

__VIEWSTATE=%2FwEPDwULLTIxMzA2MjYxMjQPZBYCAgEPZBYCAgcPDxYCHgRUZXh0BQQyMDMyZGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFC2ltZ2J0bkxvZ2lus68ZoVKzELO3e1%2ByB4%2BYYTTnKoU%3D&txUserID=1111111111&txUserPw=abcdefgh&rdblUserType=S&imgbtnLogin.x=42&imgbtnLogin.y=17&__EVENTVALIDATION=%2FwEWBwL2x%2B6UBgKRi5i3CwKLkLTxAQKKkLTxAQKFkLTxAQLm%2F56fDQLHg6JXhXxNHdxibBdeXc7kOSrpaP%2B0paw%3D

红色高亮处就是POST的表单值。第三个代表角色为学生,我们可以不理会,就默认为S。前两个是用户名和密码。我们只需要改变用户名和密码的值,POST这一段字符串给服务器,就可以模拟登录。此外,要注意Live HTTP Headers抓取到了Session。所以我们要在cURL模拟登录的时候打开Session。

<?php
$cookie_file = tempnam('./temp','cookie');//cookie存放位置
$login_url  = 'http://www.abc.com/login.aspx';//登录URL
$username='1111111111';
$password='abcdefgh';
$post_fields = '__VIEWSTATE=%2FwEPDwULLTIxMzA2MjYxMjQPZBYCAgEPZBYCAgcPDxYCHgRUZXh0BQMyNDVkZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAQULaW1nYnRuTG9naW59yADsZAXJC3CmUge2HczBNNq9DA%3D%3D&txUserID='.$username.'&txUserPw='.$password.'&rdblUserType=S&imgbtnLogin.x=39&imgbtnLogin.y=19&__EVENTVALIDATION=%2FwEWBwKX2tv2AgKRi5i3CwKLkLTxAQKKkLTxAQKFkLTxAQLm%2F56fDQLHg6JXwNSaHhxonOYuwAnlNFimXV0jkMU%3D';
$ch = curl_init($login_url);
$this_header = array("content-type: application/x-www-form-urlencoded;charset=gb2312");//由于网站是GB2312编码的,所以注意抓取时更改编码
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);//注意要带cookie
curl_exec($ch);
curl_close($ch);
$url='http://www.abc.com/score.aspx';//登录后转向
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
$contents = curl_exec($ch);
?>

我们注意到网站是GB2312编码的,不在抓取的时候更改编码的话,抓取到的结果页面为乱码。

首先我们来分析一下结果页面的源代码。

<table id="ctl00_ContentPlaceHolder1_dlStuCrs" cellspacing="0" border="0" style="width:827px;border-collapse:collapse;">
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl00_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第1学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl00_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>计算机导论 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>高等数学A(一) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>线性代数 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>大学英语(一) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>思想道德修养与法律基础 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>高级程序设计语言 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 7 </td>
<td>&nbsp;</td>
<td>思想政治理论实践(思修) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 8 </td>
<td>&nbsp;</td>
<td>体育(一) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 9 </td>
<td>&nbsp;</td>
<td>军事教育 </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 10 </td>
<td>&nbsp;</td>
<td>军事训练 </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl01_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第2学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl01_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>生活中的税收学 </td>
<td>公共选修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>中国旅游地理 </td>
<td>公共选修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>计算机系统维护 </td>
<td>公共选修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>会计学 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>高等数学A(二) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>马克思主义基本原理概论 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 7 </td>
<td>&nbsp;</td>
<td>大学英语(二) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 8 </td>
<td>&nbsp;</td>
<td>数据结构与算法 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 9 </td>
<td>&nbsp;</td>
<td>离散数学 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 10 </td>
<td>&nbsp;</td>
<td>面向对象技术引论 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 11 </td>
<td>&nbsp;</td>
<td>思想政治理论实践(马克思) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 12 </td>
<td>&nbsp;</td>
<td>体育(二) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl02_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第3学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl02_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>大学英语四级 </td>
<td>证书考试 </td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>世界名著赏析 </td>
<td>公共选修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>专项体育-跆拳道1 </td>
<td>体育限选 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>中国近现代史纲要 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>大学英语(三) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>计算机组成原理及系统结构 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 7 </td>
<td>&nbsp;</td>
<td>运筹学 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 8 </td>
<td>&nbsp;</td>
<td>Java程序设计 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 9 </td>
<td>&nbsp;</td>
<td>VC++面向对象程序设计 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 10 </td>
<td>&nbsp;</td>
<td>思想政治理论实践(近代史) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl03_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第4学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl03_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>大学英语六级 </td>
<td>证书考试 </td>
<td>&nbsp;</td>
<td>考试 </td>
<td>0</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>专项体育-跆拳道2 </td>
<td>体育限选 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>概率论与数理统计 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>4</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>大学英语(四) </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>5</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>毛思和中国特色社会主义理论体系 </td>
<td>公共课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>4</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>数据库原理与应用 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>4</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 7 </td>
<td>&nbsp;</td>
<td>操作系统 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>4</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 8 </td>
<td>&nbsp;</td>
<td>动态网站技术 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>3</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 9 </td>
<td>&nbsp;</td>
<td>思想政治理论实践(毛思) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>1</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 10 </td>
<td>&nbsp;</td>
<td>多媒体技术与网站设计 </td>
<td>专业类选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 11 </td>
<td>&nbsp;</td>
<td>Java企业级开发项目实践 </td>
<td>专业类选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 12 </td>
<td>&nbsp;</td>
<td>社会分层与流动 </td>
<td>跨专业选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>2</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 13 </td>
<td>&nbsp;</td>
<td>经济社会学 </td>
<td>跨专业选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>2</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl04_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第5学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl04_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>软件工程 </td>
<td>基础课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>计算机网络与通信(双语) </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>统计学 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>英语口语训练(一) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>软件项目管理 </td>
<td>专业类选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>VC++项目实践 </td>
<td>专业类选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 7 </td>
<td>&nbsp;</td>
<td>证券投资学 </td>
<td>跨专业选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 8 </td>
<td>&nbsp;</td>
<td>公民、社会与发展 </td>
<td>跨专业选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 9 </td>
<td>&nbsp;</td>
<td>组织社会学 </td>
<td>跨专业选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
<tr>
<td><table>
<tr>
<td style="width: 86px; height: 21px"><span id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl05_Label5" style="color:#400040;font-size:Medium;font-weight:bold;">第6学期</span></td>
<td style="width: 100px; height: 21px"></td>
<td style="width: 100px; height: 21px"></td>
</tr>
<tr>
<td colspan="3" style="height: 166px"><div>
<table cellspacing="0" cellpadding="4" rules="all" border="1" id="ctl00_ContentPlaceHolder1_dlStuCrs_ctl05_gvDtlCrsStu" style="color:#333333;font-size:10.5pt;height:75px;width:961px;border-collapse:collapse;">
<tr style="color:DimGray;background-color:#E2F5FB;font-weight:bold;">
<th scope="col">序号</th>
<th scope="col">课程代号</th>
<th scope="col">课程名称</th>
<th scope="col">课程类型</th>
<th scope="col">成绩</th>
<th scope="col">考核方式</th>
<th scope="col">学分</th>
<th scope="col">绩点</th>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 1 </td>
<td>&nbsp;</td>
<td>ERP原理与应用 </td>
<td>专业课必修</td>
<td>&nbsp;</td>
<td>考试 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 2 </td>
<td>&nbsp;</td>
<td>B/S系统架构 </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 3 </td>
<td>&nbsp;</td>
<td>C/S系统架构 </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 4 </td>
<td>&nbsp;</td>
<td>数据库综合设计 </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:#EFF3FB;">
<td> 5 </td>
<td>&nbsp;</td>
<td>英语口语训练(二) </td>
<td>实践必修 </td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr style="background-color:White;">
<td> 6 </td>
<td>&nbsp;</td>
<td>Linux操作系统 </td>
<td>专业类选修</td>
<td>&nbsp;</td>
<td>考查 </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</div></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
</table></td>
</tr>
</table>

以上为结果页面的部分源代码,且其中的某些实际内容已经隐去。

我们可以看到每一个学期的成绩均被一个id为ctl00_ContentPlaceHolder1_dlStuCrs_ctl05_gvDtlCrsStu的table所包括。红色部分数字根据不同学期而不同,依次从0到7,各代表8个学期。

而我们只需要抓取最新的一个学期即可。我们需要依次判断是否存在一些标签。

<?php
$flag=7;
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl07_gvDtlCrsStu')!== false)
{
$flag=7;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl06_gvDtlCrsStu')!== false)
{
$flag=6;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl05_gvDtlCrsStu')!== false)
{
$flag=5;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl04_gvDtlCrsStu')!== false)
{
$flag=4;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl03_gvDtlCrsStu')!== false)
{
$flag=3;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl02_gvDtlCrsStu')!== false)
{
$flag=2;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl01_gvDtlCrsStu')!== false)
{
$flag=1;
}else
if(stripos($contents,'ctl00_ContentPlaceHolder1_dlStuCrs_ctl00_gvDtlCrsStu')!== false)
{
$flag=0;
}
?>

最后根据flag的值我们就可以知道最新的是哪一个学期。

然后利用正则表达式,清理、去除标签。

<?php
preg_match('/<table cellspacing=\"0\" cellpadding=\"4\" rules=\"all\" border=\"1\" id=\"ctl00_ContentPlaceHolder1_dlStuCrs_ctl0'.$flag.'_gvDtlCrsStu\" height=\"75\" width=\"961\">(.*)<\/table>/isU',$contents,$message);
preg_match_all('/<td>([\w\W]*?)<\/td>/',$message[0],$message2);
?>

经过试验发现,微信消息中的换行符“\n”在消息中直接显示出来了,所以我们将其替换成特殊字符串之后再替换回来。并且清理多余的空格,以及处理GBK到UTF-8编码的转换(微信只能接受UTF-8编码)。

<?php
for($i=2;$i<count($message2[1]);$i=$i+8)
{
	$contentStr=$contentStr.$message2[1][$i].$message2[1][$i+2].'huanhang';
}
$contentStr=trim(strip_tags($contentStr),' ');
$contentStr=mb_convert_encoding($contentStr,'UTF-8','gbk');
$contentStr=str_replace(" ", "", $contentStr);
$contentStr=str_replace("huanhang", "\n", $contentStr);
?>

最后输出消息,并且关闭cURL。

<?php
echo $contentStr;
curl_close($ch);
?>

现在就解决了微信发送用户名、密码然后模拟登录,抓取信息并且回复消息的问题。但是由于微信管理后台能看到用户与微信服务器交互的每一句留言,直接明文发送密码是不可取的。所以我们需要有一个授权。利用数据库来保存并读取用户名和密码,并且存储微信的openid来实现账号的绑定。这样不仅有利于安全性,并且可以做到一键查询(自定义菜单或让用户回复指定关键字)。这些我将会在下一篇博文中仔细介绍。

回复