From 4d764f6de9a8f41e4cf78a74f37c2dac6700a1bc Mon Sep 17 00:00:00 2001 From: ANGEL MERINO Date: Sun, 24 Aug 2025 09:21:59 -0500 Subject: [PATCH] Upgrade rutina --- solutions/02_web_scraping_solutions.ipynb | 186 ++++++++++++++-------- solutions/senado_ilga_members.csv | 61 +++++++ solutions/senado_ilga_moderno.csv | 120 +++++++------- 3 files changed, 243 insertions(+), 124 deletions(-) create mode 100644 solutions/senado_ilga_members.csv diff --git a/solutions/02_web_scraping_solutions.ipynb b/solutions/02_web_scraping_solutions.ipynb index 68614c5..3d5eaa3 100644 --- a/solutions/02_web_scraping_solutions.ipynb +++ b/solutions/02_web_scraping_solutions.ipynb @@ -243,14 +243,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[WARN] No se pudo leer https://www.ilga.gov/Senate/List: 404 Client Error: Not Found for url: https://www.ilga.gov/Senate/List\n", "Perfiles encontrados en la lista: 60\n", "Total miembros parseados: 60\n", "('Member', 8505, 'D', 'https://www.ilga.gov/Senate/Members/Details/3264')\n", @@ -272,7 +271,7 @@ "3 Member 5966 D https://www.ilga.gov/Senate/Members/Details/3269\n", "4 Member 422 D https://www.ilga.gov/Senate/Members/Details/3270\n", "\n", - "CSV generado: senado_ilga_moderno.csv\n" + "CSV generado: senado_ilga_members.csv\n" ] } ], @@ -284,7 +283,7 @@ "\n", "LIST_URLS = [\n", " \"https://www.ilga.gov/Senate/Members/List\",\n", - " \"https://www.ilga.gov/Senate/List\",\n", + " \"https://www.ilga.gov/Senate/Members\",\n", "]\n", "BASE = \"https://www.ilga.gov\"\n", "\n", @@ -415,7 +414,7 @@ " print(\"\\nPrimeras 5 filas:\")\n", " print(df.head())\n", " df.to_csv(\"senado_ilga_moderno.csv\", index=False, encoding=\"utf-8\")\n", - " print(\"\\nCSV generado: senado_ilga_moderno.csv\")\n", + " print(\"\\nCSV generado: senado_ilga_members.csv\")\n", " except ImportError:\n", " print(\"Pandas no está instalado; omitiendo CSV. Instala con: pip install pandas openpyxl\")\n", "\n", @@ -547,53 +546,107 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 96, "metadata": {}, "outputs": [], "source": [ - "import re\n", + "import re, time\n", "from urllib.parse import urljoin\n", "import requests\n", "from bs4 import BeautifulSoup\n", "\n", - "def get_members(url: str = \"https://www.ilga.gov/Senate/Members/List\"):\n", + "HEADERS = {\"User-Agent\": \"Mozilla/5.0\"}\n", + "\n", + "# --- util: extraer distrito/partido desde texto plano ---\n", + "def _extract_district_party(text: str):\n", + " # 1) \"47 R\"\n", + " m = re.search(r'\\b(\\d+)\\s+([DRI])\\b', text)\n", + " if m:\n", + " return int(m.group(1)), m.group(2).upper()\n", + " # 2) \"District 47 (R)\" u otras variantes\n", + " m = re.search(r'(?:District\\s*)?(\\d+).*?\\b([DRI])\\b', text, flags=re.I)\n", + " if m:\n", + " return int(m.group(1)), m.group(2).upper()\n", + " # 3) Si solo viene el nombre del partido completo\n", + " party = \"\"\n", + " if re.search(r'\\bDemocrat(ic)?\\b', text, flags=re.I):\n", + " party = \"D\"\n", + " elif re.search(r'\\bRepublican\\b', text, flags=re.I):\n", + " party = \"R\"\n", + " elif re.search(r'\\bIndependent\\b', text, flags=re.I):\n", + " party = \"I\"\n", + " return None, party # distrito desconocido, partido si se detectó\n", + "\n", + "# --- leer distrito/partido desde el perfil individual ---\n", + "def _parse_profile(profile_url: str, session: requests.Session):\n", + " r = session.get(profile_url, timeout=30)\n", + " r.raise_for_status()\n", + " psoup = BeautifulSoup(r.text, \"lxml\")\n", + "\n", + " # nombre (por si quieres validar)\n", + " name = \"\"\n", + " h1 = psoup.select_one(\"h1\")\n", + " if h1:\n", + " name = h1.get_text(strip=True)\n", + " elif psoup.title:\n", + " name = psoup.title.get_text(strip=True)\n", + "\n", + " text = psoup.get_text(\" \", strip=True)\n", + " district, party = _extract_district_party(text)\n", + " return name, district, party\n", + "\n", + "def get_members(url: str = \"https://www.ilga.gov/Senate/Members\"):\n", " \"\"\"\n", - " Devuelve una lista de tuplas (Nombre, Distrito:int, Partido:str, Perfil:str)\n", - " extraídas desde la página moderna del Senado de Illinois.\n", + " Devuelve lista de tuplas (Nombre, Distrito:int|None, Partido:str, Perfil:str)\n", + " Tomando enlaces a /Senate/Members/Details/... desde /Senate/Members o /Senate/Members/List.\n", + " Si el distrito/partido no está cerca del enlace, se visita el perfil para extraerlos.\n", " \"\"\"\n", - " headers = {\"User-Agent\": \"Mozilla/5.0\"}\n", - " resp = requests.get(url, headers=headers, timeout=30)\n", - " resp.raise_for_status()\n", + " s = requests.Session()\n", + " s.headers.update(HEADERS)\n", + "\n", + " r = s.get(url, timeout=30)\n", + " r.raise_for_status()\n", + " soup = BeautifulSoup(r.text, \"lxml\")\n", "\n", - " soup = BeautifulSoup(resp.text, \"lxml\")\n", " members = []\n", + " seen = set()\n", "\n", - " # Enlaces a perfiles /Senate/Members/Details/\n", + " # Enlaces a perfiles\n", " for a in soup.select('a[href*=\"/Senate/Members/Details/\"], a[href*=\"/senate/members/details/\"]'):\n", " name = a.get_text(strip=True)\n", " if not name:\n", " continue\n", "\n", - " # En el contenedor suele venir \"Nombre 47 R\" (número + partido)\n", - " full_text = a.parent.get_text(\" \", strip=True)\n", - " tail = full_text.replace(name, \"\").strip()\n", - "\n", - " # 1) patrón directo: \"47 R\"\n", - " m = re.search(r'(\\d+)\\s+([DRI])\\b', tail)\n", - " # 2) fallback: \"District 47 (R)\" u otras variantes\n", - " if not m:\n", - " m = re.search(r'(?:District\\s*)?(\\d+).*?([DRI])\\b', tail, re.I)\n", - " if not m:\n", - " # si no se detecta distrito/partido, igual guarda el nombre y el perfil\n", - " district, party = None, \"\"\n", - " else:\n", - " district = int(m.group(1))\n", - " party = m.group(2).upper()\n", - "\n", - " profile = urljoin(url, a.get(\"href\"))\n", + " profile = urljoin(url, a.get(\"href\") or \"\")\n", + " if profile in seen:\n", + " continue\n", + " seen.add(profile)\n", + "\n", + " # 1) Intentar extraer distrito/partido del contenedor más cercano\n", + " container = a.parent\n", + " # sube hasta 3 niveles si es necesario (algunas páginas usan divs anidados)\n", + " hops = 0\n", + " while container and hops < 3 and len(container.get_text(strip=True)) < 10:\n", + " container = container.parent\n", + " hops += 1\n", + "\n", + " tail_text = \"\"\n", + " if container:\n", + " # texto del contenedor sin el nombre, para evitar falsos positivos\n", + " ctext = container.get_text(\" \", strip=True)\n", + " tail_text = ctext.replace(name, \"\").strip()\n", + "\n", + " district, party = _extract_district_party(tail_text)\n", + "\n", + " # 2) Si no encontramos, entramos al perfil\n", + " if district is None and not party:\n", + " _, district, party = _parse_profile(profile, s)\n", + " time.sleep(0.2) # cortesía con el servidor\n", + "\n", " members.append((name, district, party, profile))\n", "\n", - " return members\n" + " return members\n", + "\n" ] }, { @@ -644,7 +697,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 97, "metadata": {}, "outputs": [ { @@ -652,11 +705,11 @@ "output_type": "stream", "text": [ "Total miembros: 60\n", - "('Neil Anderson', None, '', 'https://www.ilga.gov/Senate/Members/Details/3312')\n", - "('Omar Aquino', None, '', 'https://www.ilga.gov/Senate/Members/Details/3316')\n", - "('Li Arellano, Jr.', None, '', 'https://www.ilga.gov/Senate/Members/Details/3383')\n", - "('Chris Balkema', None, '', 'https://www.ilga.gov/Senate/Members/Details/3413')\n", - "('Christopher Belt', None, '', 'https://www.ilga.gov/Senate/Members/Details/3337')\n" + "('Neil Anderson', 2006, 'R', 'https://www.ilga.gov/Senate/Members/Details/3312')\n", + "('Omar Aquino', 2016, 'D', 'https://www.ilga.gov/Senate/Members/Details/3316')\n", + "('Li Arellano, Jr.', 2025, 'D', 'https://www.ilga.gov/Senate/Members/Details/3383')\n", + "('Chris Balkema', 2025, 'R', 'https://www.ilga.gov/Senate/Members/Details/3413')\n", + "('Christopher Belt', 2019, 'R', 'https://www.ilga.gov/Senate/Members/Details/3337')\n" ] } ], @@ -664,7 +717,8 @@ "senate_members = get_members() # o get_members(\"https://www.ilga.gov/Senate/Members/List\")\n", "print(\"Total miembros:\", len(senate_members))\n", "for m in senate_members[:5]:\n", - " print(m)\n" + " print(m)\n", + "\n" ] }, { @@ -679,19 +733,19 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 98, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - " Nombre Distrito Partido \\\n", - "0 Neil Anderson None \n", - "1 Omar Aquino None \n", - "2 Li Arellano, Jr. None \n", - "3 Chris Balkema None \n", - "4 Christopher Belt None \n", + " Nombre Distrito Partido \\\n", + "0 Neil Anderson 2006.0 R \n", + "1 Omar Aquino 2016.0 D \n", + "2 Li Arellano, Jr. 2025.0 D \n", + "3 Chris Balkema 2025.0 R \n", + "4 Christopher Belt 2019.0 R \n", "\n", " Perfil \n", "0 https://www.ilga.gov/Senate/Members/Details/3312 \n", @@ -707,7 +761,8 @@ "\n", "df = pd.DataFrame(senate_members, columns=[\"Nombre\", \"Distrito\", \"Partido\", \"Perfil\"])\n", "print(df.head())\n", - "# df.to_csv(\"senado_ilga_moderno.csv\", index=False, encoding=\"utf-8\")\n" + "\n", + "df.to_csv(\"senado_ilga_moderno.csv\", index=False, encoding=\"utf-8\")\n" ] }, { @@ -742,7 +797,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 72, "metadata": {}, "outputs": [], "source": [ @@ -867,7 +922,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 101, "metadata": {}, "outputs": [], "source": [ @@ -879,15 +934,18 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 104, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Clave encontrada: None\n", - "No hay datos para distrito 52.\n" + "Clave encontrada: 2006\n", + "Clave encontrada: 2016\n", + "Clave encontrada: 2025\n", + "Clave encontrada: 2019\n", + "Número de proyectos para distrito 2006: 0\n" ] } ], @@ -897,24 +955,24 @@ " print(\"Clave encontrada:\", key)\n", "\n", "# Acceder de forma segura\n", - "if 52 in bills_dict:\n", - " print(\"Número de proyectos para distrito 52:\", len(bills_dict[52]))\n", + "if 2006 in bills_dict:\n", + " print(\"Número de proyectos para distrito 2006:\", len(bills_dict[2006]))\n", "else:\n", - " print(\"No hay datos para distrito 52.\")\n" + " print(\"No hay datos para distrito 2006.\")\n" ] }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Claves disponibles en bills_dict: [None]\n", - "Total claves: 1\n", - "No hay datos para el distrito 52.\n" + "Claves disponibles en bills_dict: [2006, 2016, 2025, 2019]\n", + "Total claves: 4\n", + "No hay datos para el distrito 2019.\n" ] } ], @@ -922,11 +980,11 @@ "print(\"Claves disponibles en bills_dict:\", list(bills_dict.keys()))\n", "print(\"Total claves:\", len(bills_dict))\n", "\n", - "bills_52 = bills_dict.get(52) or bills_dict.get(\"52\")\n", - "if bills_52 is None:\n", - " print(\"No hay datos para el distrito 52.\")\n", + "bills_2019 = bills_dict.get(2019) or bills_dict.get(\"2019\")\n", + "if bills_2019 is None:\n", + " print(\"No hay datos para el distrito 2019.\")\n", "else:\n", - " print(\"Número de proyectos:\", len(bills_52))\n" + " print(\"Número de proyectos:\", len(bills_2019))\n" ] } ], diff --git a/solutions/senado_ilga_members.csv b/solutions/senado_ilga_members.csv new file mode 100644 index 0000000..c1a799c --- /dev/null +++ b/solutions/senado_ilga_members.csv @@ -0,0 +1,61 @@ +Nombre,Distrito,Partido,Perfil +Craig Wilcox,4,R,https://www.ilga.gov/Senate/Members/Details/3336 +Karina Villa,33,D,https://www.ilga.gov/Senate/Members/Details/3385 +Meg Loughran Cappel,52,D,https://www.ilga.gov/Senate/Members/Details/3380 +Mike Porfirio,54,D,https://www.ilga.gov/Senate/Members/Details/3404 +Andrew S. Chesney,180,R,https://www.ilga.gov/Senate/Members/Details/3410 +Christopher Belt,187,D,https://www.ilga.gov/Senate/Members/Details/3337 +Doris Turner,228,D,https://www.ilga.gov/Senate/Members/Details/3399 +Linda Holmes,422,D,https://www.ilga.gov/Senate/Members/Details/3270 +Sara Feigenholtz,523,D,https://www.ilga.gov/Senate/Members/Details/3376 +Chapin Rose,1006,R,https://www.ilga.gov/Senate/Members/Details/3295 +Robert F. Martwick,1035,D,https://www.ilga.gov/Senate/Members/Details/3369 +Willie Preston,1607,D,https://www.ilga.gov/Senate/Members/Details/3405 +"Li Arellano, Jr.",1942,R,https://www.ilga.gov/Senate/Members/Details/3383 +Donald P. DeWitte,1977,R,https://www.ilga.gov/Senate/Members/Details/3334 +Laura Fine,2119,D,https://www.ilga.gov/Senate/Members/Details/3338 +Jil Tracy,2479,R,https://www.ilga.gov/Senate/Members/Details/3319 +Paul Faraci,2507,D,https://www.ilga.gov/Senate/Members/Details/3412 +"Elgie R. Sims, Jr.",3201,D,https://www.ilga.gov/Senate/Members/Details/3331 +Julie A. Morrison,3650,D,https://www.ilga.gov/Senate/Members/Details/3294 +Sue Rezin,3840,R,https://www.ilga.gov/Senate/Members/Details/3281 +Laura M. Murphy,3875,D,https://www.ilga.gov/Senate/Members/Details/3313 +Michael W. Halpin,4307,D,https://www.ilga.gov/Senate/Members/Details/3408 +Mark L. Walker,4471,D,https://www.ilga.gov/Senate/Members/Details/3449 +Bill Cunningham,5145,D,https://www.ilga.gov/Senate/Members/Details/3291 +Erica Harriss,5247,R,https://www.ilga.gov/Senate/Members/Details/3411 +Celina Villanueva,5304,D,https://www.ilga.gov/Senate/Members/Details/3375 +Robert Peters,5338,D,https://www.ilga.gov/Senate/Members/Details/3343 +Dave Syverson,5413,R,https://www.ilga.gov/Senate/Members/Details/3265 +Ram Villivalam,5500,D,https://www.ilga.gov/Senate/Members/Details/3345 +Dale Fowler,5509,R,https://www.ilga.gov/Senate/Members/Details/3318 +Omar Aquino,5652,D,https://www.ilga.gov/Senate/Members/Details/3316 +Jason Plummer,5755,R,https://www.ilga.gov/Senate/Members/Details/3344 +Neil Anderson,5957,R,https://www.ilga.gov/Senate/Members/Details/3312 +Mattie Hunter,5966,D,https://www.ilga.gov/Senate/Members/Details/3269 +Sally J. Turner,6216,R,https://www.ilga.gov/Senate/Members/Details/3397 +Lakesia Collins,6252,D,https://www.ilga.gov/Senate/Members/Details/3443 +Chris Balkema,6597,R,https://www.ilga.gov/Senate/Members/Details/3413 +Mary Edly-Allen,7353,D,https://www.ilga.gov/Senate/Members/Details/3407 +Patrick J. Joyce,7419,D,https://www.ilga.gov/Senate/Members/Details/3372 +Cristina Castro,7746,D,https://www.ilga.gov/Senate/Members/Details/3317 +Dan McConchie,8010,R,https://www.ilga.gov/Senate/Members/Details/3315 +Darby A. Hills,8010,R,https://www.ilga.gov/Senate/Members/Details/3460 +Steve Stadelman,8022,D,https://www.ilga.gov/Senate/Members/Details/3296 +"Napoleon Harris, III",8066,D,https://www.ilga.gov/Senate/Members/Details/3292 +Terri Bryant,8137,R,https://www.ilga.gov/Senate/Members/Details/3386 +Suzy Glowiak Hilton,8148,D,https://www.ilga.gov/Senate/Members/Details/3341 +Don Harmon,8176,D,https://www.ilga.gov/Senate/Members/Details/3268 +Adriane Johnson,8181,D,https://www.ilga.gov/Senate/Members/Details/3378 +Graciela Guzmán,8191,D,https://www.ilga.gov/Senate/Members/Details/3442 +Laura Ellman,8192,D,https://www.ilga.gov/Senate/Members/Details/3339 +Steve McClure,8206,R,https://www.ilga.gov/Senate/Members/Details/3342 +David Koehler,8250,D,https://www.ilga.gov/Senate/Members/Details/3271 +Mike Simmons,8492,D,https://www.ilga.gov/Senate/Members/Details/3398 +Kimberly A. Lightford,8505,D,https://www.ilga.gov/Senate/Members/Details/3264 +Rachel Ventura,8800,D,https://www.ilga.gov/Senate/Members/Details/3409 +John F. Curran,9407,R,https://www.ilga.gov/Senate/Members/Details/3329 +Javier L. Cervantes,9415,D,https://www.ilga.gov/Senate/Members/Details/3403 +Seth Lewis,9463,R,https://www.ilga.gov/Senate/Members/Details/3406 +"Emil Jones, III",9573,D,https://www.ilga.gov/Senate/Members/Details/3276 +Michael E. Hastings,9595,D,https://www.ilga.gov/Senate/Members/Details/3293 diff --git a/solutions/senado_ilga_moderno.csv b/solutions/senado_ilga_moderno.csv index 50f0e43..35c72aa 100644 --- a/solutions/senado_ilga_moderno.csv +++ b/solutions/senado_ilga_moderno.csv @@ -1,61 +1,61 @@ Nombre,Distrito,Partido,Perfil -Member,8505,D,https://www.ilga.gov/Senate/Members/Details/3264 -Member,5413,R,https://www.ilga.gov/Senate/Members/Details/3265 -Member,8176,D,https://www.ilga.gov/Senate/Members/Details/3268 -Member,5966,D,https://www.ilga.gov/Senate/Members/Details/3269 -Member,422,D,https://www.ilga.gov/Senate/Members/Details/3270 -Member,8250,D,https://www.ilga.gov/Senate/Members/Details/3271 -Member,9573,D,https://www.ilga.gov/Senate/Members/Details/3276 -Member,3840,R,https://www.ilga.gov/Senate/Members/Details/3281 -Member,5145,D,https://www.ilga.gov/Senate/Members/Details/3291 -Member,8066,D,https://www.ilga.gov/Senate/Members/Details/3292 -Member,9595,D,https://www.ilga.gov/Senate/Members/Details/3293 -Member,3650,D,https://www.ilga.gov/Senate/Members/Details/3294 -Member,1006,R,https://www.ilga.gov/Senate/Members/Details/3295 -Member,8022,D,https://www.ilga.gov/Senate/Members/Details/3296 -Member,5957,R,https://www.ilga.gov/Senate/Members/Details/3312 -Member,3875,D,https://www.ilga.gov/Senate/Members/Details/3313 -Member,8010,R,https://www.ilga.gov/Senate/Members/Details/3315 -Member,5652,D,https://www.ilga.gov/Senate/Members/Details/3316 -Member,7746,D,https://www.ilga.gov/Senate/Members/Details/3317 -Member,5509,R,https://www.ilga.gov/Senate/Members/Details/3318 -Member,2479,R,https://www.ilga.gov/Senate/Members/Details/3319 -Member,9407,R,https://www.ilga.gov/Senate/Members/Details/3329 -Member,3201,D,https://www.ilga.gov/Senate/Members/Details/3331 -Member,1977,R,https://www.ilga.gov/Senate/Members/Details/3334 -Member,4,R,https://www.ilga.gov/Senate/Members/Details/3336 -Member,187,D,https://www.ilga.gov/Senate/Members/Details/3337 -Member,2119,D,https://www.ilga.gov/Senate/Members/Details/3338 -Member,8192,D,https://www.ilga.gov/Senate/Members/Details/3339 -Member,8148,D,https://www.ilga.gov/Senate/Members/Details/3341 -Member,8206,R,https://www.ilga.gov/Senate/Members/Details/3342 -Member,5338,D,https://www.ilga.gov/Senate/Members/Details/3343 -Member,5755,R,https://www.ilga.gov/Senate/Members/Details/3344 -Member,5500,D,https://www.ilga.gov/Senate/Members/Details/3345 -Member,1035,D,https://www.ilga.gov/Senate/Members/Details/3369 -Member,7419,D,https://www.ilga.gov/Senate/Members/Details/3372 -Member,5304,D,https://www.ilga.gov/Senate/Members/Details/3375 -Member,523,D,https://www.ilga.gov/Senate/Members/Details/3376 -Member,8181,D,https://www.ilga.gov/Senate/Members/Details/3378 -Member,52,D,https://www.ilga.gov/Senate/Members/Details/3380 -Member,1942,R,https://www.ilga.gov/Senate/Members/Details/3383 -Member,33,D,https://www.ilga.gov/Senate/Members/Details/3385 -Member,8137,R,https://www.ilga.gov/Senate/Members/Details/3386 -Member,6216,R,https://www.ilga.gov/Senate/Members/Details/3397 -Member,8492,D,https://www.ilga.gov/Senate/Members/Details/3398 -Member,228,D,https://www.ilga.gov/Senate/Members/Details/3399 -Member,9415,D,https://www.ilga.gov/Senate/Members/Details/3403 -Member,54,D,https://www.ilga.gov/Senate/Members/Details/3404 -Member,1607,D,https://www.ilga.gov/Senate/Members/Details/3405 -Member,9463,R,https://www.ilga.gov/Senate/Members/Details/3406 -Member,7353,D,https://www.ilga.gov/Senate/Members/Details/3407 -Member,4307,D,https://www.ilga.gov/Senate/Members/Details/3408 -Member,8800,D,https://www.ilga.gov/Senate/Members/Details/3409 -Member,180,R,https://www.ilga.gov/Senate/Members/Details/3410 -Member,5247,R,https://www.ilga.gov/Senate/Members/Details/3411 -Member,2507,D,https://www.ilga.gov/Senate/Members/Details/3412 -Member,6597,R,https://www.ilga.gov/Senate/Members/Details/3413 -Member,8191,D,https://www.ilga.gov/Senate/Members/Details/3442 -Member,6252,D,https://www.ilga.gov/Senate/Members/Details/3443 -Member,4471,D,https://www.ilga.gov/Senate/Members/Details/3449 -Member,8010,R,https://www.ilga.gov/Senate/Members/Details/3460 +Neil Anderson,2006.0,R,https://www.ilga.gov/Senate/Members/Details/3312 +Omar Aquino,2016.0,D,https://www.ilga.gov/Senate/Members/Details/3316 +"Li Arellano, Jr.",2025.0,D,https://www.ilga.gov/Senate/Members/Details/3383 +Chris Balkema,2025.0,R,https://www.ilga.gov/Senate/Members/Details/3413 +Christopher Belt,2019.0,R,https://www.ilga.gov/Senate/Members/Details/3337 +Terri Bryant,2015.0,D,https://www.ilga.gov/Senate/Members/Details/3386 +Cristina Castro,2017.0,D,https://www.ilga.gov/Senate/Members/Details/3317 +Javier L. Cervantes,2022.0,R,https://www.ilga.gov/Senate/Members/Details/3403 +Andrew S. Chesney,2018.0,D,https://www.ilga.gov/Senate/Members/Details/3410 +Lakesia Collins,2020.0,R,https://www.ilga.gov/Senate/Members/Details/3443 +Bill Cunningham,2011.0,R,https://www.ilga.gov/Senate/Members/Details/3291 +John F. Curran,110.0,D,https://www.ilga.gov/Senate/Members/Details/3329 +Donald P. DeWitte,2018.0,R,https://www.ilga.gov/Senate/Members/Details/3334 +Mary Edly-Allen,2023.0,D,https://www.ilga.gov/Senate/Members/Details/3407 +Laura Ellman,2019.0,D,https://www.ilga.gov/Senate/Members/Details/3339 +Paul Faraci,2023.0,R,https://www.ilga.gov/Senate/Members/Details/3412 +Sara Feigenholtz,1995.0,R,https://www.ilga.gov/Senate/Members/Details/3376 +Laura Fine,2013.0,R,https://www.ilga.gov/Senate/Members/Details/3338 +Dale Fowler,2016.0,D,https://www.ilga.gov/Senate/Members/Details/3318 +Suzy Glowiak Hilton,2019.0,D,https://www.ilga.gov/Senate/Members/Details/3341 +Graciela Guzmán,2.0,R,https://www.ilga.gov/Senate/Members/Details/3442 +Michael W. Halpin,2023.0,D,https://www.ilga.gov/Senate/Members/Details/3408 +Don Harmon,2003.0,D,https://www.ilga.gov/Senate/Members/Details/3268 +"Napoleon Harris, III",2013.0,R,https://www.ilga.gov/Senate/Members/Details/3292 +Erica Harriss,24.0,D,https://www.ilga.gov/Senate/Members/Details/3411 +Michael E. Hastings,121.0,D,https://www.ilga.gov/Senate/Members/Details/3293 +Darby A. Hills,2025.0,D,https://www.ilga.gov/Senate/Members/Details/3460 +Linda Holmes,309.0,I,https://www.ilga.gov/Senate/Members/Details/3270 +Mattie Hunter,2003.0,R,https://www.ilga.gov/Senate/Members/Details/3269 +Adriane Johnson,2020.0,R,https://www.ilga.gov/Senate/Members/Details/3378 +"Emil Jones, III",2009.0,R,https://www.ilga.gov/Senate/Members/Details/3276 +Patrick J. Joyce,2019.0,D,https://www.ilga.gov/Senate/Members/Details/3372 +David Koehler,2006.0,R,https://www.ilga.gov/Senate/Members/Details/3271 +Seth Lewis,24.0,D,https://www.ilga.gov/Senate/Members/Details/3406 +Kimberly A. Lightford,1998.0,R,https://www.ilga.gov/Senate/Members/Details/3264 +Meg Loughran Cappel,2020.0,D,https://www.ilga.gov/Senate/Members/Details/3380 +Robert F. Martwick,2013.0,D,https://www.ilga.gov/Senate/Members/Details/3369 +Steve McClure,2019.0,I,https://www.ilga.gov/Senate/Members/Details/3342 +Julie A. Morrison,2013.0,D,https://www.ilga.gov/Senate/Members/Details/3294 +Laura M. Murphy,2015.0,R,https://www.ilga.gov/Senate/Members/Details/3313 +Robert Peters,2019.0,I,https://www.ilga.gov/Senate/Members/Details/3343 +Jason Plummer,2019.0,R,https://www.ilga.gov/Senate/Members/Details/3344 +Mike Porfirio,2023.0,I,https://www.ilga.gov/Senate/Members/Details/3404 +Willie Preston,2023.0,R,https://www.ilga.gov/Senate/Members/Details/3405 +Sue Rezin,24.0,D,https://www.ilga.gov/Senate/Members/Details/3281 +Chapin Rose,2003.0,D,https://www.ilga.gov/Senate/Members/Details/3295 +Mike Simmons,2021.0,R,https://www.ilga.gov/Senate/Members/Details/3398 +"Elgie R. Sims, Jr.",2012.0,D,https://www.ilga.gov/Senate/Members/Details/3331 +Steve Stadelman,2013.0,D,https://www.ilga.gov/Senate/Members/Details/3296 +Dave Syverson,1993.0,D,https://www.ilga.gov/Senate/Members/Details/3265 +Jil Tracy,23.0,D,https://www.ilga.gov/Senate/Members/Details/3319 +Doris Turner,2021.0,I,https://www.ilga.gov/Senate/Members/Details/3399 +Sally J. Turner,2021.0,D,https://www.ilga.gov/Senate/Members/Details/3397 +Rachel Ventura,2.0,R,https://www.ilga.gov/Senate/Members/Details/3409 +Karina Villa,2019.0,R,https://www.ilga.gov/Senate/Members/Details/3385 +Celina Villanueva,2019.0,R,https://www.ilga.gov/Senate/Members/Details/3375 +Ram Villivalam,2019.0,R,https://www.ilga.gov/Senate/Members/Details/3345 +Mark L. Walker,2009.0,D,https://www.ilga.gov/Senate/Members/Details/3449 +Craig Wilcox,2018.0,D,https://www.ilga.gov/Senate/Members/Details/3336 +Dan McConchie,,R,https://www.ilga.gov/Senate/Members/Details/3315