Flutter scrape Google Shopping - flutter

I am trying to get a product price by searching for the product in Google Shopping with a given title and storeName.
I found this question on SO, which explains how you would do it with Python. How can something like this be done with Flutter?
Also like I said, is there any way to select the store?
I couldn't find anything on this. Any help is appreciated. Let me know if you need any more info!
I tried it like this:
Future<void> getGoogleShoppingResult() async {
const String requestUrl =
'https://www.google.com/search?q=minecraft+toys&tbm=shop';
final response = await http.get(Uri.parse(requestUrl));
dom.Document document = parser.parse(response.body);
final elements = document.querySelectorAll(
'div.sh-np__product-title.translate-content',
);
print(elements.first.innerHtml);
}
With this I tried to get the title of the first found product. But this never finds any product, even though I copied the selector from Google Shopping.

You should use these packages:
webview_flutter
http
html
And wait till JavaScript has been loaded.
This tutorial can help:
https://www.youtube.com/watch?v=EHk66k___EY
The code snippet:
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:html/dom.dart' as dom;
class WebViewPageExample extends StatefulWidget {
const WebViewPageExample({Key? key}) : super(key: key);
#override
State<WebViewPageExample> createState() => _WebViewPageExampleState();
}
class _WebViewPageExampleState extends State<WebViewPageExample> {
late WebViewController _controller;
#override
Widget build(BuildContext context) {
return WebView(
onWebViewCreated: _onWebViewCreated,
javascriptMode: JavascriptMode.unrestricted,
initialUrl: "https://www.google.com/search?q=minecraft+toys&tbm=shop",
onPageFinished: _onPageFinished,
);
}
void _onWebViewCreated(WebViewController controller) {
_controller = controller;
}
Future _onPageFinished(String url) async {
final html = await _controller.runJavascriptReturningResult(
"new XMLSerializer().serializeToString(document);");
final div = dom.Document.html(html)
.querySelectorAll('div.sh-np__product-title.translate-content');
log('Count: ${div.length}');
}
}

Related

Downloading a PDF fron a link, inside a website made using Flutter Webview,

I have made a flutter/dart webiew app using a existing website, it works well for browsing and opening other page links, except PDF file links, for example a payslip. This link is different for every user. I have used the flutter webview example code to build this, using three classes home_Page.dart, my_webview.dart, main.dart.
I am new to dart and flutter, what can I do to make this link work. I have seen loads of examples online, tried but not sure where to use what code.
Code for my_webview
// ignore_for_file: import_of_legacy_library_into_null_safe
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/platform_interface.dart';
import 'package:webview_flutter/webview_flutter.dart';
class MyWebView extends StatelessWidget {
final String title;
final String selectedUrl;
final Completer<WebViewController> _controller = Completer<WebViewController>();
MyWebView({
required this.title,
required this.selectedUrl,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//title: Text(title),
),
body: WebView(
initialUrl: selectedUrl,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
));
}
}
I have tried using different examples, giving permission for external read and write in android.xml.
using flutter code listener made sense, but I can't make it work either.
tried pasting the code below in different classes, see in different examples
StreamSubscription<String> _onWebViewUrlChanged;
_onWebViewUrlChanged =
FlutterWebviewPlugin().onUrlChanged.listen((String url) {
if (url.contains('.pdf')) {
launchURL(url);
}
});
any ideas

Post and get data using flutter webview

I'm having a problem with Flutter. More precisely, since it is not a language that I have a command of, I did something by looking at the videos. Of course, old videos etc. I've been in trouble.
First of all, I will write what I want to do and what I failed to achieve. I am pulling my website into application with webview. There is no problem here. Then I added onesignal. This also works flawlessly. But I want to get the id called playerid that onesignal defines for each device and post it to my php page. I tried many plugins for this, but I could not succeed. Then I sent it as a cookie, it still didn't work. I realized that I can send data as get in the latest webview link, but the fact that I can't pull the variable I created here also infuriated me. I'm adding the codes below and asking for help from an expert friend. If there is, you can suggest an easy way to POST and GET. Thanks everyone in advance.
In the code below, I can't get the variable that I defined as userid and printed in the link section. In the simplest way, if I do this, it can work for now.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart';
void main() async {
runApp(PnlbaseApp());
}
class PnlbaseApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PNLBASE APP',
home: PnlbaseAppPage(),
);
}
}
class PnlbaseAppPage extends StatefulWidget {
PnlbaseAppPage({Key? key}) : super(key: key);
#override
_PnlbaseAppPageState createState() => _PnlbaseAppPageState();
}
class _PnlbaseAppPageState extends State<PnlbaseAppPage> {
#override
void initState() {
super.initState();
OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);
OneSignal.shared.setAppId("APP-ID");
OneSignal.shared.promptUserForPushNotificationPermission().then((accepted) {
print("Accepted permission: $accepted");
});
OneSignal.shared.getDeviceState().then((deviceState) {
print("OneSignal: device state: ${deviceState?.jsonRepresentation()}");
var userid;
userid = deviceState?.userId;
print(userid);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
top: true,
child: WebView(
initialUrl: "https://app.pnlbase.com/login?playerid",
javascriptMode: JavascriptMode.unrestricted,
),
),
);
}
}

