基于HttpClient的正方教务系统模拟登录(带验证码)

有多少人被图片吸引,但事实上,除了金絮,干货,原始地址:csdn爬虫文章。

PS:恩,因为最近在学习web和简单的http协议,所以心血来潮想用java写爬虫爬学校官网(正方教务系统)个人主页基本信息(课程信息、成绩)……),其实我以前学过java你可以在基础教程中写知后觉总是在现阶段完成前一阶段应该完成的任务!也许这就是菜鸟~~~。

写在前面:其实写java爬虫一般采用三种方法:自带仓库(urlconnection),外库(httpclient)以及文档分析库(jsoup);其中jsoup这个第三方库的重点是html除了官方文外,对文档的分析Jsoup.connect()访问网页外没有多余的方法,在访问网页时需要登录的网站爬虫中(get和post方法访问),主要使用前两种方法。httpclient比自带库更灵活高效,所以在爬虫中使用httpclient访问 Jsoup结合操作分析文档。

注:作为一个小白人,当尝试每个别人已经实现和他们没有实现的项目时,或多或少会有问题,这个爬虫项目对我来说也是如此,所以我会写这篇博客文章作为填补坑的记录,但也方便其他刚刚开始的小白人成功完成。如果你正在阅读,你也是一个新的小白人,想使用它java写一个爬虫爬学校官网(大神不喷,请绕道~~~),幸运的是,只要你一步一步地遵循以下文章,你就会得到你想要的结果。(当然,在我下一个描述的项目中,它是通过正式的学术事务系统实现的。如果你的学校官方网站是其他的,事实上,掌握核心技术也是一样的。

前期准备:火狐浏览器,eclipseIDE所需外库jar包:commons-codec-1.3.jarcommons-httpclient-3.1.jarcommons-logging-1.0.4.jarjsouop-1.8.1.jar

注:这些jar包是必不可少的,有些人可能会想:不仅仅是httpclient包好了,为什么还要另外两个包?事实上,只要你知道这三个包的版本都很旧,Apache不再维护和更新,这三个包是相互依赖和必不可少的。(因为我一开始下载的是3.1版本,不想4.X是的,因为有些方法函数的使用是不同的。下载的话我已经分享过了csdn中,可下载:httpclient-jar包下载),导入eclipse不用细说,结果如下图所示。

破土动工:

【注】爬虫是什么,不需要重复。如果是通过的url爬没有权限的网页很简单,直接用Jsoup可以完成。但是当我们爬上一些需要登录的网站时,如果我们仍然直接访问它们url的话会重新返回到登录首页,所以我们就要进行模拟登录,至于什么是模拟登录,就是将账号密码验证码post记住网站的服务器cookie访问登录后的其他页面(其实这是先行知识,之所以要提一口,是因为一开始我很困惑)。

首先分析模拟登录过程,先打开火狐浏览器,打开学校教务系统登录界面。然后按下F12按正常方式打开抓包界面登录。(~~不小心暴露了学校……)

成功登录后,分析登录过程http状态,你会发现其中一个状态码是302POST方法和200的GET然后打开这两个提交数据,可以看到下图。

要求数据界面的地址在红框中。

继而分析提交数据,在抓包分析的时候会发现其中有很多的参数,其实就是在登录的过程中浏览器会自动将你手动输入的账号密码和验证码以及其自动生成的作为唯一身份验证的cookie作为参数POST到网站服务器进行身份验证并登录。cookie和session的区别以及POST和GET参数如下图所示:

用代码登录网站时,需要提交这些表单数据作为参数,但虽然参数很多,但真正需要的参数只需要标记的四个参数:

学号:txtUserName密码:TextBox2验证码:txtSecretCode_VIEWSTATE,其实这个参数和同学的官网是一样的。至于参数在哪里,在网页上登录html源码中:

嗯,所有需要提交的参数都已经理解,所以可以实现模拟登录。然而,现在的问题是,登录页面时需要提交验证码。哪里可以获得验证码?如下图所示:

所以每次提交信息都需要get网页获取验证码,因为自动识别验证码比较麻烦,所以在本项目中将验证码下载到本地,然后手动输入验证码登录。

【高能:我将在下一篇博文中详细解释验证码的自动识别】

成功登录后即可使用cookie访问想要访问的页面。

整体框架大致熟悉,然后直接上源码:package com.yxs.Link; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.cookie.*; import java.util.*; import org.jsoup.*; import org.jsoup.nodes.*; import org.jsoup.select.*; import java.io.*; /** *<p>Tile:LoginTest.java<p> *<p>Description:获取cookie验证码模拟登录教务系统<p> * @author YXS<p> * @data2018年6月3日 */ public class LoginTMSystem public static String getHTML() String cookie1 = ""; String html = "null"; String txtSecretCode = ""; System.out.println("请输入学号:"); String txtUserName = new Scanner(System.in).next().trim();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;System.out.println("请输入密码:"); String TextBox2 = new Scanner(System.in).next().trim();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;String RadioButtonList1 = ""; String __VIEWSTATE = ""; url String loginURL = "http://jwxt.hfnu.edu.cn/(arezfqaeu12awkft0yuoe1qg)/default2.aspx"; //教务管理系统首页url String indexURL = "http://jwxt.hfnu.edu.cn/(arezfqaeu12awkft0yuoe1qg)/xs_ ** in.aspx"; url String dataURL = "http://jwxt.hfnu.edu.cn/(arezfqaeu12awkft0yuoe1qg)/xskbcx.aspx"; String checkCodeURL = "http://jwxt.hfnu.edu.cn/(arezfqaeu12awkft0yuoe1qg)/CheckCode.aspx"; HttpClient httpClient = new HttpClient();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; //先访问验证码页面,获取验证码 GetMethod getMethod1 = new GetMethod(checkCodeURL); try HttpClient接收Cookie httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); httpClient.executeMethod(getMethod1); Cookie Cookie[] cookies1 = httpClient.getState().getCookies();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;StringBuffer tmpcookies1 = new StringBuffer();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;for(Cookie c1 : cookies1) tmpcookies1.append(c1.toString() ";"); System.out.println("访问页面cookies : " c1.toString();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cookie1 = tmpcookies1.toString();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; //cookie1 = c1.toString();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;} //验证码保存路径 File storeFile = new File("D:java爬虫jar包verifycodevc.gif"); InputStream is = getMethod1.getResponseBodyAsStream();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;FileOutputStream fos = new FileOutputStream(storeFile); byte[] b = new byte[1024]int n; while((n = is.read(b)) != -1) fos.write(b,0,n); is.close();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;fos.close();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 该处代码是用于验证码自动识别 txtSecretCode = I ** gePreProcess.getAllOrc("D:java爬虫jar包verifycodevc.gif"); catch(Exception e) e.printStackTrace(); System.out.println("请输入验证码:"); String txtSecretCode = new Scanner(System.in).next().trim(); System.out.println(txtSecretCode); System.out.println("测试使用cookie1:"+cookie1); //模拟登录,按实际服务器端要求选用Post 或 Get请求方式 PostMethod postMethod = new PostMethod(loginURL); //设置相同的cookie postMethod.setRequestHeader("cookie",cookie1); //设置登录时需要的信息,用户名和密码 NameValuePair[] data = { new NameValuePair("__VIEWSTATE",__VIEWSTATE), new NameValuePair("Button1",""), new NameValuePair("hidPdrs",""), new NameValuePair("hidsc",""), new NameValuePair("lbLanguage",""), new NameValuePair("RadioButtonList1",RadioButtonList1), new NameValuePair("TextBox2",TextBox2), new NameValuePair("txtSecretCode",txtSecretCode), new NameValuePair("txtUserName",txtUserName) }; postMethod.setRequestBody(data); try { int statusCode = httpClient.executeMethod(postMethod); //html = postMethod.getResponseBodyAsString(); System.out.println(statusCode); //重定向 if(statusCode == 302) { System.out.println("模拟登录成功!"); //设置HttpClient接收Cookie,用与浏览器一样的策略 httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); //获取登录后的Cookie Cookie[] cookies = httpClient.getState().getCookies(); StringBuffer tmpcookies = new StringBuffer(); for(Cookie c : cookies) { tmpcookies.append(c.toString()+";"); System.out.println("登录页面cookies : "+c.toString()); } //System.out.println("-------------------------------Infor ** tionFrame------------------------------"); //进行登录后的操作 //访问主页面 GetMethod getMethod2 = new GetMethod(indexURL+"?xh="+txtUserName); //每次访问需授权的网址时带上前面的cookie作为通行证 getMethod2.setRequestHeader("cookie",tmpcookies.toString()); httpClient.executeMethod(getMethod2); //访问课程表页面 GetMethod getMethod3 = new GetMethod(dataURL+"?xh="+txtUserName+"&xm=&gnmkdm="); //每次访问需授权的网址时带上前面的cookie作为通行证 getMethod3.setRequestHeader("referer",indexURL+"?xh="+txtUserName); getMethod3.setRequestHeader("cookie",tmpcookies.toString()); httpClient.executeMethod(getMethod3); html = getMethod3.getResponseBodyAsString(); /*//访问主页面 GetMethod getMethod = new GetMethod(indexURL+"?xh="+txtUserName); //每次访问需授权的网址时带上前面的cookie作为通行证 getMethod.setRequestHeader("cookie",tmpcookies.toString()); httpClient.executeMethod(getMethod); html = getMethod.getResponseBodyAsString();*/ }else { System.out.println("登录失败"); } }catch(Exception e) { e.printStackTrace(); } return html; } public static void ** in(String[] args) { Document doc = Jsoup.parse(LoginTMSystem.getHTML()); //System.out.println(doc); /*Element link1 = doc.select("span#Label3").first(); String text1 = link1.text(); Element link2 = doc.select("span#xhxm").first(); String text2 = link2.text(); System.out.println(text1+text2);*/ Elements link1 = doc.select("span#Label5"); Elements link2 = doc.select("span#Label6"); Elements link3 = doc.select("span#Label7"); Elements link4 = doc.select("span#Label8"); Elements link5 = doc.select("span#Label9"); String text1 = link1.text(); String text2 = link2.text(); String text3 = link3.text(); String text4 = link4.text(); String text5 = link5.text(); System.out.println("-------------------------------个人信息------------------------------"); System.out.println(text1); System.out.println(text2); System.out.println(text3); System.out.println(text4); System.out.println(text5); System.out.println("-------------------------------课程信息------------------------------"); Elements tds1 = doc.select("td[rowspan=2]"); for(int i=0;i<tds1.size();i++) { String td = tds1.get(i).text().replace(Jsoup.parse(" ").text(), " "); System.out.println(td); } Elements tds2 = doc.select("td[rowspan=3]"); for(int i=0;i<tds2.size();i++) { String td = tds2.get(i).text().replace(Jsoup.parse(" ").text(), " "); System.out.println(td); } System.exit(0); }

结果显示:

源码的话,就自己解读吧,理解核心方法的话,就很容易理解代码的意思,而且其中也添加了许多注释,如果还有不懂得话,可以在评论里提问或者不嫌弃我菜的话加我qq1420755674进行交流。【注1】cookie和session的缠绵悱恻

当你在浏览网站的时候,WEB 服务器会先送一些资料放在你的计算机上,Cookie会帮你在网站上所打的文字或是一些选择,都记录下来。当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie 资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内容给你。 Cookie 的使用很普遍,许多有提供个人化服务的网站,都是利用Cookie来辨认使用者,以方便送出使用者量身定做的内容,像是 Web 接口的免费 e ** il 网站,都要用到 Cookie。

具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。

同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。

cookie机制。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。

cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式

session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为sessionid),如果已包含则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的session id,sessionid的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个sessionid的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个cookie的名字都是类似于SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把sessionid传递回服务器。

