-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelitiscrape.py
More file actions
134 lines (109 loc) · 5.76 KB
/
Copy pathelitiscrape.py
File metadata and controls
134 lines (109 loc) · 5.76 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import time
import requests
from bs4 import BeautifulSoup
from ftfy import fix_text
import pandas as pd
from tqdm import tqdm
class SingaporeLawScraper:
def __init__(self):
self.base_list_url = "https://www.elitigation.sg/gd/Home/Index"
self.base_case_url = "https://www.elitigation.sg/gd/s/"
def scrape_elitigation_cases(self, start_year, end_year):
all_cases = []
output_file_name = f"elitigation_cases_{start_year}_to_{end_year}.csv"
with tqdm(desc="Scraping cases", unit="case") as pbar:
for year in range(start_year, end_year + 1):
page_num = 1
while True:
list_url = f"{self.base_list_url}?Filter=SUPCT&YearOfDecision={year}&SortBy=Score&CurrentPage={page_num}"
response = requests.get(list_url)
if response.status_code != 200:
break
soup = BeautifulSoup(response.text, 'html.parser')
cards = soup.find_all('div', class_='card col-12')
if not cards:
break
for card in cards:
case_identifier_span = card.find('span', class_='gd-addinfo-text')
if case_identifier_span:
case_identifier = fix_text(case_identifier_span.text.strip().replace(" |", ""))
catchwords_links = card.find_all('a', class_='gd-cw')
catchwords_texts = [
fix_text(link.text.strip().replace("—", "-").replace("[", "").replace("]", ""))
for link in catchwords_links
]
formatted_case_identifier = (
case_identifier.replace(" ", "_")
.replace("[", "")
.replace("]", "")
.replace("(", "")
.replace(")", "")
)
case_url = f"{self.base_case_url}{formatted_case_identifier}"
case_details = self.scrape_case_details(case_url)
if case_details:
all_cases.append({
'CaseIdentifier': case_identifier,
'Catchwords': ", ".join(catchwords_texts) if catchwords_texts else None,
'Year': year,
'URL': case_url,
**case_details
})
pbar.update(1)
pbar.set_postfix_str(f"Year: {year}, Page: {page_num}", refresh=False)
page_num += 1
time.sleep(0.5)
pd.DataFrame(all_cases).to_csv(output_file_name, index=False)
print(f"\nSaved all cases to {output_file_name}")
return output_file_name
def scrape_case_details(self, url):
response = requests.get(url)
if response.status_code != 200:
return None
soup = BeautifulSoup(response.text, 'html.parser')
# paragraph count handling
judgment_divs = soup.find_all('div', class_='Judg-1')
paragraph_count = 0
if judgment_divs:
last_paragraph = fix_text(judgment_divs[-1].text.strip())
if last_paragraph:
first_word = last_paragraph.split()[0] if last_paragraph.split() else ''
paragraph_count = int(first_word) if first_word.isdigit() else 0
# word count calculation
full_text = " ".join(fix_text(div.text) for div in judgment_divs)
word_count = len(full_text.split())
# judge name cleaning
judge_div = soup.find('div', class_='Judg-Author') or soup.find('div', class_='Judg-Sign')
judge_raw = fix_text(judge_div.text.strip()) if judge_div else "Unknown"
judge_cleaned = (
judge_raw.replace("Â", "")
.replace(":", "")
.split("(delivering")[0]
.strip()
)
# counsels
lawyers_divs = soup.find_all('div', class_='Judg-Lawyers')
legal_parties_text = []
if lawyers_divs:
for div in lawyers_divs:
legal_parties_text.append(fix_text(div.text.strip()))
last_lawyer_div = lawyers_divs[-1]
current_element = last_lawyer_div.next_sibling
while current_element:
if hasattr(current_element, 'name') and current_element.name == 'div':
if 'class' in current_element.attrs:
if 'Judg-EOF' in current_element.get('class', []):
break
elif 'txt-body' in current_element.get('class', []):
legal_parties_text.append(fix_text(current_element.text.strip()))
current_element = current_element.next_sibling
legal_parties_cleaned = " ".join(legal_parties_text).replace(";", "").strip()
return {
'WordCount': word_count,
'ParagraphCount': paragraph_count,
'Author': judge_cleaned,
'LegalParties': legal_parties_cleaned if legal_parties_cleaned else "Not found"
}
if __name__ == "__main__":
scraper = SingaporeLawScraper()
scraper.scrape_elitigation_cases(start_year=2020, end_year=2025)