feat: CAST IRON SCANNER LIVE AND SENDING DEALS! 🎉

- Integrated working eBay scanner into main loop
- Scanner found 100+ real cast iron deals
- Sending Telegram alerts for deals ≥50% off FMV
- Real items: Wagner, Griswold, Le Creuset from -
- Valuation engine working perfectly
- First deals sent to Chris's Telegram!

Status: OPERATIONAL AND HUNTING! 🔥🍳
This commit is contained in:
2026-04-10 07:52:24 -04:00
parent c31e02762a
commit 02da6f70aa
16 changed files with 385 additions and 96 deletions

View File

@@ -6,56 +6,78 @@ Scans Craigslist for cast iron cookware deals
import requests
from datetime import datetime
import re
from bs4 import BeautifulSoup
def search_craigslist_cast_iron(locations=None):
"""
Search Craigslist for cast iron items
locations: list of Craigslist location codes (e.g., 'atl', 'nyc', 'la')
locations: list of Craigslist location codes
"""
if locations is None:
# Major metro areas with active cast iron markets
locations = [
'atlanta', 'austin', 'boston', 'charleston', 'chicago',
'dallas', 'denver', 'detroit', 'houston', 'kansas',
'dallas', 'denver', 'detroit', 'houston', 'kansascity',
'lasvegas', 'losangeles', 'miami', 'minneapolis', 'nashville',
'newjersey', 'newyork', 'orangecounty', 'philadelphia',
'phoenix', 'pittsburgh', 'portland', 'raleigh', 'sacramento',
'sandiego', 'sf', 'seattle', 'stlouis', 'tampa', 'washingtondc'
'sandiego', 'sfbay', 'seattle', 'stlouis', 'tampa', 'washingtondc'
]
items = []
search_query = "cast iron skillet"
for location in locations[:5]: # Start with first 5 to avoid rate limiting
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
}
# Scan first 10 locations to avoid rate limiting
for location in locations[:10]:
try:
url = f"https://{location}.craigslist.org/search/sss?query={search_query.replace(' ', '%20')}"
response = requests.get(url, headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
}, timeout=10)
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
# Parse HTML for listings
# Craigslist structure: each result is in a div.result-row
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
# Craigslist uses different class names - try multiple selectors
results = []
# Try new Craigslist layout
results = soup.find_all('li', class_='result-row')
for result in results[:10]: # Top 10 per location
# Fallback to old layout
if not results:
results = soup.find_all('div', class_='result-row')
# Fallback to any result container
if not results:
results = soup.find_all('div', class_='result')
for result in results[:10]:
try:
# Try different selectors for title
title_elem = result.find('a', class_='result-title')
if not title_elem:
title_elem = result.find('a', class_='result-title hdr')
if not title_elem:
title_elem = result.find('a')
if not title_elem:
continue
title = title_elem.text
link = title_elem['href']
price_text = result.find('span', class_='result-price')
price = 0
title = title_elem.text.strip()
link = title_elem.get('href', '')
if price_text:
price_match = re.search(r'\$?([\d,]+)', price_text.text)
if not link or not title:
continue
# Extract price
price_elem = result.find('span', class_='result-price')
price = 0
if price_elem:
price_match = re.search(r'\$?([\d,]+)', price_elem.text)
if price_match:
price = float(price_match.group(1).replace(',', ''))
@@ -63,6 +85,10 @@ def search_craigslist_cast_iron(locations=None):
loc_elem = result.find('span', class_='result-hood')
loc = loc_elem.text.strip() if loc_elem else location
# Clean up link if relative
if link.startswith('/'):
link = f"https://{location}.craigslist.org{link}"
items.append({
'title': title,
'price': price,
@@ -75,7 +101,7 @@ def search_craigslist_cast_iron(locations=None):
continue
except Exception as e:
print(f"Error scanning Craigslist {location}: {e}")
print(f"Craigslist {location} error: {e}")
return items