这是一个非常常见的需求,通常用于调试、数据分析或实现特定功能,核心思路是利用 WebView 提供的回调接口,在网页加载完成后获取其内容。

(图片来源网络,侵删)
核心方法:WebViewClient 的 onPageFinished 回调
当 WebView 完成加载一个页面后,系统会调用 WebViewClient 的 onPageFinished(WebView view, String url) 方法,我们就是在这个方法里,通过 view 对象来获取当前的 HTML 源码。
最关键的方法是:view.getUrl() 和 view.getPageSource()。
getUrl(): 获取当前 WebView 加载的 URL 地址。getPageSource(): 获取当前页面的完整 HTML 源码,这是实现目标的核心方法。
完整代码示例
下面是一个完整的、可以直接运行的 Activity 示例,它展示如何加载一个网页,并在加载完成后将其源码打印到 Logcat 中,同时显示在一个 TextView 里。
布局文件 (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<WebView
android:id="@+id/my_webview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:id="@+id/source_code_text"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#f0f0f0"
android:text="网页源码将显示在这里..."
android:textIsSelectable="true" />
</LinearLayout>
Java 代码 (MainActivity.java)
package com.example.webviewdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "WebViewSourceCode";
private WebView webView;
private TextView sourceCodeTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
webView = findViewById(R.id.my_webview);
sourceCodeTextView = findViewById(R.id.source_code_text);
// 1. 启用 JavaScript (如果网页需要)
webView.getSettings().setJavaScriptEnabled(true);
// 2. 设置 WebViewClient,这是获取源码的关键
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// 网页加载完成后,此方法会被调用
Log.d(TAG, "页面加载完成,URL: " + url);
// 3. 获取网页源码
String htmlSource = view.getPageSource();
// 4. 将源码打印到 Logcat
Log.d(TAG, "网页源码:\n" + htmlSource);
// 5. 将源码显示在 TextView 中 (注意:源码可能很长,建议只显示部分或用其他方式查看)
// 为了避免UI卡顿,可以考虑使用异步任务或只显示前N个字符
sourceCodeTextView.setText(htmlSource.length() > 5000 ?
htmlSource.substring(0, 5000) + "\n\n... (源码过长,已截断)" :
htmlSource);
}
});
// 6. 加载一个网页
// 加载本地 HTML 文件
// webView.loadUrl("file:///android_asset/my_page.html");
// 加载网络 URL
webView.loadUrl("https://www.baidu.com");
}
// 7. 处理返回键,让 WebView 能够返回上一页而不是退出应用
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
AndroidManifest.xml 配置
别忘了在 AndroidManifest.xml 中添加网络权限和声明 WebView 所需的 usesCleartextTraffic(如果加载的是 HTTP 网站或某些 HTTPS 网站)。

(图片来源网络,侵删)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.webviewdemo">
<!-- 添加网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true" <!-- 允许 HTTP 请求,对某些 HTTPS 网站也必要 -->
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.WebViewDemo">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
关键点解析与注意事项
-
onPageFinished的时机:- 这个方法在页面及其所有资源(如图片、CSS、JS)都加载完毕后才会调用。
- 如果网页有大量异步加载的内容(例如通过 AJAX 动态加载),
onPageFinished只会在初始 HTML 加载完成后触发,此时获取的源码可能不包含这些动态加载的内容,如果需要获取最终渲染后的完整 DOM,情况会更复杂,可能需要与前端 JS 交互。
-
性能考虑:
- 网页源码可能非常巨大(特别是现代网站),直接将其全部加载到内存并显示在
TextView中可能会导致内存问题或 UI 卡顿。 - 建议:在实际应用中,不要直接将整个源码显示在 UI 上,可以:
- 只打印到 Logcat 进行调试。
- 只截取源码的前几百个字符进行预览。
- 将源码保存到文件中。
- 使用
StringBuilder或流式处理来分析源码,而不是一次性全部读入。
- 网页源码可能非常巨大(特别是现代网站),直接将其全部加载到内存并显示在
-
JavaScript 与动态内容:
- 如上所述,
getPageSource()获取的是服务器返回的原始 HTML,而不是浏览器渲染后的 DOM。 - 如果网页内容是通过 JavaScript 动态生成的(使用 React, Vue, Angular 框架),
onPageFinished触发时这些内容可能还未添加到 DOM 中。 - 如何获取动态内容?
- 与 JS 交互,在
onPageFinished中,通过WebView.evaluateJavascript()执行一段 JS 代码,让 JS 将整个document.documentElement.outerHTML(渲染后的完整 HTML) 返回给 Java 代码。// 在 onPageFinished 中添加 webView.evaluateJavascript("(function() { return document.documentElement.outerHTML; })();", value -> { // value 是 JS 返回的结果,是一个 String 类型 Log.d(TAG, "通过 JS 获取的渲染后源码: " + value); // 在这里处理 value }); - 等待,可以设置一个定时器,延迟几秒后再调用
getPageSource(),给 JS 脚本留出执行时间,但这非常不可靠,不推荐。
- 与 JS 交互,在
- 如上所述,
-
HTTPS 与安全:
- 在 Android 9 (API 28) 及以上,默认禁止使用 HTTP,如果你的目标网页是
http://开头的,需要在AndroidManifest.xml的<application>标签中设置android:usesCleartextTraffic="true"。 - 如果是
https://,但网站证书不受信任(例如自签名证书),WebView 可能会加载失败,需要处理onReceivedSslError回调来接受证书。
- 在 Android 9 (API 28) 及以上,默认禁止使用 HTTP,如果你的目标网页是
获取 Android WebView 网页源码的标准流程是:
- 为
WebView设置一个自定义的WebViewClient。 - 重写
onPageFinished(WebView view, String url)方法。 - 在该方法内部,调用
view.getPageSource()获取 HTML 字符串。 - 根据需求处理这个字符串(打印、保存、分析等)。
对于静态网页,这是最直接、最可靠的方法,对于动态网页,则需要结合 JavaScript 交互来获取最终渲染的源码。
