爬取大学课程网站时遭遇TooManyRedirects错误的解决咨询
解决重定向循环问题的修复方案
你的代码触发重定向循环,核心原因是ASP.NET页面的动态验证参数(__VIEWSTATE、__EVENTVALIDATION等)没有在每次请求后更新,同时缺少必要的浏览器请求头模拟,导致服务器拒绝请求并不断重定向。以下是具体修复步骤:
关键修复点
- 每次POST请求后,从新返回的页面中提取最新的
__VIEWSTATE、__EVENTVALIDATION等参数,而非一直复用第一次GET请求的旧值 - 添加浏览器请求头(如
User-Agent),模拟正常用户访问 - 确保会话(session)持续维持,避免状态丢失
修改后的完整代码
from bs4 import BeautifulSoup import requests url = "https://internet3.trincoll.edu/ptools/courselisting.aspx" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } with requests.session() as s: # 初始请求获取页面和初始参数 s.headers.update(headers) response = s.get(url) soup = BeautifulSoup(response.content, "html.parser") courses = [v["value"] for v in soup.select("#ddlList [value]") if v["value"] != "0"] # 过滤空值选项 for c in courses: # 从当前页面提取最新的表单参数 data = {} for inp in soup.select("input[name]"): if inp.get("value") is not None: data[inp["name"]] = inp["value"] # 设置需要修改的参数 data["ddlList"] = c data["ddlLevelList"] = "0" data["ddlTermList"] = "1241" # Fall 2023 data["ddlSession"] = "0" data["__EVENTTARGET"] = "ddlList" data["__EVENTARGUMENT"] = "" data["__LASTFOCUS"] = "" # 发送POST请求 response = s.post(url, data=data) # 更新soup为最新返回的页面,用于下一次循环提取参数 soup = BeautifulSoup(response.content, "html.parser") # 解析课程数据 print(c) print("-" * 80) # 调整选择器确保匹配正确元素,避免重复或错误 course_rows = soup.select("tr[class^='row']") for row in course_rows: id_elem = row.select_one(".TITLE_id") time_elem = row.select_one(".TITLE_times") title_elem = row.select_one(".TITLE_title") c_id_elem = row.select_one("td[nowrap='true']") if all([id_elem, time_elem, title_elem, c_id_elem]): print(f"{id_elem.text.strip():<10} {title_elem.text.strip()} {time_elem.text.strip()} {c_id_elem.text.strip()}") print()
修复说明
- 动态更新表单参数:每次循环都从最新页面提取
__VIEWSTATE等参数,这些是ASP.NET验证请求合法性的关键,旧参数会导致服务器拒绝请求并触发重定向。 - 添加User-Agent头:很多网站会拦截无浏览器标识的请求,添加该头可模拟正常用户访问,降低被拦截概率。
- 过滤无效选项:原代码可能包含
ddlList的空值选项(如value="0"),过滤后避免无效请求。 - 优化元素选择:通过选择课程行而非单独的td元素,避免
zip时因元素数量不匹配导致的错误,确保每个课程信息对应正确。
如果仍出现重定向问题,可尝试:
- 检查
ddlTermList的值是否有效(当前1241对应Fall2023,若学期已结束需更换为最新学期代码) - 在会话中添加更多请求头(如
Accept-Language、Referer),进一步模拟浏览器行为
内容的提问来源于stack exchange,提问作者akhargha
相关产品推荐
相关产品推荐

