如何在 flutter 中获取 html 内容形式的 flutterWebViewPlugin ( webview )

how to get html content form flutterWebViewPlugin ( webview ) in flutter

我的问题很简单。如何从 webview 中的加载页面获取 html 数据。数据采用 JSON 格式。由于某种原因,我无法在此处对任何获取​​请求使用 post 请求,因此我只需要使用 webview 获取数据。如何实现?

flutterWebViewPlugin.onUrlChanged.listen((String url) {
      if (url.contains('/recon?')) {
        print('printing url : $url');
        // need to get data ( html content ) on this url
        flutterWebViewPlugin.close();
        Navigator.of(context).pop(url);
      }
    });
});


WebviewScaffold(
                userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0",
                url: myurl,               
              )

您可以使用我的插件 flutter_inappwebview,这是一个 Flutter 插件,允许您添加内联 WebView 或打开应用内浏览器 window,并且有很多事件、方法和控制 WebView 的选项。

要获取 HTML 数据,只需在 onLoadStop 事件中使用 var html = await controller.evaluateJavascript(source: "window.document.getElementsByTagName('html')[0].outerHTML;");

这是使用您的 userAgent:

的示例
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  InAppWebViewController webView;
  String myurl = "https://github.com/flutter";

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('InAppWebView Example'),
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                  child: InAppWebView(
                    initialUrl: myurl,
                    initialHeaders: {},
                    initialOptions: InAppWebViewGroupOptions(
                      crossPlatform: InAppWebViewOptions(
                        debuggingEnabled: true,
                        userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0"
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) async {
                      if (url.contains('/recon?')) {
                        // if JavaScript is enabled, you can use
                        var html = await controller.evaluateJavascript(
                            source: "window.document.getElementsByTagName('html')[0].outerHTML;");

                        log(html);
                      }
                    },
                  ))
            ])),
      ),
    );
  }
}

只需将 myurl 变量设置为您的 url。

通过window.document.getElementsByTagName('html')[0].outerHTML;你会得到所有的HTML字符串。相反,如果您只需要正文,则可以使用 window.document.body.innerText;.

进行更改

您可以使用官方 webview 库执行此操作:

WebView(
  initialUrl: model.luxtrustUrl,
  onWebViewCreated: (controller) {
    _controller = controller;
  },
  javascriptMode: JavascriptMode.unrestricted,
  gestureNavigationEnabled: true,
  onPageFinished: (_) {
    readJS();
    model.hideProgress();
  },
)

void readJS() async{
    String html = await _controller.evaluateJavascript("window.document.getElementsByTagName('html')[0].outerHTML;");    
    print(html);
}

我的答案是从 url 而不是 html content 获取令牌,因为我无法正确提取它并出现错误

[VERBOSE-2:ui_dart_state.cc(166)] Unhandled Exception: FormatException: Unexpected character (at character 1)
<html><head></head><body><pre style="word-wrap: break-word; white-space: pr...
^

所以一开始对我有用的是以下解决方案:

WebView(
          userAgent: "random",
          initialUrl: mainUrl,
          onWebViewCreated: (controller) {
            _controller = controller;
            print(_controller.currentUrl());
          },
          javascriptMode: JavascriptMode.unrestricted,
          gestureNavigationEnabled: true,
          onPageFinished: (_) {
            _controller.currentUrl().then(
              (url) {
                if (url.contains("recon?")) {
                  var token = url.split('recon?')[1];
                  _prefs.setString('token', token);
                }
                if (url.contains("dashboard")) {
                  _controller.clearCache();
                  _controller.loadUrl(mainUrl);
                }
              },
            );
          },
        ),

这里我们取 url,根据关键字拆分它,然后存储另一半,即令牌并继续。我能够通过 flutter_webview_pluginflutter_inappwebview 这两种方式来做到这一点,其过程相同,但 URL 只对我有用。提取上下文没有,所以他们没有被标记为答案,而是帮助我理解可能性的赞成票。