| Crates.io | lbc-rs |
| lib.rs | lbc-rs |
| version | 0.1.1 |
| created_at | 2025-08-23 14:12:36.855928+00 |
| updated_at | 2025-08-23 14:28:21.447183+00 |
| description | Unofficial client for Leboncoin API, inspired by the Python implementation etienne-hd/lbc |
| homepage | |
| repository | https://github.com/lheintzmann1/lbc-rs |
| max_upload_size | |
| id | 1807542 |
| size | 130,189 |
This project is heavily inspired by the excellent Python implementation: etienne-hd/lbc
use lbc::{Client, City, Category, Sort, AdType};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let location = City::new(
48.85994982004764,
2.33801967847424,
Some(10_000), // 10 km radius
Some("Paris".to_string())
);
let result = client.search()
.text("maison")
.locations(vec![location.into()])
.page(1)
.limit(35)
.sort(Sort::Newest)
.ad_type(AdType::Offer)
.category(Category::Immobilier)
.square(200, 400)
.price(300_000, 700_000)
.execute()
.await?;
for ad in result.ads {
if let (Some(url), Some(subject), price) = (ad.url, ad.subject, ad.price()) {
println!("{} - {} - {:?}", url, subject, price);
}
}
Ok(())
}
lbc-rs is not affiliated with, endorsed by, or in any way associated with Leboncoin or its services. Use at your own risk.
This project is heavily inspired by the excellent Python implementation: etienne-hd/lbc
Add this to your Cargo.toml:
[dependencies]
lbc-rs = "0.1"
tokio = { version = "1.0", features = ["full"] }
use lbc::Client;
// Basic client
let client = Client::new();
// Client with proxy
use lbc::Proxy;
let proxy = Proxy::with_auth(
"proxy.example.com".to_string(),
8080,
"username".to_string(),
"password".to_string()
);
let client = Client::builder()
.proxy(proxy)
.timeout(std::time::Duration::from_secs(60))
.max_retries(10)
.build()?;
let result = client.search()
.text("smartphone")
.category(Category::Electronique)
.execute()
.await?;
println!("Found {} ads", result.ads.len());
use lbc::{City, Region, Department, Sort, AdType, OwnerType};
let paris = City::new(48.8566, 2.3522, Some(5_000), Some("Paris".to_string()));
let idf = Region::IleDeFrance;
let result = client.search()
.text("appartement")
.category(Category::ImmobilierVentes)
.locations(vec![paris.into(), idf.into()])
.sort(Sort::Cheapest)
.ad_type(AdType::Offer)
.owner_type(OwnerType::Private)
.price(200_000, 500_000)
.square(40, 80)
.rooms(2, 4)
.page(1)
.limit(50)
.execute()
.await?;
You can also search using a full Leboncoin URL:
let result = client.search()
.url("https://www.leboncoin.fr/recherche?category=9&text=maison&locations=Paris__48.86023250788424_2.339006433295173_9256&square=100-200&price=500000-1000000".to_string())
.execute()
.await?;
let user = client.get_user("57f99bb6-0446-4b82-b05d-a44ea7bcd2cc").await?;
if let Some(name) = user.name {
println!("User: {}", name);
}
if user.is_pro() {
println!("This is a professional user");
if let Some(pro) = user.pro {
if let Some(store_name) = pro.online_store_name {
println!("Store: {}", store_name);
}
}
}
let ad = client.get_ad("2391847319").await?;
if let Some(subject) = ad.subject {
println!("Title: {}", subject);
}
if let Some(body) = ad.body {
println!("Description: {}", body);
}
if let Some(price) = ad.price() {
println!("Price: €{:.2}", price);
}
// Get the seller's information
if let Ok(Some(user)) = ad.get_user().await {
if let Some(name) = user.name {
println!("Seller: {}", name);
}
}
The library supports three types of location filters:
use lbc::City;
let city = City::new(
48.8566, // latitude
2.3522, // longitude
Some(10_000), // radius in meters (optional)
Some("Paris".to_string()) // city name (optional)
);
use lbc::Region;
let region = Region::IleDeFrance;
let location = region.into(); // Convert to Location
use lbc::Department;
let department = Department::Paris;
let location = department.into(); // Convert to Location
The library provides detailed error types:
use lbc::LbcError;
match client.search().text("test").execute().await {
Ok(result) => {
println!("Found {} ads", result.ads.len());
}
Err(LbcError::DatadomeError(msg)) => {
eprintln!("Blocked by anti-bot protection: {}", msg);
// Consider using a proxy or reducing request frequency
}
Err(LbcError::NotFoundError(msg)) => {
eprintln!("Resource not found: {}", msg);
}
Err(LbcError::RequestError(msg)) => {
eprintln!("Request failed: {}", msg);
}
Err(e) => {
eprintln!("Other error: {}", e);
}
}
If you encounter a 403 Forbidden error, it usually means your requests are being blocked by Datadome. To resolve this:
// Example with delays
use tokio::time::{sleep, Duration};
for page in 1..=5 {
let result = client.search()
.text("voiture")
.page(page)
.execute()
.await?;
// Process results...
// Add delay between requests
sleep(Duration::from_secs(2)).await;
}
The library includes all Leboncoin categories:
use lbc::Category;
// Main categories
Category::ToutesCategories
Category::Vehicules
Category::Immobilier
Category::Electronique
Category::MaisonJardin
Category::Mode
Category::Loisirs
Category::Animaux
Category::Emploi
// Subcategories
Category::VehiculesVoitures
Category::ImmobilierVentes
Category::ElectroniqueOrdinateurs
// ... and many more
This project is licensed under either of
at your option.
This project is heavily inspired by the excellent Python implementation: etienne-hd/lbc
Contributions are welcome! Please feel free to submit a Pull Request.
This is an unofficial client and is not affiliated with Leboncoin. Use responsibly and respect the website's terms of service.