bharatgraph / scrapers /ed_scraper.py
abinazebinoy's picture
fix(NEW-A3 part1): replace em-dashes/smart-quotes in 56+ Python files -- CI requires pure ASCII source
8a0fba4
Raw
History Blame Contribute Delete
3.67 kB
import os
from datetime import datetime
from bs4 import BeautifulSoup
from scrapers.base_scraper import BaseScraper
from loguru import logger
class EDScraper(BaseScraper):
BASE_URL = "https://enforcementdirectorate.gov.in"
PRESS_URL = "https://enforcementdirectorate.gov.in/press-release"
STATS_URL = "https://enforcementdirectorate.gov.in/statistics"
def __init__(self):
super().__init__(name="ed", delay=2.0)
self.session.headers.update({
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
),
})
def fetch_press_releases(self, limit: int = 20,
save: bool = True) -> list:
logger.info("[ED] Fetching press releases...")
html = self.get_html(self.PRESS_URL)
releases = []
if html:
releases = self._parse_press_releases(html, limit)
if not releases:
logger.warning("[ED] Could not fetch live data -- using sample")
releases = self._get_sample_releases()
if save and releases:
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
filepath = f"data/samples/ed_releases_{ts}.json"
self.save_json(releases, filepath)
logger.success(f"[ED] Saved {len(releases)} releases")
return releases
def _parse_press_releases(self, html: str, limit: int) -> list:
soup = BeautifulSoup(html, "lxml")
releases = []
for link in soup.find_all("a", href=True):
title = link.get_text(strip=True)
href = link.get("href", "")
if len(title) < 15:
continue
if not any(k in title.lower() for k in
["attach","arrest","pmla","fema","crore","case"]):
continue
full_url = (href if href.startswith("http")
else self.BASE_URL + href)
releases.append({
"title": title,
"url": full_url,
"source": "Enforcement Directorate",
"source_url": self.BASE_URL,
"scraped_at": datetime.now().isoformat(),
"entity_type": "ed_press_release",
})
if len(releases) >= limit:
break
logger.info(f"[ED] Parsed {len(releases)} press releases")
return releases
def _get_sample_releases(self) -> list:
return [
{
"title": (
"ED Attaches Properties Worth Rs 10021.46 Crore "
"in PACL Money Laundering Case"
),
"date": "2026-02-18",
"amount_crore":10021.46,
"case_type": "PMLA",
"accused": "PACL India Limited",
"url": (
"https://enforcementdirectorate.gov.in/"
"press-release/2026/feb/pacl"
),
"source": "Enforcement Directorate (sample)",
"source_url": self.BASE_URL,
"scraped_at": datetime.now().isoformat(),
"entity_type": "ed_press_release",
},
]
if __name__ == "__main__":
print("=" * 55)
print("BharatGraph - ED Scraper")
print("=" * 55)
scraper = EDScraper()
releases = scraper.fetch_press_releases(save=True)
print(f"\n Records: {len(releases)}")
if releases:
print(f" Example: {releases[0]['title'][:60]}")
print("\nDone!")