You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jamabandi网站爬取POST请求失效问题及代码排查

故障排查与解决方案

核心故障原因

  • 会话未保持:未使用requests.Session()统一管理Cookie,ASP.NET的ViewState、SessionID等依赖会话一致性,分散的请求会导致服务器识别无效。
  • 隐藏字段提取不全:进入Mutation页面后,除了常规的__VIEWSTATE、__VIEWSTATEGENERATOR、__EVENTVALIDATION,还需额外提取__EVENTTARGET、__EVENTARGUMENT等触发事件的参数,否则POST请求会被服务器拒绝。
  • POST参数缺失:选择变更编号时,需指定触发控件的ID(比如对应的下拉框或按钮ID),仅传隐藏字段无法触发正确的服务器逻辑。

解决方案

  1. 全程使用Session维护会话:所有GET/POST请求通过同一个requests.Session()对象发送,自动保持Cookie。
  2. 每次请求后重新提取隐藏字段:每个页面跳转后,都解析当前页面的表单隐藏字段,确保参数为最新值。
  3. 补充事件触发参数:在POST请求中加入__EVENTTARGET(指定触发的控件ID)和__EVENTARGUMENT(通常为空),模拟用户点击操作。
  4. 处理页面编码:指定响应编码为utf-8,避免解析BeautifulSoup时出现乱码导致字段提取失败。

完整爬取代码

import requests
from bs4 import BeautifulSoup

# 初始化会话,统一管理Cookie
session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
})

base_url = "https://jamabandi.punjab.gov.in"

def extract_hidden_fields(soup):
    """提取页面所有表单隐藏字段"""
    hidden_fields = {}
    for input_tag in soup.find_all('input', type='hidden'):
        name = input_tag.get('name')
        value = input_tag.get('value')
        if name and value:
            hidden_fields[name] = value
    return hidden_fields

try:
    # 1. 访问首页,提取初始隐藏字段
    response = session.get(base_url)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 2. POST选择地区(示例取第一个可选地区,需根据实际页面调整value)
    district_option = soup.find('select', id='ddlDistrict').find_all('option')[1]
    post_data = hidden_fields.copy()
    post_data.update({
        'ddlDistrict': district_option['value'],
        '__EVENTTARGET': 'ddlDistrict',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 3. POST选择乡(示例取第一个可选乡)
    tehsil_option = soup.find('select', id='ddlTehsil').find_all('option')[1]
    post_data = hidden_fields.copy()
    post_data.update({
        'ddlTehsil': tehsil_option['value'],
        '__EVENTTARGET': 'ddlTehsil',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 4. POST选择村(示例取第一个可选村)
    village_option = soup.find('select', id='ddlVillage').find_all('option')[1]
    post_data = hidden_fields.copy()
    post_data.update({
        'ddlVillage': village_option['value'],
        '__EVENTTARGET': 'ddlVillage',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 5. POST选择年份(示例取第一个可选年份)
    year_option = soup.find('select', id='ddlYear').find_all('option')[1]
    post_data = hidden_fields.copy()
    post_data.update({
        'ddlYear': year_option['value'],
        '__EVENTTARGET': 'ddlYear',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 6. 进入Mutation页面(假设触发按钮ID为btnMutation,需根据实际页面确认)
    post_data = hidden_fields.copy()
    post_data.update({
        '__EVENTTARGET': 'btnMutation',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'
    soup = BeautifulSoup(response.text, 'html.parser')
    hidden_fields = extract_hidden_fields(soup)

    # 7. 选择变更编号(示例取第一个可选编号)
    mutation_option = soup.find('select', id='ddlMutation').find_all('option')[1]
    post_data = hidden_fields.copy()
    post_data.update({
        'ddlMutation': mutation_option['value'],
        '__EVENTTARGET': 'ddlMutation',
        '__EVENTARGUMENT': ''
    })
    response = session.post(base_url, data=post_data)
    response.encoding = 'utf-8'

    # 验证爬取结果
    soup = BeautifulSoup(response.text, 'html.parser')
    print("当前页面标题:", soup.title.string)

except Exception as e:
    print(f"爬取出错: {str(e)}")

# 注意事项:
# 1. 需根据实际页面的控件ID调整参数(比如下拉框、按钮的ID)
# 2. 若页面出现验证码,需额外添加验证码识别逻辑
# 3. 控制请求频率,避免触发网站反爬机制

内容的提问来源于stack exchange,提问作者jatin rajani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:55:08