经常被使用的一种技术叫做URL重写,就是把sessionid直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把sessionid传递回服务器。比如:

<form name="testform"action="/xxx">

<input type="hidden"name="jsessionid"value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-1457887 ** ">

<input type="text">

</form>

实际上这种技术可以简单的用对action应用URL重写来代替。

cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE操作,考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

【注2】POST和GET的双宿双飞从安全性看get<post,get提交数据会在浏览器的地址栏显示从提交的内容大小来看get<post,get提交的数据不能大于2k,而post提交的数据上理论不受限制,实际编程中建议不要大于 ** k从请求响应速度来看get>post,get要求服务器立即处理请求,而post请求可能形成一个队列请求。记其中的三两坑

【坑1】

在前期停滞了两天,就是关于那个登录界面的验证码和你访问验证码网页获得的验证码是否一致的问题,我当时一直搞不懂如何保持相同,也搜了很多但是都是没有说到点子上或者很多教程都是没有在该点上侧重注意的,所以这一点算是坑死我。下图是当时搜的一些讨论。后来还是经过学长的指点才算是醍醐灌顶。先简单说说我当时的思考思路:由于我在POST参数时,需要将账号密码验证码和提交,这时是POST到loginURL,但是我有验证码的前提是要GET下checkCodeURL下载验证码,可是我怎么保证两者的验证码就是同一验证码呢?所以我想先GETcheckCodeURL获取验证码,同时获取该网页的cookie,然后再用相同的cookie作为参数POST到loginURL,这样的意思就是保证让服务器知道我两次访问的是同一用户,以保证两个验证码保持一致,但是结果,当然毫无起色!!!!!那么问题出在那了?

看了这么多图片,你应该能够发现每个URL中都有和普通URL不同之处,如下图,URL中有一长串字符编码,【重点】其实这个就是对每个网页的一个唯一标识码,就是当不同次访问网页是服务器都会生成一个标识码,只有当这个标识码保持一致时,服务器才会认定两个验证码是保持一致的。

【坑2】

其实解决完坑1后,你就会发现可以成功登录了,但是这时当你想POST课程表页面时,会出错!WTF ?!

这时也是有三个参数要提交,和前面的类似,但是关键关键之处:一定要加该句,用于告诉该POST的网页你从哪里来。

扫码免费用

源码支持二开

申请免费使用

在线咨询