libraccio_scraper
A Flutter package to scrape book data and cover images from Libraccio.it by ISBN.
It fetches detailed book information and provides easy access to the cover preview.
Features
- Search book details by ISBN.
- Extracts title, author, attributes, and other metadata.
- Downloads and previews the book cover image.
- Simple and easy-to-use API for Flutter apps.
Getting Started
Installation
Add this to your pubspec.yaml:
dependencies:
libraccio_scraper: ^1.0.0
Example
Here's a complete example of a Flutter app that uses the libraccio_scraper package to search for books by ISBN:
import 'package:flutter/material.dart';
import 'package:libraccio_scraper/libraccio_scraper.dart';
void main() {
runApp(const LibraccioApp());
}
class LibraccioApp extends StatelessWidget {
const LibraccioApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Libraccio Scraper Demo',
theme: ThemeData(
primarySwatch: Colors.deepOrange,
brightness: Brightness.light,
),
home: const BookSearchPage(),
);
}
}
class BookSearchPage extends StatefulWidget {
const BookSearchPage({super.key});
@override
State<BookSearchPage> createState() => _BookSearchPageState();
}
class _BookSearchPageState extends State<BookSearchPage> {
final _isbnController = TextEditingController();
final _scraper = LibraccioScraper();
BookData? _bookData;
String? _errorMessage;
bool _loading = false;
void _searchBook() async {
final isbn = _isbnController.text.trim();
if (isbn.isEmpty) {
setState(() {
_errorMessage = 'Inserisci un ISBN valido.';
_bookData = null;
});
return;
}
setState(() {
_loading = true;
_errorMessage = null;
_bookData = null;
});
try {
final bookData = await _scraper.fetchBookData(isbn);
setState(() {
_bookData = bookData;
});
} catch (e) {
setState(() {
_errorMessage = 'Errore durante la ricerca: $e';
});
} finally {
setState(() {
_loading = false;
});
}
}
Widget _buildBookDetails() {
if (_bookData == null) return const SizedBox.shrink();
final rawCover = _bookData!.attributes['coverImageUrl'] ?? '';
final coverUrl = rawCover.startsWith('http')
? rawCover
: 'https://www.libraccio.it$rawCover';
return Card(
elevation: 4,
margin: const EdgeInsets.symmetric(vertical: 20),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (coverUrl.isNotEmpty)
Center(
child: Image.network(
coverUrl,
height: 180,
fit: BoxFit.contain,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const SizedBox(
height: 180,
child: Center(child: CircularProgressIndicator()),
);
},
errorBuilder: (context, error, stackTrace) =>
const Icon(Icons.broken_image, size: 180),
),
),
const SizedBox(height: 12),
Text(
_bookData!.title,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
if (_bookData!.author.isNotEmpty)
Text(
'Autore: ${_bookData!.author}',
style: const TextStyle(fontSize: 18, fontStyle: FontStyle.italic),
),
const SizedBox(height: 12),
const Text(
'Dettagli:',
style: TextStyle(fontSize: 18, decoration: TextDecoration.underline),
),
..._bookData!.attributes.entries.map(
(entry) => Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Text('${entry.key}: ${entry.value}'),
),
),
],
),
),
);
}
@override
void dispose() {
_isbnController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Libraccio Book Search'),
),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
TextField(
controller: _isbnController,
decoration: const InputDecoration(
labelText: 'ISBN',
hintText: 'Inserisci ISBN del libro',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.book),
),
keyboardType: TextInputType.number,
onSubmitted: (_) => _searchBook(),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _loading ? null : _searchBook,
icon: const Icon(Icons.search),
label: const Text('Cerca libro'),
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(48),
),
),
const SizedBox(height: 16),
if (_loading) const CircularProgressIndicator(),
if (_errorMessage != null)
Text(
_errorMessage!,
style: const TextStyle(
color: Colors.red, fontWeight: FontWeight.bold),
),
Expanded(
child: SingleChildScrollView(
child: _buildBookDetails(),
),
),
],
),
),
);
}
}
This example demonstrates:
- How to set up a simple Flutter app using the libraccio_scraper package
- Creating a search interface with an ISBN input field
- Implementing the book search functionality
- Displaying book details including cover image
- Error handling for invalid ISBNs or network issues
- Proper state management during loading states
To use this example:
- Create a new Flutter project
- Add
libraccio_scraperas a dependency in yourpubspec.yaml - Replace the contents of
lib/main.dartwith the code above - Run the app and enter a valid ISBN to search for a book