chatgpt로 simple flutter code 만들기(15) - Dynamic content loading을 사용하는 사이트 대응
만들고 있는 '즐겨찾기' 앱으로 외부에서 Sharing기능으로 홈페이지 url을 전달할 때, 잘 안되는 경우가 있습니다.
대표적인 예시가 바로 네이버 카페입니다.
예를 들어서 다음과 같은 title을 가지는 카페 페이지가 있습니다.
[초저렴/프리미엄] 갤럭시S9플러스 라벤더 64기가 10만 판매해요! : 네이버 카페
그런데 저의 앱에서 공유받는 url을 플러터의 http.get(uri)를 사용해서 html을 읽어오게 되면
네이버 카페
라고 읽어오게 됩니다.
원인은 네이버 카페 웹페이지는 자바스크립트가 동적으로 컨텐츠를 로딩하지만 플러터의 http 패키지는 정적으로만 불러올 수 있기 때문이라고 합니다.
그래서 해결책을 찾다가 webview_flutter 패키지를 사용하면 동적으로 웹페이지를 읽어올 수 있다는 사실을 알게되었습니다! https://pub.dev/packages/webview_flutter
webview_flutter | Flutter Package A Flutter plugin that provides a WebView widget on Android and iOS. A Flutter plugin that provides a WebView widget on Android and iOS.
1
2
3
4
webview_flutter: ^4.4.4 # New Added for dynamic html parsing
webview_flutter_android: ^3.13.2 # New Added for android dynamic html parsing
webview_flutter_wkwebview: ^3.10.1 # New Added for ios dynamic html parsing
제가 만든 webViewHelper클래스의 loadPageAndGetTitle()함수를 사용하면 동적인 웹페이지의 Title을 불러올 수 있습니다.
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
class WebViewHelper {
late final WebViewController _controller;
bool _isControllerInitialized = false;
Future initController() async {
// #docregion platform_features
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const {},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
final WebViewController controller =
WebViewController.fromPlatformCreationParams(params);
// #enddocregion platform_features
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..loadRequest(Uri.parse('about:blank'));
_controller = controller;
_isControllerInitialized = true;
}
Future loadPage(Uri url) async {
if (!_isControllerInitialized) {
await initController();
}
await _controller.loadRequest(url);
// Wait for page to finish loading
await Future.delayed(const Duration(seconds: 1)); // Adjust delay as needed
}
Future loadPageAndGetTitle(Uri url) async {
await loadPage(url);
// Get the page title
String title = await _controller.runJavaScriptReturningResult('document.title') as String;
printDebug('Page title: $title');
return title;
}
}
저는 Refresh(새로고침) 버튼을 누르면 동적 웹사이트의 title을 다시 읽어서 제 UI에 반영할 수 있도록 했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
IconButton(
icon: Icon(Icons.refresh),
onPressed: () async {
// Add your refresh logic here
Uri uri = Uri.parse(siteUrlController.text);
final webViewHelper = WebViewHelper();
String pageTitle = await webViewHelper.loadPageAndGetTitle(uri);
// Update the siteNameController's text with the fetched page title
siteNameController.text = pageTitle;
// snack bar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Page Title: $pageTitle \n URL: $uri',
style: const TextStyle(color: Colors.white)),
backgroundColor: Colors.black,
),
);
},
),
[영상]


