-
Notifications
You must be signed in to change notification settings - Fork 0
/
price-comparison-scraper.py
109 lines (91 loc) · 3.49 KB
/
price-comparison-scraper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import requests
from bs4 import BeautifulSoup
import pandas as pd
from typing import List, Dict
import concurrent.futures
import urllib3
urllib3.disable_warnings()
class PriceTracker:
def __init__(self, sites_config: Dict[str, Dict]):
"""
Inicializa o rastreador de preços com configurações dos sites.
:param sites_config: Dicionário com configurações de cada site
"""
self.sites_config = sites_config
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def _fetch_price(self, site_name: str, url: str) -> Dict:
"""
Busca o preço de um produto em um site específico.
:param site_name: Nome do site
:param url: URL do produto
:return: Dicionário com informações do produto
"""
try:
response = requests.get(url, headers=self.headers, verify=False, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
selector = self.sites_config[site_name]['price_selector']
price_element = soup.select_one(selector)
if price_element:
price_text = price_element.get_text().strip()
price = float(price_text.replace('R$', '').replace('.', '').replace(',', '.'))
return {
'site': site_name,
'price': price,
'url': url
}
except Exception as e:
print(f"Erro ao buscar preço de {site_name}: {e}")
return None
def track_product_prices(self, product_urls: List[str]) -> pd.DataFrame:
"""
Rastreia preços de um produto em múltiplos sites.
:param product_urls: Lista de URLs do mesmo produto em diferentes sites
:return: DataFrame com preços ordenados
"""
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = []
for url in product_urls:
site_name = next(
(site for site, config in self.sites_config.items()
if config['domain'] in url),
'Unknown'
)
futures.append(
executor.submit(self._fetch_price, site_name, url)
)
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result:
results.append(result)
df = pd.DataFrame(results)
return df.sort_values('price') if not df.empty else pd.DataFrame()
# Exemplo de configuração de sites
sites_config = {
'Magazine Luiza': {
'domain': 'magazineluiza.com.br',
'price_selector': '.price__current'
},
'Amazon': {
'domain': 'amazon.com.br',
'price_selector': '.a-price-whole'
},
'Americanas': {
'domain': 'americanas.com.br',
'price_selector': '[data-testid="price-value"]'
}
}
def main():
tracker = PriceTracker(sites_config)
# URLs de um mesmo produto
product_urls = [
'https://www.magazineluiza.com.br/exemplo-produto',
'https://www.amazon.com.br/exemplo-produto',
'https://www.americanas.com.br/exemplo-produto'
]
result = tracker.track_product_prices(product_urls)
print(result)
if __name__ == "__main__":
main()