About PDF file opening and downloading flutter web in web hosting

I am trying to generate Pdf in flutter with pdf package in flutter Web.
while doing so I found a solution for flutter web with this code ..
Uint8List bytes = await pdf.save() ;
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
this code worked fine in local host but is not running in web hosting . please help
My first answer was deleted, so I'll repost it.
To download files look this one:
https://stackoverflow.com/a/60614367/18386517.
If you want to just open PDFs files inside your app try the pdfx package. Here is an example:
import 'dart:async';
import 'dart:typed_data';
import 'package:pdfx/pdfx.dart';
import 'package:flutter/material.dart';
class PdfLabPage extends StatefulWidget {
final String name;
final FutureOr<Uint8List> content;
const PdfLabPage({Key? key, required this.name, required this.content}) : super(key: key);
#override
State<PdfLabPage> createState() => _PdfLabPageState();
}
class _PdfLabPageState extends State<PdfLabPage> {
late PdfControllerPinch pdfController;
#override
void initState() {
pdfController = PdfControllerPinch(
document: PdfDocument.openData(widget.content)
);
super.initState();
}
#override
void dispose() {
pdfController.dispose();
super.dispose();
}
Widget pdfView() => PdfViewPinch(
controller: pdfController ,
onDocumentLoaded: (msg) {print(msg.toString());},
onDocumentError: (error) { print(error.toString());}
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.name),
),
body:
Center(
child: pdfView(),
),
);
}
}
I got the content of the PDF file from the web using:
var url = "..."
final file = await http.get(Uri.parse(url));
final content = file.bodyBytes;
But you can load from assets (Android, Ios, MacOs, Web):
final document = await PdfDocument.openAsset('assets/sample.pdf')
From file (Android, Ios, MacOs):
final document = await PdfDocument.openFile('path/to/file/on/device')
From data (Android, Ios, MacOs, Web):
final document = await PdfDocument.openData((FutureOr<Uint8List>) data)

How to get a flutter webview to show only a part of the webpage

I need to interact with a part of a web application through my flutter app so I chose to use flutter webviews but i dont need the hole page i only need to show a div, changing the style of all the DOM elements except the one i want would probably work but that is not a good solution, is there any way to only render the chosen Dom element in a flutter webview Widget?
class Activity extends StatefulWidget {
const Activity({Key? key}) : super(key: key);
#override
_ActivityState createState() => _ActivityState();
}
class _ActivityState extends State<Activity> {
late WebViewController _controller;
#override
Widget build(BuildContext context) {
return WebView(
initialUrl: "https://h5p.org/",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller = controller;
},
onPageStarted: (url) {
_controller.evaluateJavascript("/*select all the elements except X*/");
print("somestuff");
},
);
}
}

Flutter, WebView - rebuild with custom HTML

I want to show some generated HTML in a WebView in my Flutter App.
The StatefulWidget which contains the WebView can change certain properties upon which the WebView would have to rebuild.
TL;DR: How to supply custom HTML without initialUrl?
Up to now I used the initialUrl propety of the WebView constructor to supply an URI with my HTML directly embedded:
WebView(
initialUrl: Uri.dataFromString(myHtml, mimeType: 'text/html').toString(),
)
Now I realized, I must rebuild the WebView with different values when some states get set. (Namely a dropdown above the WebView). As the name tells, this URI is just initial.
So my question is: How can I update the HTML in the WebView? Is there maybe some way to reset the internal state of the WebView?
I guess webview's api doesn't allow to do that, but you can use a workaround: just save the HTML to temp file and provide an URI to WebView using initialUrl. Here's the example:
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Uri uri;
Future<void> _showHtml(String html) async {
final tempDir = await getTemporaryDirectory();
final path = join(tempDir.path, 'page.html');
final tempFile = File(path);
tempFile.writeAsStringSync(html);
setState(() {
uri = Uri(scheme: 'file', path: path);
});
}
#override
void initState() {
super.initState();
_showHtml('<html>Test</html>');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: uri != null ? WebView(
initialUrl: uri.toString(),
) : Container()
),
);
}
}
You can also use onWebViewCreated callback to save webview's controller and use the controller later to load other using loadUrl method.