fix: add use tor option
This commit is contained in:
@@ -11,3 +11,11 @@ HEADLESS=false
|
||||
# Use mock data generation instead of denuncias.yml file (true/false)
|
||||
# Set to true to generate realistic test data automatically
|
||||
USE_MOCK_DATA=false
|
||||
|
||||
# Use Tor proxy for anonymity (true/false)
|
||||
# When enabled, routes all browser traffic through Tor
|
||||
USE_TOR=false
|
||||
|
||||
# Tor proxy address (SOCKS5)
|
||||
# Default Tor proxy address, change if using custom Tor configuration
|
||||
TOR_PROXY=socks5://127.0.0.1:9050
|
||||
|
18
README.md
18
README.md
@@ -15,8 +15,16 @@ docker run -e USE_MOCK_DATA=true jorgeteixe/laliga-denuncias:latest
|
||||
|
||||
**¿Por qué?** Este comando genera y envía denuncias falsas automáticamente al sitio oficial de LaLiga. Solo debe usarse en entornos de desarrollo con URLs de prueba.
|
||||
|
||||
### 🛑 NO uses VPN
|
||||
Si vas a hacer denuncias reales, NO uses VPN. LaLiga necesita verificar que eres un denunciante local y serio.
|
||||
### 🔐 Anonimato con Tor (Opcional)
|
||||
El sistema incluye soporte para proxy Tor para mayor privacidad. Para habilitarlo:
|
||||
|
||||
```bash
|
||||
# En tu archivo .env
|
||||
USE_TOR=true
|
||||
TOR_PROXY=socks5://127.0.0.1:9050
|
||||
```
|
||||
|
||||
**Nota**: Asegurate de tener Tor ejecutandose en tu sistema antes de habilitar esta opcion.
|
||||
|
||||
---
|
||||
|
||||
@@ -84,6 +92,12 @@ HEADLESS=false
|
||||
|
||||
# SIEMPRE false para denuncias reales
|
||||
USE_MOCK_DATA=false
|
||||
|
||||
# Usar proxy Tor para anonimato (opcional)
|
||||
USE_TOR=false
|
||||
|
||||
# Direccion del proxy Tor (SOCKS5)
|
||||
TOR_PROXY=socks5://127.0.0.1:9050
|
||||
```
|
||||
|
||||
## 🔧 Como Ejecutar
|
||||
|
18
docker-compose.local.yml
Normal file
18
docker-compose.local.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
tor-proxy:
|
||||
image: dperson/torproxy
|
||||
container_name: tor-sidecar
|
||||
restart: unless-stopped
|
||||
|
||||
laliga-denuncias:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: laliga-denuncias
|
||||
network_mode: "service:tor-proxy"
|
||||
volumes:
|
||||
- ./images:/app/images
|
||||
environment:
|
||||
- USE_MOCK_DATA=true
|
||||
- USE_TOR=true
|
||||
restart: always
|
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
tor-proxy:
|
||||
image: dperson/torproxy
|
||||
container_name: tor-sidecar
|
||||
restart: unless-stopped
|
||||
|
||||
laliga-denuncias:
|
||||
image: jorgeteixe/laliga-denuncias:latest
|
||||
container_name: laliga-denuncias
|
||||
network_mode: "service:tor-proxy"
|
||||
volumes:
|
||||
- ./images:/app/images
|
||||
environment:
|
||||
- USE_MOCK_DATA=true
|
||||
- USE_TOR=true
|
||||
restart: always
|
||||
|
||||
|
134
main.py
134
main.py
@@ -3,6 +3,8 @@ import yaml
|
||||
import random
|
||||
import glob
|
||||
import logging
|
||||
import requests
|
||||
import time
|
||||
from dotenv import load_dotenv
|
||||
from playwright.sync_api import sync_playwright
|
||||
from faker import Faker
|
||||
@@ -22,13 +24,63 @@ def setup_logging():
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
def wait_for_tor_connection(proxy_server):
|
||||
"""Wait for Tor connection to be established using Playwright"""
|
||||
logger.info("Waiting for Tor connection to be established...")
|
||||
|
||||
while True:
|
||||
try:
|
||||
# Use Playwright to check Tor status through the proxy
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(
|
||||
headless=True,
|
||||
proxy={
|
||||
"server": proxy_server
|
||||
}
|
||||
)
|
||||
context = browser.new_context()
|
||||
page = context.new_page()
|
||||
|
||||
try:
|
||||
response = page.goto('https://check.torproject.org/api/ip', timeout=10000)
|
||||
if response and response.status == 200:
|
||||
content = page.content()
|
||||
# Extract JSON from the page content
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', content)
|
||||
if json_match:
|
||||
import json
|
||||
data = json.loads(json_match.group())
|
||||
if data.get("IsTor") is True:
|
||||
logger.info(f"Tor connection established! IP: {data.get('IP', 'Unknown')}")
|
||||
browser.close()
|
||||
return
|
||||
else:
|
||||
logger.info(f"Not using Tor yet. Current IP: {data.get('IP', 'Unknown')}")
|
||||
else:
|
||||
logger.warning("Could not parse Tor check response")
|
||||
else:
|
||||
logger.warning(f"Tor check failed with status: {response.status if response else 'No response'}")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Error during Tor check: {e}")
|
||||
finally:
|
||||
browser.close()
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Error checking Tor status: {e}")
|
||||
|
||||
logger.info("Waiting 10 seconds before next Tor check...")
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
def close_cookie_consent(page):
|
||||
try:
|
||||
logger.info("Waiting for cookie consent dialog to appear...")
|
||||
reject_button = page.locator("#onetrust-reject-all-handler")
|
||||
|
||||
# Wait longer for the cookie banner to appear after page load
|
||||
reject_button.wait_for(state="visible", timeout=15000)
|
||||
reject_button.wait_for(state="visible", timeout=30000)
|
||||
reject_button.click()
|
||||
logger.info("Cookie consent dialog closed")
|
||||
|
||||
@@ -373,9 +425,11 @@ def submit_form(page):
|
||||
success_heading = page.locator("h2:has-text('FORMULARIO ENVIADO CORRECTAMENTE')")
|
||||
success_heading.wait_for(state="visible", timeout=10000)
|
||||
logger.info("Form submitted successfully")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error submitting form: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def return_to_form(page):
|
||||
@@ -409,13 +463,27 @@ def main():
|
||||
|
||||
headless = os.getenv("HEADLESS", "true").lower() == "true"
|
||||
use_mock_data = os.getenv("USE_MOCK_DATA", "false").lower() == "true"
|
||||
use_tor = os.getenv("USE_TOR", "false").lower() == "true"
|
||||
proxy_address = os.getenv("TOR_PROXY", "socks5://127.0.0.1:9050")
|
||||
|
||||
logger.info(f"Opening browser to: {url}")
|
||||
logger.info(f"Headless mode: {headless}")
|
||||
logger.info(f"Use mock data: {use_mock_data}")
|
||||
logger.info(f"Use Tor: {use_tor}")
|
||||
if use_tor:
|
||||
logger.info(f"Tor proxy: {proxy_address}")
|
||||
|
||||
# Wait for Tor connection if enabled
|
||||
if use_tor:
|
||||
wait_for_tor_connection(proxy_address)
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=headless)
|
||||
# Configure browser with or without proxy
|
||||
browser_options = {"headless": headless}
|
||||
if use_tor:
|
||||
browser_options["proxy"] = {"server": proxy_address}
|
||||
|
||||
browser = p.chromium.launch(**browser_options)
|
||||
page = browser.new_page()
|
||||
page.goto(url)
|
||||
|
||||
@@ -425,6 +493,8 @@ def main():
|
||||
if use_mock_data:
|
||||
# Continuous mock data mode - generate and submit until stopped
|
||||
submission_count = 0
|
||||
failure_count = 0
|
||||
max_failures = 3
|
||||
logger.info("Starting continuous mock data mode - will run until stopped")
|
||||
|
||||
while True:
|
||||
@@ -436,31 +506,65 @@ def main():
|
||||
logger.info(f"Submitting for: {form_data['nombre_local']}")
|
||||
|
||||
fill_form(page, form_data)
|
||||
submit_form(page)
|
||||
return_to_form(page)
|
||||
success = submit_form(page)
|
||||
|
||||
# Wait between submissions
|
||||
wait_time = random.randint(3, 8) # Random delay 3-8 seconds
|
||||
logger.info(f"Waiting {wait_time} seconds before next submission...")
|
||||
page.wait_for_timeout(wait_time * 1000)
|
||||
if success:
|
||||
failure_count = 0 # Reset failure counter on success
|
||||
return_to_form(page)
|
||||
|
||||
# Wait between submissions
|
||||
wait_time = random.randint(3, 5) # Random delay 3-5 seconds
|
||||
logger.info(f"Waiting {wait_time} seconds before next submission...")
|
||||
page.wait_for_timeout(wait_time * 1000)
|
||||
else:
|
||||
failure_count += 1
|
||||
logger.warning(f"Submission failed. Failure count: {failure_count}/{max_failures}")
|
||||
|
||||
if failure_count >= max_failures:
|
||||
logger.error(f"Reached maximum failures ({max_failures}). Exiting application.")
|
||||
break
|
||||
|
||||
# Wait a bit before retrying
|
||||
logger.info("Waiting 5 seconds before next attempt...")
|
||||
page.wait_for_timeout(5000)
|
||||
else:
|
||||
# YAML file mode - process all submissions once
|
||||
form_data_list = load_form_data()
|
||||
failure_count = 0
|
||||
max_failures = 3
|
||||
successful_submissions = 0
|
||||
|
||||
for i, form_data in enumerate(form_data_list, 1):
|
||||
logger.info(f"--- Processing submission {i}/{len(form_data_list)} ---")
|
||||
logger.info(f"Submitting for: {form_data['nombre_local']}")
|
||||
|
||||
fill_form(page, form_data)
|
||||
submit_form(page)
|
||||
success = submit_form(page)
|
||||
|
||||
# Return to form for next submission (except on last one)
|
||||
if i < len(form_data_list):
|
||||
return_to_form(page)
|
||||
logger.info("Waiting 2 seconds before next submission...")
|
||||
page.wait_for_timeout(2000)
|
||||
if success:
|
||||
failure_count = 0 # Reset failure counter on success
|
||||
successful_submissions += 1
|
||||
|
||||
# Return to form for next submission (except on last one)
|
||||
if i < len(form_data_list):
|
||||
return_to_form(page)
|
||||
logger.info("Waiting 2 seconds before next submission...")
|
||||
page.wait_for_timeout(2000)
|
||||
else:
|
||||
failure_count += 1
|
||||
logger.warning(f"Submission failed. Failure count: {failure_count}/{max_failures}")
|
||||
|
||||
if failure_count >= max_failures:
|
||||
logger.error(f"Reached maximum failures ({max_failures}). Exiting application.")
|
||||
break
|
||||
|
||||
# Return to form to retry or continue
|
||||
if i < len(form_data_list):
|
||||
return_to_form(page)
|
||||
logger.info("Waiting 5 seconds before next attempt...")
|
||||
page.wait_for_timeout(5000)
|
||||
|
||||
logger.info(f"Completed {len(form_data_list)} form submissions successfully")
|
||||
logger.info(f"Completed {successful_submissions}/{len(form_data_list)} form submissions successfully")
|
||||
|
||||
if not headless:
|
||||
input("Press Enter to close the browser...")
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "l4l1g4-d3nunc145"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
description = "Automated LaLiga piracy reporting tool for legitimate complaints. Spanish form automation with Docker support."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
@@ -9,4 +9,5 @@ dependencies = [
|
||||
"playwright>=1.55.0",
|
||||
"python-dotenv>=1.1.1",
|
||||
"pyyaml>=6.0.2",
|
||||
"requests>=2.31.0",
|
||||
]
|
||||
|
Reference in New Issue
Block a user