Android WebView填表登陆QQ空间
安卓WebView可以通过JS对网页文档对象进行操作,实现自动填写账号和密码,这样下次就可以免手动输入了,比较方便。这儿使用QQ空间网页版进行模拟登陆
准备工作
基于Android Studio3.0版本
首先需要为软件声明联网权限
1 |
<uses-permission android:name="android.permission.INTERNET"/>
|
因为WebView需要连接网络,所以这个是必须的。
代码开始
创建界面,这儿为了演示,所以把软件分成两个部分,一个是填表输入文本,然后再模拟点击按钮。
首先创建界面,下面贴出代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ghboke.tbdl.MainActivity"
tools:layout_editor_absoluteY="81dp">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<WebView
android:id="@+id/web"
android:layout_width="match_parent"
android:layout_height="300dp">
</WebView>
<EditText
android:id="@+id/editText_us"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="QQ"
android:inputType="textPersonName"
android:text="你的QQ号" />
<EditText
android:id="@+id/editText_pw"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="密码"
android:inputType="textPassword"
android:text="你的密码" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="填表" />
<Button
android:id="@+id/button_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登陆" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
|
在Java代码中绑定他们
1
2
3
4
5
|
mWeb = (WebView) findViewById(R.id.web);
mEditTextUs = (EditText) findViewById(R.id.editText_us);
mEditTextPw = (EditText) findViewById(R.id.editText_pw);
mButton = (Button) findViewById(R.id.button);
mButtonLogin = (Button) findViewById(R.id.button_login);
|
绑定好以后,我们来分析一下这个软件。
首先是WebView浏览器,加载一个网页需要加载JS,而默认是不会加载的,所以我们要给他手动开启。
1 |
mWeb.getSettings().setJavaScriptEnabled(true);
|
这句代码就是开启浏览器对JS的支持了,再来需要跳转到我们登陆的地址
这个地址就是QQ空间手机页面登陆的地址了。
分析JS
要模拟操作网页的对象,首先要了解JS代码。
一个网页他就是一个docment对象,我们可以根据网页上元素的ID确定唯一的一个对象,因为ID是不重复的嘛,那么使用的代码就是
1 |
document.getElementById('p')
|
其中,getElementById意为去网页对象中查找ID为p的那一个元素。那么现在就很明了了,打开谷歌浏览器,审查一下元素。
可以看到,元素代码的ID为,u,如果你对网页元素对象不太理解的话,请稍微看看JS部分即可。同理,找到下面密码框的ID为p,登陆按钮是一个DIV,ID为go。
那么现在我们就可以给安卓的WebView注入JS代码了。
WebView最简单的加载JS方法是loadUrl方法,他不仅仅可以跳转网址,只要内容开头为javascript即可注入JS代码
原生的JS代码进行填表是这样写的
1
2
3
|
document.getElementById('u').value='填表内容';//账号
document.getElementById('p').value='填表内容';//密码
document.getElementById('go').click()//登陆按钮点击
|
在Android 8.0上面直接执行这个JS代码会直接网页白屏,不知道是怎么回事,所以需要先注入,后加载的方式调用,方法如下
1
2
3
4
5
6
7
8
9
10
11
12
|
public void loadjs() {
String jscode = StructureJs(mEditTextUs.getText().toString(), mEditTextPw.getText().toString());
mWeb.loadUrl(jscode);
mWeb.loadUrl("javascript:inputninandpw();");
}
public String StructureJs(String uin, String pw) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("javascript:function inputninandpw(){document.getElementById('u').value='" + uin + "';");
stringBuffer.append("document.getElementById('p').value='" + pw + "';}");
return stringBuffer.toString();
}
|
首先我声明了一个StructureJs函数,传入账号和密码,里面声明了一个StringBuffer ,你可以直接使用String拼接,JS代码是一个名为inputninandpw的函数,名字你可以自己起。接着,如果点击了填表按钮,就执行loadjs函数,这个函数中,把拼接好的JS代码先注入网页,再调用他,这样就可以成功的调用这个函数进行填表了,传入的账号和密码就是账号和密码文本框里面的内容了。
填表成功后,就可以模拟点击登陆按钮了
登陆按钮点击代码事件如下
1
2
3
|
public void clicklogin() {
mWeb.loadUrl("javascript:document.getElementById('go').click();");
}
|
非常简单对吧,点击后就会进行登陆了。
完善代码
如果隐藏了WebView,或者是让软件判断是否登陆成功怎么搞呢?总不能用户登陆成功以后,然后点击一个按钮告诉程序我已经登陆成功了吧,显然是不行的。那么,我们需要为浏览器写一个事件
本登陆页面如果登陆成功了,会跳到https://h5.qzone.qq.com/mqzone/index页面,如果没有登陆成功,是不会跳到这个页面的,所以我们可以在浏览器跳转完毕后进行判断。
为浏览器添加setWebChromeClient事件,本事件是浏览器的一个进度接口,那么只要进度到了100,那就说明网页已经加载完成了,接着我们获取网页的地址判断一下就可以知道用户是否登陆成功了。
1
2
3
4
5
6
7
8
9
10
11
|
mWeb.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
//加载完成
if (progress == 100) {
if (mWeb.getUrl().equals("https://h5.qzone.qq.com/mqzone/index")){
Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_LONG).show();
}
}
}
});
|
很多网页用户登陆了以后,把cookies拿下来就可以做很多事了,那么在这个登陆成功判断后面再添加如下代码,就可以获取到cookies了
1
2
|
CookieManager cookieManager = CookieManager.getInstance();
String CookieStr = cookieManager.getCookie("https://h5.qzone.qq.com/mqzone/index");
|
getCookie传入需要获取cookie的url,这儿传入用户登陆成功的地址即可。