如何用BeautifulSoup抓取select标签切换选项后的课程数据?
解决ASP.NET课程表网站的专业课程数据抓取问题
问题原因
你之前的方法无效,是因为修改BeautifulSoup解析后的HTML的selected属性,只是在本地修改了静态文本,并没有向服务器发送切换专业的请求。这个网站基于ASP.NET构建,切换专业需要通过提交表单(POST请求)触发服务器返回对应专业的课程数据,而非静态修改HTML就能生效。
解决方案:模拟表单提交获取对应专业数据
要抓取其他专业的课程,需要模拟浏览器提交专业选择的表单请求,步骤如下:
1. 分析表单参数
打开浏览器开发者工具(F12)切换到「网络」标签,选择专业并点击搜索,观察发送的POST请求,会发现需要携带以下关键参数:
- ASP.NET的隐藏字段:
__VIEWSTATE、__VIEWSTATEGENERATOR、__EVENTVALIDATION(这些字段每次请求都会变化,需从初始GET请求的页面中提取) - 专业选择字段:对应下拉菜单的
name属性(比如页面中select标签的name是ctl00$MainContent$ddlPrefix,值为专业代码如CPSC) - 搜索按钮参数:比如
ctl00$MainContent$btnSearch=Search
2. 具体代码实现
from bs4 import BeautifulSoup import requests # 目标网站URL url = 'https://internet3.trincoll.edu/ptools/courselisting.aspx' # 第一步:发送GET请求,获取页面中的隐藏表单参数 session = requests.Session() # 使用Session保持会话,优化请求效率 initial_response = session.get(url) soup_initial = BeautifulSoup(initial_response.text, 'lxml') # 提取ASP.NET所需的隐藏字段 viewstate = soup_initial.find('input', id='__VIEWSTATE')['value'] viewstategenerator = soup_initial.find('input', id='__VIEWSTATEGENERATOR')['value'] eventvalidation = soup_initial.find('input', id='__EVENTVALIDATION')['value'] # 第二步:构造POST请求的表单数据 target_major = 'CPSC' # 想要抓取的专业代码 form_data = { '__VIEWSTATE': viewstate, '__VIEWSTATEGENERATOR': viewstategenerator, '__EVENTVALIDATION': eventvalidation, 'ctl00$MainContent$ddlPrefix': target_major, 'ctl00$MainContent$btnSearch': 'Search' # 对应搜索按钮的提交参数 } # 第三步:发送POST请求,获取对应专业的课程页面 course_response = session.post(url, data=form_data) soup_courses = BeautifulSoup(course_response.text, 'lxml') # 第四步:解析课程ID和上课时间 # 假设课程数据在class为courseRow的tr标签中,可根据实际页面结构调整 course_rows = soup_courses.find_all('tr', class_='courseRow') for row in course_rows: # 提取课程ID(前缀+编号) course_prefix = row.find('td', class_='coursePrefix').text.strip() course_number = row.find('td', class_='courseNumber').text.strip() course_id = f"{course_prefix}{course_number}" # 提取上课时间 course_time = row.find('td', class_='courseTime').text.strip() print(f"课程ID: {course_id}, 上课时间: {course_time}")
注意事项
- 表单字段名(如
ctl00$MainContent$ddlPrefix)需要和页面实际的select标签name属性一致,若网站更新可能会变化,需重新检查。 - 若需要抓取多个专业,只需循环修改
target_major的值,重复发送POST请求即可。
内容的提问来源于stack exchange,提问作者akhargha
相关产品推荐
相关产品推荐

