شرح Web Scraping بإستخدام فلاتر والحصول على بيانات المنتاجات من على الانترنت
مجال Web Scraping من اقوى المجالات المطلوبة في السوق وذلك لانها تسهل الكثير من الوقت على مدخل البيانات في معظم المتاجر ولكن ماذا لو قلت لك انك يمكنك ان تقوم بالحصول على معلومات صفحه معينه على سبيل المثال في موقع اماوزن يمكنك الحصول على روابط المنتجات والاسماء والصور دفعه واحده دون المرور على العناصر واحد تلو الاخر وهذه هي ميزة الWeb Scraping وكثير من الاشخاص لا يعرفون عنها ولا يعرفون اهميتها الكبيره ولهذا قررنا عمل مقال حول كيفية عمل Web Scraping في فلاتر بطريقة بسيطه .
بيئة تطوير متكاملة جيدة لتطوير تطبيقات Android الأصلية. بالمقارنة مع IDEs الأخرى مثل eclipse، فإن أداء Android Studio يعد ابطئ قليلا من البرامج الاخرى ولكنه الاقوى. على الهواتف الذكية التي تعمل بنظام Android ، يعمل البرنامج المدمج بشكل رائع. يقوم بإنشاء تطبيقات Android موثوقة وقيمة باستخدام IDE هذا. ومع ذلك ، فهو يقدم فقط تطبيقات Android الأصلية. Android Studio متاح أيضًا لأنظمة Windows و Mac OS X و Linux. ومع ذلك ، يمكننا فقط إنشاء تطبيقات Android أصلية.
المكتبات التي تحتاجها لتنفيذ لعمل web scraping
http: ^0.13.4
html: ^0.15.0
Web Scraping with Flutter
بكل بساطة سوف نقوم بإستدعاء المكتبات السابقه ونرمز لكل مكتبة بإسم ,مثل dom باسم dom وهكذا بعدها قمنا بتحويل التصميم الى StatefulWidget وقمنا بعمل List باسم articles وهي من نوع Article وهذا عباره عن class model قمنا بتصميمه بالاسفل لكي يحفظ القيم بداخله , وعند بدء تشغيل التصميم يتم استدعاء getWebsiteData وهيا عباره عن methode يتم من خلالها الحصول على البيانات بداخلها نقوم بعمل Uri.parse ونضع بداخلها الرابط الخاص الذي نريد البحث في داخله وهنا فتحنا موقع امازون وبحثنا على الماوس وقمنا بنسخ الرابط ووضعه بداخلها .
الان نضع titles ونكتب الكود كما هو موضح وبعدها نفتح الموقع ونضغط right click من على العنصر الذي نريد الحصول عليه وهنا قمنا بعملها على العنوان وبعدها نلاحظ ان العنوان موجود في الجزء المحدد بعدها قم بعملية نسخ الذي تم تحديده وسوف تلاحظ ان الرابط طويل قليلا ولهذا سوف نحتاج فقط نهايه الرابط ونضعها كما هو موضح بالصورة الخاصه بالكود والكود نفسه .
الان في مرحلة الصوره والرابط نلاحظ ان الرابط موجود في href وهذا الجزء الذي يحتوي على الرابط لهذا سوف نستخدم e.attributes['href'] والان نلاحظ ان الرابط ظهر بدون عنوان النطاق الاول لهذا قمنا باضافة العنوان الخاص بالموقع او النطاق بعدها نضع الرابط ليصبح رابط قابل للنقر , والصور كانت نفس الفكرة ولكن لا تحتاج الى ان تقوم بإضافة الرابط في البداية فقط يمكنك اتقباس رابط الموقع فقط كما هو موضح
الان بعد الانتهاء من كل شيئ يمكنك عمل setstate لتغيير العناصر ووضعها بداخل الmodel واخيرا نقوم بعمل list بالاسم لايظهار العناصر وهنا قمنا بعمل for بسيط لمعرفة عدد العناصر وطباعتها فقط يمكنك تخطي هذه المرحلة .
gee.dart
import 'package:flutter/material.dart';
import 'package:html/dom.dart' as dom;
import 'package:http/http.dart' as http;
class CodeLess extends StatefulWidget {
const CodeLess({Key? key}) : super(key: key);
@override
State<CodeLess> createState() => _CodeLessState();
}
class _CodeLessState extends State<CodeLess> {
List<Article> articles =[];
@override
void initState() {
super.initState();
getWebsiteData();
}
Future getWebsiteData () async {
final url = Uri.parse('https://www.amazon.com/s?k=mouse');
final response = await http.get(url);
dom.Document html = dom.Document.html(response.body);
final titles = html
.querySelectorAll('h2 > a > span')
.map((e) => e.innerHtml.trim())
.toList();
// #search > div.s-desktop-width-max.s-desktop-content.s-opposite-dir.sg-row > div.s-matching-dir.sg-col-16-of-20.sg-col.sg-col-8-of-12.sg-col-12-of-16 > div > span:nth-child(4) > div.s-main-slot.s-result-list.s-search-results.sg-row > div:nth-child(14) > div > div > div > div > div > div.sg-col.sg-col-4-of-12.sg-col-8-of-16.sg-col-12-of-20.s-list-col-right > div > div > div.a-section.a-spacing-none.s-padding-right-small.s-title-instructions-style > h2 > a
final urls = html
.querySelectorAll('h2 > a')
.map((e) => 'https://www.amazon.com/${e.attributes['href']}')
.toList();
// #search > div.s-desktop-width-max.s-desktop-content.s-opposite-dir.sg-row > div.s-matching-dir.sg-col-16-of-20.sg-col.sg-col-8-of-12.sg-col-12-of-16 > div > span:nth-child(4) > div.s-main-slot.s-result-list.s-search-results.sg-row > div:nth-child(2) > div > div > div > div > div > div > div > div.sg-col.sg-col-4-of-12.sg-col-4-of-16.sg-col-4-of-20.s-list-col-left > div > div.s-product-image-container.aok-relative.s-image-overlay-grey.s-text-center.s-padding-left-small.s-padding-right-small.s-flex-expand-height.s-media-gallery.s-media-gallery-treatment-T2.s-media-gallery-ready > div > span > a > div > img:nth-child(1)
final images = html
.querySelectorAll('span > a > div > img')
.map((e) => e.attributes['src'])
.toList();
print('count ${titles.length}');
setState(() {
articles = List.generate(titles.length,
(index) => Article(
title: titles[index] ,
url: urls[index],
img: images[index]!,
));
});
for (final title in titles) {
print('this title is $title');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Center(
child: ListView.separated(
physics: const BouncingScrollPhysics(),
separatorBuilder: (context,index)=> const Divider(thickness: 1),
padding: const EdgeInsets.all(15),
itemCount: articles.length,
itemBuilder: (context,index) {
final article = articles[index];
return ListTile(
title: Text(article.title),
subtitle: Text(article.url , maxLines: 2,overflow: TextOverflow.ellipsis),
leading: Image.network(article.img,fit: BoxFit.fitHeight,width: 50,),
);
}),
),
),
);
}
}
class Article {
final String url;
final String title;
final String img;
Article({
required this.url,
required this.title,
required this.img
});
}
يمكنك ايضا استخدام الطريقة الاخرى وهيا عن طريق مكتبة beautiful_soup_dart
import 'package:http/http.dart' as http;
const String urlLink = 'https://mindegy1.blogspot.com/';
class HttpService {
static Future getHttp() async {
try {
final response = await http.get(Uri.parse(urlLink));
if (response.statusCode == 200) {
return response.body;
} else {
print('error');
return 'Error';
}
} catch (e) {
print('error');
return 'Error';
}
}
}
class ScraperService {
static List<TestModel> run(String html) {
List<TestModel> testModels = [];
try {
final soup = BeautifulSoup(html);
final items = soup.findAll('div', class_: 'post-outer');
for (var item in items) {
final title = item.find('div', class_: 'post-info')!.text ?? '';
// final desc = item.find('div', class_: 'Short_content')!.text ?? '';
final link = item.find('a', class_: 'thumb')?.attributes[0] ?? '';
final desc = item.find('a', class_: 'thumb')?.attributes[0] ?? '';
TestModel testModel = TestModel(title: title, body: desc, link: link);
testModels.add(testModel);
}
} catch (e) {
print('error ------ $e');
}
return testModels;
}
}
Future<void> getData () async {
final html = await HttpService.getHttp();
if (html != null) {
List list = ScraperService.run(html);
}
}
مزيد من الاكواد البرمجية :
- شرح كيفية تغيير اللغة بين العربيه والانجليزيه في فلاتر | Language translation in Flutter
- عمل انتقال للصور مع animation بسيط لتحسين عملية نقل البيانات
- كود تكبير الصور في Flutter عند النقر عليها مرتين مع امكانية تتبع الموقع المراد تكبيره
- تصميم صفحة sign in و sign up بإستخدام animation في flutter
- كيفية وضع العناصر فوق بعض في فلاتر بدون مكتبات باستخدام Stack و Positioned
- التعديل على زر الرجوع للخلف في فلاتر | your are sure to exit from app flutter
تعليقات
إرسال تعليق