feat: Implement monitoring of specific HTML elements using BeautifulSoup and add MONITOR_SELECTOR configuration.

This commit is contained in:
Rodrigo Verdiani 2025-12-11 23:29:51 -03:00
parent 8b8f80a93a
commit d5239a9d78
3 changed files with 44 additions and 2 deletions

11
main.py
View File

@ -4,12 +4,14 @@ import schedule
import hashlib import hashlib
import time import time
from datetime import datetime from datetime import datetime
from bs4 import BeautifulSoup
URL_TO_MONITOR = "https://univesp.br/vestibular" URL_TO_MONITOR = "https://univesp.br/vestibular"
HASH_FILE = os.path.join("/data", "last_hash.txt") HASH_FILE = os.path.join("/data", "last_hash.txt")
NTFY_URL = os.getenv("NTFY_URL") NTFY_URL = os.getenv("NTFY_URL")
FLARESOLVERR_URL = os.getenv("FLARESOLVERR_URL") FLARESOLVERR_URL = os.getenv("FLARESOLVERR_URL")
MONITOR_SELECTOR = os.getenv("MONITOR_SELECTOR", "div.conteudo")
def send_notification(message): def send_notification(message):
@ -52,7 +54,14 @@ def get_page_hash(url):
html_content = fs_response['solution']['response'] html_content = fs_response['solution']['response']
print(f"[{datetime.now()}] FlareSolverr request successful.") print(f"[{datetime.now()}] FlareSolverr request successful.")
return hashlib.sha256(html_content.encode('utf-8')).hexdigest() soup = BeautifulSoup(html_content, 'html.parser')
element = soup.select_one(MONITOR_SELECTOR)
if element:
return hashlib.sha256(str(element).encode('utf-8')).hexdigest()
else:
print(f"[{datetime.now()}] ❌ Element '{MONITOR_SELECTOR}' not found in the page.")
return None
else: else:
print(f"[{datetime.now()}] FlareSolverr failed to solve the challenge. Status: {fs_response.get('status')}. Error: {fs_response.get('message')}") print(f"[{datetime.now()}] FlareSolverr failed to solve the challenge. Status: {fs_response.get('status')}. Error: {fs_response.get('message')}")
return None return None

View File

@ -5,5 +5,5 @@ description = "App to verify if the Univesp pages changed"
readme = "README.md" readme = "README.md"
requires-python = ">=3.14" requires-python = ">=3.14"
dependencies = [ dependencies = [
"requests", "schedule" "requests", "schedule", "beautifulsoup4"
] ]

33
uv.lock generated
View File

@ -2,6 +2,19 @@ version = 1
revision = 3 revision = 3
requires-python = ">=3.14" requires-python = ">=3.14"
[[package]]
name = "beautifulsoup4"
version = "4.14.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "soupsieve" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" },
]
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2025.11.12" version = "2025.11.12"
@ -69,17 +82,37 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/20/a7/84c96b61fd13205f2cafbe263cdb2745965974bdf3e0078f121dfeca5f02/schedule-1.2.2-py3-none-any.whl", hash = "sha256:5bef4a2a0183abf44046ae0d164cadcac21b1db011bdd8102e4a0c1e91e06a7d", size = 12220, upload-time = "2024-05-25T18:41:59.121Z" }, { url = "https://files.pythonhosted.org/packages/20/a7/84c96b61fd13205f2cafbe263cdb2745965974bdf3e0078f121dfeca5f02/schedule-1.2.2-py3-none-any.whl", hash = "sha256:5bef4a2a0183abf44046ae0d164cadcac21b1db011bdd8102e4a0c1e91e06a7d", size = 12220, upload-time = "2024-05-25T18:41:59.121Z" },
] ]
[[package]]
name = "soupsieve"
version = "2.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" },
]
[[package]]
name = "typing-extensions"
version = "4.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
]
[[package]] [[package]]
name = "univesper" name = "univesper"
version = "0.1.0" version = "0.1.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "beautifulsoup4" },
{ name = "requests" }, { name = "requests" },
{ name = "schedule" }, { name = "schedule" },
] ]
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "beautifulsoup4" },
{ name = "requests" }, { name = "requests" },
{ name = "schedule" }, { name = "schedule" },
] ]