diff --git a/uk_bin_collection/tests/input.json b/uk_bin_collection/tests/input.json
index a032b7b504..c3923c353a 100755
--- a/uk_bin_collection/tests/input.json
+++ b/uk_bin_collection/tests/input.json
@@ -1344,14 +1344,11 @@
"LAD24CD": "E07000121"
},
"LeedsCityCouncil": {
- "house_number": "1",
- "postcode": "LS6 2SE",
"skip_get_url": true,
"uprn": "72506983",
"url": "https://www.leeds.gov.uk/residents/bins-and-recycling/check-your-bin-day",
- "web_driver": "http://selenium:4444",
"wiki_name": "Leeds",
- "wiki_note": "Pass the house number, postcode, and UPRN. This parser requires a Selenium webdriver.",
+ "wiki_note": "Pass the UPRN.",
"LAD24CD": "E08000035"
},
"LeicesterCityCouncil": {
@@ -1420,6 +1417,14 @@
"wiki_note": "Pass the UPRN. You can find it using [FindMyAddress](https://www.findmyaddress.co.uk/search).",
"LAD24CD": "E09000009"
},
+ "LondonBoroughHammersmithandFulham": {
+ "postcode": "W12 0BQ",
+ "url": "https://www.lbhf.gov.uk/",
+ "wiki_command_url_override": "https://www.lbhf.gov.uk/",
+ "wiki_name": "Hammersmith & Fulham",
+ "wiki_note": "Pass only the property postcode",
+ "LAD24CD": "E09000013"
+ },
"LondonBoroughHarrow": {
"uprn": "100021298754",
"url": "https://www.harrow.gov.uk",
diff --git a/uk_bin_collection/uk_bin_collection/councils/BarkingDagenham.py b/uk_bin_collection/uk_bin_collection/councils/BarkingDagenham.py
index 7fe52600c6..b007a1e655 100644
--- a/uk_bin_collection/uk_bin_collection/councils/BarkingDagenham.py
+++ b/uk_bin_collection/uk_bin_collection/councils/BarkingDagenham.py
@@ -47,23 +47,7 @@ def parse_data(self, page: str, **kwargs) -> dict:
# Close popup if it exists
driver.switch_to.active_element.send_keys(Keys.ESCAPE)
- # Handle cookie banner if present
- wait = WebDriverWait(driver, 60)
- try:
- cookie_button = wait.until(
- EC.element_to_be_clickable(
- (
- By.CSS_SELECTOR,
- ".agree-button.eu-cookie-compliance-secondary-button.button.button--small",
- )
- ),
- message="Cookie banner not found",
- )
- cookie_button.click()
- print("Cookie banner clicked.")
- time.sleep(1) # Brief pause to let banner disappear
- except (TimeoutException, NoSuchElementException):
- print("No cookie banner appeared or selector failed.")
+ wait = WebDriverWait(driver, 10)
# Enter postcode
print("Looking for postcode input...")
@@ -84,7 +68,7 @@ def parse_data(self, page: str, **kwargs) -> dict:
EC.element_to_be_clickable((By.ID, "address")),
message="Address dropdown not found",
)
-
+
dropdown = Select(address_select)
found = False
diff --git a/uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py b/uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py
index 30a9bd82f4..d19bddb29b 100644
--- a/uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/BromleyBoroughCouncil.py
@@ -30,7 +30,8 @@ def parse_data(self, page: str, **kwargs) -> dict:
data = {"bins": []}
# Get our initial session running
- driver = create_webdriver(web_driver, headless, None, __name__)
+ user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+ driver = create_webdriver(web_driver, headless, user_agent, __name__)
driver.get(kwargs.get("url"))
wait = WebDriverWait(driver, 30)
diff --git a/uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py b/uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py
index a665024cea..f351faadd8 100644
--- a/uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/CumberlandCouncil.py
@@ -1,3 +1,5 @@
+from datetime import date
+
import requests
from bs4 import BeautifulSoup
@@ -29,64 +31,26 @@ def parse_data(self, page: str, **kwargs) -> dict:
if not content_region:
return bindata
- # Parse the text content to extract collection dates
- text_content = content_region.get_text()
- lines = [line.strip() for line in text_content.split('\n') if line.strip()]
-
- current_month = None
- current_year = None
- i = 0
-
- # Determine the year range from the page header
- year_2026 = "2026" in text_content
-
- while i < len(lines):
- line = lines[i]
-
- # Check if this is a month name
- if line in ["January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"]:
- current_month = line
- # Determine year based on month and context
- if year_2026:
- current_year = "2026" if line in ["January", "February"] else "2025"
- else:
- current_year = str(datetime.now().year)
- i += 1
- continue
-
- # Check if this is a day number (1-31)
- if line.isdigit() and 1 <= int(line) <= 31 and current_month:
- day = line
- # Next line should be the bin type
- if i + 1 < len(lines):
- bin_type = lines[i + 1]
-
- # Skip the subtype line (Refuse/Recycling detail)
- if i + 2 < len(lines) and lines[i + 2] in ["Refuse", "Recycling"]:
- i += 1
-
- # Parse the date
- try:
- date_str = f"{day} {current_month} {current_year}"
- collection_date = datetime.strptime(date_str, "%d %B %Y")
-
- dict_data = {
- "type": bin_type,
- "collectionDate": collection_date.strftime(date_format),
- }
- bindata["bins"].append(dict_data)
- except ValueError:
- pass
-
- i += 2
- continue
-
- i += 1
+ lis = content_region.find_all("li")
+ for li in lis:
+ collection_day = li.find("span", class_="waste-collection__day--day")
+ collection_type_str = li.find("span", class_="waste-collection__day--type")
+
+ collection_date = collection_day.find("time")["datetime"]
+
+ collection_type = collection_type_str.text
+
+ collection_date = datetime.strptime(collection_date, "%Y-%m-%d")
+
+ dict_data = {
+ "type": collection_type.strip(),
+ "collectionDate": collection_date.strftime(date_format),
+ }
+ bindata["bins"].append(dict_data)
# Sort by collection date
bindata["bins"].sort(
- key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
+ key=lambda x: datetime.strptime(x.get("collectionDate"), date_format)
)
return bindata
diff --git a/uk_bin_collection/uk_bin_collection/councils/EastleighBoroughCouncil.py b/uk_bin_collection/uk_bin_collection/councils/EastleighBoroughCouncil.py
index 71ea375fb7..b81c94bfc0 100644
--- a/uk_bin_collection/uk_bin_collection/councils/EastleighBoroughCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/EastleighBoroughCouncil.py
@@ -23,7 +23,8 @@ def parse_data(self, page: str, **kwargs) -> dict:
headless = kwargs.get("headless")
web_driver = kwargs.get("web_driver")
url = f"https://www.eastleigh.gov.uk/waste-bins-and-recycling/collection-dates/your-waste-bin-and-recycling-collections?uprn={uprn}"
- driver = create_webdriver(web_driver, headless, None, __name__)
+ user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+ driver = create_webdriver(web_driver, headless, user_agent, __name__)
driver.get(url)
wait = WebDriverWait(driver, 10)
diff --git a/uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py b/uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py
index bc25c2f29f..84cc8155a7 100644
--- a/uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/HarboroughDistrictCouncil.py
@@ -23,15 +23,18 @@ def parse_data(self, page: str, **kwargs) -> dict:
check_uprn(user_uprn)
bindata = {"bins": []}
- URI = "https://harborough.fccenvironment.co.uk/detail-address"
+ URI1 = "https://harborough.fccenvironment.co.uk/"
+ URI2 = "https://harborough.fccenvironment.co.uk/detail-address"
+
+ # Make the GET request
+ session = requests.session()
+ response = session.get(
+ URI1, verify=False
+ ) # Initialize session state (cookies) required by URI2
+ response.raise_for_status() # Validate session initialization
- headers = {
- "Content-Type": "application/json",
- "User-Agent": "Mozilla/5.0",
- "Referer": "https://harborough.fccenvironment.co.uk/",
- }
params = {"Uprn": user_uprn}
- response = requests.post(URI, headers=headers, data=params, verify=False)
+ response = session.post(URI2, data=params, verify=False)
# Check for service errors
if response.status_code == 502:
@@ -40,20 +43,20 @@ def parse_data(self, page: str, **kwargs) -> dict:
f"This is a temporary issue with the council's waste collection system. "
f"Please try again later."
)
-
+
response.raise_for_status()
soup = BeautifulSoup(response.content, features="html.parser")
bin_collection = soup.find(
"div", {"class": "blocks block-your-next-scheduled-bin-collection-days"}
)
-
+
if bin_collection is None:
raise ValueError(
f"Could not find bin collection data for UPRN {user_uprn}. "
"The council website may have changed or the UPRN may be invalid."
)
-
+
lis = bin_collection.find_all("li")
for li in lis:
try:
diff --git a/uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py b/uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py
index fe0daa49e8..8237b18bee 100644
--- a/uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/LeedsCityCouncil.py
@@ -1,14 +1,5 @@
-import urllib.request
from datetime import datetime
-import pandas as pd
-from bs4 import BeautifulSoup
-from selenium.webdriver.common.by import By
-from selenium.webdriver.common.keys import Keys
-from selenium.webdriver.support import expected_conditions as EC
-from selenium.webdriver.support.ui import Select
-from selenium.webdriver.support.wait import WebDriverWait
-
from uk_bin_collection.uk_bin_collection.common import *
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
@@ -22,92 +13,50 @@ class CouncilClass(AbstractGetBinDataClass):
def parse_data(self, page: str, **kwargs) -> dict:
driver = None
+ data = {"bins": []}
try:
- """
- Parse council provided CSVs to get the latest bin collections for address
- """
-
user_uprn = kwargs.get("uprn")
- user_postcode = kwargs.get("postcode")
- web_driver = kwargs.get("web_driver")
- headless = kwargs.get("headless")
check_uprn(user_uprn)
- check_postcode(user_postcode)
- # Create Selenium webdriver
- page = f"https://www.leeds.gov.uk/residents/bins-and-recycling/check-your-bin-day"
-
- driver = create_webdriver(web_driver, headless, None, __name__)
- driver.get(page)
-
- wait = WebDriverWait(driver, 60)
- postcode_box = wait.until(
- EC.element_to_be_clickable(
- (
- By.XPATH,
- "//input[@id='postcode']",
- )
- )
- )
- postcode_box.send_keys(user_postcode)
- postcode_btn_present = wait.until(
- EC.presence_of_element_located(
- (
- By.XPATH,
- "//button[contains(text(),'Look up Address')]",
- )
- )
- )
- postcode_btn_present.send_keys(Keys.RETURN)
+ URI = "https://api.leeds.gov.uk/public/waste/v1/BinsDays"
- dropdown_present = wait.until(
- EC.presence_of_element_located(
- (
- By.XPATH,
- '//option[contains(text(),"Select an address")]/parent::select',
- )
- )
- )
+ startDate = datetime.now()
+ endDate = (startDate + timedelta(weeks=8)).strftime("%Y-%m-%d")
+ startDate = startDate.strftime("%Y-%m-%d")
+
+ params = {
+ "uprn": user_uprn,
+ "startDate": startDate,
+ "endDate": endDate,
+ }
+
+ headers = {
+ "ocp-apim-subscription-key": "ad8dd80444fe45fcad376f82cf9a5ab4",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
+ }
- dropdown_select = Select(dropdown_present)
+ # print(params)
- dropdown_select.select_by_value(user_uprn)
+ # Send GET request
+ response = requests.get(URI, params=params, headers=headers)
- result = wait.until(
- EC.presence_of_element_located(
- (
- By.XPATH,
- "//div[@class='lcc-bins']",
- )
+ print(response.content)
+
+ collections = json.loads(response.content)
+
+ for collection in collections:
+
+ collectionDate = datetime.strptime(
+ collection["date"], "%Y-%m-%dT%H:%M:%S"
)
- )
-
- data = {"bins": []} # dictionary for data
- soup = BeautifulSoup(
- result.get_attribute("innerHTML"), features="html.parser"
- )
-
- bin_sections = soup.select("div.lcc-bin:not(.lcc-bin--calendar)")
-
- for section in bin_sections:
- h3_text = section.find("h3").get_text(strip=True)
- bin_type = h3_text.split()[0] # e.g., 'Black', 'Brown', 'Green'
-
- # Find all
elements inside the bin days list
- date_elements = section.select("div.lcc-bin__days li")
- for li in date_elements:
- raw_date = li.get_text(strip=True)
- if not raw_date:
- continue
- try:
- formatted_date = datetime.strptime(
- raw_date, "%A %d %b %Y"
- ).strftime(date_format)
- data["bins"].append(
- {"type": bin_type, "collectionDate": formatted_date}
- )
- except ValueError:
- print(f"Skipping unparseable date: {raw_date}")
+
+ data["bins"].append(
+ {
+ "type": collection["type"],
+ "collectionDate": collectionDate.strftime(date_format),
+ }
+ )
+
except Exception as e:
# Here you can log the exception if needed
print(f"An error occurred: {e}")
diff --git a/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHammersmithandFulham.py b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHammersmithandFulham.py
new file mode 100644
index 0000000000..0080b057ea
--- /dev/null
+++ b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHammersmithandFulham.py
@@ -0,0 +1,60 @@
+from datetime import datetime
+
+import requests
+from bs4 import BeautifulSoup
+
+from uk_bin_collection.uk_bin_collection.common import *
+from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
+
+
+# import the wonderful Beautiful Soup and the URL grabber
+class CouncilClass(AbstractGetBinDataClass):
+ """
+ Concrete classes have to implement all abstract operations of the
+ base class. They can also override some operations with a default
+ implementation.
+ """
+
+ def parse_data(self, page: str, **kwargs) -> dict:
+
+ user_postcode = kwargs.get("postcode")
+ check_postcode(user_postcode)
+ bindata = {"bins": []}
+
+ user_postcode = user_postcode.strip().replace(" ", "")
+
+ URI = f"https://www.lbhf.gov.uk/bin-recycling-day/results?postcode={user_postcode}"
+ UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
+ session = requests.session()
+ session.headers.update({"User-Agent": UA})
+ # Make the GET request
+ response = session.get(URI)
+ response.raise_for_status()
+
+ soup = BeautifulSoup(response.content, features="html.parser")
+ results = soup.find("div", {"class": "nearest-search-results"})
+ ol = results.find("ol")
+ bin_collections = ol.find_all("a")
+
+ today = datetime.now().strftime("%A")
+
+ for bin_collection in bin_collections:
+ collection_day = bin_collection.get_text().split(" - ")[0]
+ collection_type = bin_collection.get_text().split(" - ")[1]
+
+ if days_of_week.get(collection_day) == days_of_week.get(today):
+ collection_day = datetime.now().strftime(date_format)
+ else:
+ collection_day = get_next_day_of_week(collection_day)
+
+ dict_data = {
+ "type": collection_type,
+ "collectionDate": collection_day,
+ }
+ bindata["bins"].append(dict_data)
+
+ bindata["bins"].sort(
+ key=lambda x: datetime.strptime(x.get("collectionDate"), "%d/%m/%Y")
+ )
+
+ return bindata
diff --git a/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHavering.py b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHavering.py
index e0daae44b2..97cb2d50ab 100644
--- a/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHavering.py
+++ b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughHavering.py
@@ -21,9 +21,9 @@ def parse_data(self, page: str, **kwargs) -> dict:
check_uprn(user_uprn)
bindata = {"bins": []}
- URI = "https://lbhapiprod.azure-api.net"
+ URI = "https://api-prd.havering.gov.uk"
endpoint = f"{URI}/whitespace/GetCollectionByUprnAndDate"
- subscription_key = "2ea6a75f9ea34bb58d299a0c9f84e72e"
+ subscription_key = "545bcf53c9094dfd980dd9da72b0514d"
# Get today's date in 'YYYY-MM-DD' format
collection_date = datetime.now().strftime("%Y-%m-%d")
diff --git a/uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py
index 73252fc63b..b938c26d88 100644
--- a/uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py
+++ b/uk_bin_collection/uk_bin_collection/councils/LondonBoroughRedbridge.py
@@ -61,7 +61,7 @@ def parse_data(self, page: str, **kwargs) -> dict:
address_link.send_keys(Keys.ENTER)
- address_results = wait.until(
+ wait.until(
EC.presence_of_element_located(
(By.CLASS_NAME, "your-collection-schedule-container")
)
diff --git a/uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py b/uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py
index aca3a58b3a..1797f9c4dd 100644
--- a/uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/MidSuffolkDistrictCouncil.py
@@ -118,6 +118,8 @@ def parse_data(self, page: str, **kwargs) -> dict:
# Collect text in p excluding the strong tag
date_str = (p_tag.get_text()).split(":")[1]
+ if " - " in date_str:
+ date_str = date_str.split(" - ")[1]
collection_date = datetime.strptime(date_str, "%a %d %b %Y")
diff --git a/uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py b/uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py
index 7290687f5d..3855acd1be 100644
--- a/uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/NorthEastDerbyshireDistrictCouncil.py
@@ -28,6 +28,7 @@ def parse_data(self, page: str, **kwargs) -> dict:
data = {"bins": []}
user_uprn = kwargs.get("uprn")
+ user_uprn = str(user_uprn).zfill(12)
user_postcode = kwargs.get("postcode")
web_driver = kwargs.get("web_driver")
headless = kwargs.get("headless")
diff --git a/uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py b/uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py
index ad6ff46e35..b5e3498892 100644
--- a/uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/PowysCouncil.py
@@ -92,7 +92,7 @@ def parse_data(self, page: str, **kwargs) -> dict:
# General rubbish collection dates
general_rubbish_section = soup.find(
- "h3", string="General Rubbish / Wheelie bin"
+ "div", class_="bdl-card bdl-card--refuse"
)
general_rubbish_dates = [
li.text for li in general_rubbish_section.find_next("ul").find_all("li")
@@ -102,13 +102,14 @@ def parse_data(self, page: str, **kwargs) -> dict:
dict_data = {
"type": "General Rubbish / Wheelie bin",
"collectionDate": datetime.strptime(
- remove_ordinal_indicator_from_date_string(date), "%d %B %Y"
+ remove_ordinal_indicator_from_date_string(date.split(" (")[0]),
+ "%A %d %B %Y",
).strftime(date_format),
}
data["bins"].append(dict_data)
# Recycling and food waste collection dates
- recycling_section = soup.find("h3", string="Recycling and Food Waste")
+ recycling_section = soup.find("div", class_="bdl-card bdl-card--recycling")
recycling_dates = [
li.text for li in recycling_section.find_next("ul").find_all("li")
]
@@ -117,13 +118,14 @@ def parse_data(self, page: str, **kwargs) -> dict:
dict_data = {
"type": "Recycling and Food Waste",
"collectionDate": datetime.strptime(
- remove_ordinal_indicator_from_date_string(date), "%d %B %Y"
+ remove_ordinal_indicator_from_date_string(date.split(" (")[0]),
+ "%A %d %B %Y",
).strftime(date_format),
}
data["bins"].append(dict_data)
# Garden waste collection dates
- garden_waste_section = soup.find("h3", string="Garden Waste")
+ garden_waste_section = soup.find("div", class_="bdl-card bdl-card--garden")
garden_waste_dates = [
li.text for li in garden_waste_section.find_next("ul").find_all("li")
]
@@ -132,7 +134,10 @@ def parse_data(self, page: str, **kwargs) -> dict:
dict_data = {
"type": "Garden Waste",
"collectionDate": datetime.strptime(
- remove_ordinal_indicator_from_date_string(date), "%d %B %Y"
+ remove_ordinal_indicator_from_date_string(
+ date.split(" (")[0]
+ ),
+ "%A %d %B %Y",
).strftime(date_format),
}
data["bins"].append(dict_data)
diff --git a/uk_bin_collection/uk_bin_collection/councils/RedcarandClevelandCouncil.py b/uk_bin_collection/uk_bin_collection/councils/RedcarandClevelandCouncil.py
index 8639306680..d2271ff790 100644
--- a/uk_bin_collection/uk_bin_collection/councils/RedcarandClevelandCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/RedcarandClevelandCouncil.py
@@ -43,11 +43,11 @@ def parse_data(self, page: str, **kwargs) -> dict:
for item in addresses
if item.get("name", "").startswith(user_paon)
),
- None,
+ addresses[1]["place_id"] if addresses[1] else None,
)
# print(addresses)
- # print(place_id)
+ # print(f"PlaceID - {place_id}")
URI = (
f"https://api.eu.recollect.net/api/places/{place_id}/services/50006/events"
diff --git a/uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py b/uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py
index 24770ca1b8..87b10b0818 100644
--- a/uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py
+++ b/uk_bin_collection/uk_bin_collection/councils/WakefieldCityCouncil.py
@@ -16,9 +16,10 @@ def parse_data(self, page: str, **kwargs) -> dict:
try:
# Create Selenium webdriver
headless = kwargs.get("headless")
- driver = create_webdriver(
- kwargs.get("web_driver"), headless, None, __name__
- )
+ web_driver = kwargs.get("web_driver")
+
+ user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+ driver = create_webdriver(web_driver, headless, user_agent, __name__)
driver.get(kwargs.get("url"))
# This URL format also works:
@@ -38,7 +39,9 @@ def parse_data(self, page: str, **kwargs) -> dict:
"div", {"class": "c-content-section_body"}
).find_all(
"div",
- class_=lambda x: x and "tablet:l-col-fb-4" in x and "u-mt-10" in x
+ class_=lambda x: x
+ and "tablet:l-col-fb-4" in x
+ and "u-mt-10" in x,
)
for row in rows:
diff --git a/wiki/Councils.md b/wiki/Councils.md
index bb87a7345d..ba7a0577f4 100644
--- a/wiki/Councils.md
+++ b/wiki/Councils.md
@@ -76,14 +76,12 @@ This document is still a work in progress, don't worry if your council isn't lis
- [Chorley](#chorley)
- [Colchester](#colchester)
- [Conwy](#conwy)
-- [Copeland](#copeland)
- [Cornwall](#cornwall)
- [Cotswold](#cotswold)
- [Coventry](#coventry)
- [Crawley](#crawley)
- [Croydon](#croydon)
- [Cumberland](#cumberland)
-- [Cumberland](#cumberland)
- [Dacorum](#dacorum)
- [Darlington Borough Council](#darlington-borough-council)
- [Dartford](#dartford)
@@ -111,6 +109,7 @@ This document is still a work in progress, don't worry if your council isn't lis
- [East Staffordshire](#east-staffordshire)
- [East Suffolk](#east-suffolk)
- [Eastleigh](#eastleigh)
+- [Eden District (Westmorland and Furness)](#eden-district-(westmorland-and-furness))
- [City of Edinburgh](#city-of-edinburgh)
- [Elmbridge](#elmbridge)
- [Enfield](#enfield)
@@ -132,6 +131,7 @@ This document is still a work in progress, don't worry if your council isn't lis
- [Gedling](#gedling)
- [Glasgow City](#glasgow-city)
- [Gloucester](#gloucester)
+- [Gosport Borough Council](#gosport-borough-council)
- [Google Calendar (Public)](#google-calendar-(public))
- [Gravesham](#gravesham)
- [Great Yarmouth](#great-yarmouth)
@@ -171,7 +171,9 @@ This document is still a work in progress, don't worry if your council isn't lis
- [City of Lincoln](#city-of-lincoln)
- [Lisburn and Castlereagh](#lisburn-and-castlereagh)
- [Liverpool](#liverpool)
+- [Camden](#camden)
- [Ealing](#ealing)
+- [Hammersmith & Fulham](#hammersmith-&-fulham)
- [Harrow](#harrow)
- [Havering](#havering)
- [Hounslow](#hounslow)
@@ -628,13 +630,14 @@ Note: You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/searc
### Bexley
```commandline
-python collect_data.py BexleyCouncil https://waste.bexley.gov.uk/waste -s -u XXXXXXXX
+python collect_data.py BexleyCouncil https://waste.bexley.gov.uk/waste -s -u XXXXXXXX -w http://HOST:PORT/
```
Additional parameters:
- `-s` - skip get URL
- `-u` - UPRN
+- `-w` - remote Selenium web driver URL (required for Home Assistant)
-Note: Provide your UPRN. Use [FindMyAddress](https://www.findmyaddress.co.uk/search) to locate it.
+Note: Provide your UPRN. Use [FindMyAddress](https://www.findmyaddress.co.uk/search) to locate it. This parser requires a Selenium webdriver.
---
@@ -1156,17 +1159,6 @@ Note: Use [FindMyAddress](https://www.findmyaddress.co.uk/search) to find your U
---
-### Copeland
-```commandline
-python collect_data.py CopelandBoroughCouncil https://www.copeland.gov.uk -u XXXXXXXX
-```
-Additional parameters:
-- `-u` - UPRN
-
-Note: *****This has now been replaced by Cumberland Council****
-
----
-
### Cornwall
```commandline
python collect_data.py CornwallCouncil https://www.cornwall.gov.uk/my-area/ -s -u XXXXXXXX
@@ -1229,18 +1221,6 @@ Note: Pass the house number and postcode in their respective parameters. This pa
---
-### Cumberland
-```commandline
-python collect_data.py CumberlandAllerdaleCouncil https://www.allerdale.gov.uk -p "XXXX XXX" -n XX
-```
-Additional parameters:
-- `-p` - postcode
-- `-n` - house number
-
-Note: Pass the house number and postcode in their respective parameters.
-
----
-
### Cumberland
```commandline
python collect_data.py CumberlandCouncil https://www.cumberland.gov.uk/bins-recycling-and-street-cleaning/waste-collections/bin-collection-schedule -u XXXXXXXX
@@ -1579,6 +1559,17 @@ Note: Pass the UPRN. You can find it using [FindMyAddress](https://www.findmyadd
---
+### Eden District (Westmorland and Furness)
+```commandline
+python collect_data.py EdenDistrictCouncil https://my.eden.gov.uk/myeden.aspx -u XXXXXXXX
+```
+Additional parameters:
+- `-u` - UPRN
+
+Note: For Eden area addresses within Westmorland and Furness. Provide your UPRN. You can find your UPRN using [FindMyAddress](https://www.findmyaddress.co.uk/search). Note: This returns collection days (e.g., 'Wednesday') rather than specific dates.
+
+---
+
### City of Edinburgh
```commandline
python collect_data.py EdinburghCityCouncil https://www.edinburgh.gov.uk -s -p "XXXX XXX" -n XX
@@ -1838,6 +1829,18 @@ Note: Pass the house number, postcode, and UPRN in their respective parameters.
---
+### Gosport Borough Council
+```commandline
+python collect_data.py GosportBoroughCouncil https://www.gosport.gov.uk/refuserecyclingdays -s -p "XXXX XXX"
+```
+Additional parameters:
+- `-s` - skip get URL
+- `-p` - postcode
+
+Note: Pass the postcode parameter. This parser uses the Supatrak API.
+
+---
+
### Google Calendar (Public)
```commandline
python collect_data.py GooglePublicCalendarCouncil https://calendar.google.com/calendar/ical/0d775884b4db6a7bae5204f06dae113c1a36e505b25991ebc27c6bd42edf5b5e%40group.calendar.google.com/public/basic.ics
@@ -2230,16 +2233,13 @@ Note: Pass the house number and postcode in their respective parameters.
### Leeds
```commandline
-python collect_data.py LeedsCityCouncil https://www.leeds.gov.uk/residents/bins-and-recycling/check-your-bin-day -s -u XXXXXXXX -p "XXXX XXX" -n XX -w http://HOST:PORT/
+python collect_data.py LeedsCityCouncil https://www.leeds.gov.uk/residents/bins-and-recycling/check-your-bin-day -s -u XXXXXXXX
```
Additional parameters:
- `-s` - skip get URL
- `-u` - UPRN
-- `-p` - postcode
-- `-n` - house number
-- `-w` - remote Selenium web driver URL (required for Home Assistant)
-Note: Pass the house number, postcode, and UPRN. This parser requires a Selenium webdriver.
+Note: Pass the UPRN.
---
@@ -2314,6 +2314,19 @@ Note: You will need to use [FindMyAddress](https://www.findmyaddress.co.uk/searc
---
+### Camden
+```commandline
+python collect_data.py LondonBoroughCamdenCouncil https://environmentservices.camden.gov.uk/property -s -u XXXXXXXX -p "XXXX XXX"
+```
+Additional parameters:
+- `-s` - skip get URL
+- `-u` - UPRN
+- `-p` - postcode
+
+Note: Pass the property ID as UPRN. Find your property at https://www.camden.gov.uk/check-collection-day then use the property ID from the URL (e.g., https://environmentservices.camden.gov.uk/property/5063139).
+
+---
+
### Ealing
```commandline
python collect_data.py LondonBoroughEaling https://www.ealing.gov.uk/site/custom_scripts/WasteCollectionWS/home/FindCollection -s -u XXXXXXXX
@@ -2326,6 +2339,17 @@ Note: Pass the UPRN. You can find it using [FindMyAddress](https://www.findmyadd
---
+### Hammersmith & Fulham
+```commandline
+python collect_data.py LondonBoroughHammersmithandFulham https://www.lbhf.gov.uk/ -p "XXXX XXX"
+```
+Additional parameters:
+- `-p` - postcode
+
+Note: Pass only the property postcode
+
+---
+
### Harrow
```commandline
python collect_data.py LondonBoroughHarrow https://www.harrow.gov.uk -u XXXXXXXX
@@ -3468,7 +3492,7 @@ Note: Follow the instructions [here](https://www.southlanarkshire.gov.uk/info/20
### South Norfolk
```commandline
-python collect_data.py SouthNorfolkCouncil https://www.southnorfolkandbroadland.gov.uk/rubbish-recycling/south-norfolk-bin-collection-day-finder -s -u XXXXXXXX
+python collect_data.py SouthNorfolkCouncil https://area.southnorfolkandbroadland.gov.uk/FindAddress -s -u XXXXXXXX
```
Additional parameters:
- `-s` - skip get URL
@@ -4257,12 +4281,13 @@ Note: Provide your UPRN. You can find it using [FindMyAddress](https://www.findm
### Wirral
```commandline
-python collect_data.py WirralCouncil https://www.wirral.gov.uk -u XXXXXXXX
+python collect_data.py WirralCouncil https://www.wirral.gov.uk -p "XXXX XXX" -w http://HOST:PORT/
```
Additional parameters:
-- `-u` - UPRN
+- `-p` - postcode
+- `-w` - remote Selenium web driver URL (required for Home Assistant)
-Note: In the `uprn` field, enter your street name and suburb separated by a comma (e.g., 'Vernon Avenue,Seacombe').
+Note: Pass your postcode and house number.
---