ASPX站点的模拟登录实际上一般就是__VIEWSTATE__EVENTVALIDATION这两个变量的处理问题。

简单点可以认为是ASPX站点防止恶意POST请求的办法,即每次用户向ASPX服务器发送POST请求时,都要带上VIEWSTATEEVENTVALIDATION的值,不发送或者在访问逻辑上值不正确,服务器就返回错误,防止恶意行为。

所以用Python模拟登录、浏览ASPX站点时就要多一些步骤。

  • 登录时需要首先GET请求获取登录页面,找到VIEWSTATEEVENTVALIDATION值(这两个值都隐藏在网页源码中),发送POST请求时在POST表单里加上这两个变量。
  • 浏览ASPX站点时最好注意及时更新VIEWSTATEEVENTVALIDATION值,避免再POST时出现麻烦。

注意,GET请求完全不需要考虑VIEWSTATEEVENTVALIDATION的问题,只是为了以后POST方便,需要从GET到的页面获取新的VIEWSTATEEVENTVALIDATION值。


获取VIEWSTATEEVENTVALIDATION

import re
import urllib.request

con = urllib.request.urlopen('http://the.site.com')
content = con.read().decode('gbk')

regular = {
    'viewstate': re.compile(r'id="__VIEWSTATE" value="(.+)" />'),
    'eventvalidation': re.compile(r'id="__EVENTVALIDATION" value="(.+)" />')
}
VIEWSTATE = regular['viewstate'].findall(content)[0]
EVENTVALIDATION = regular['eventvalidation'].findall(content)[0]

这里就是首先GET到登录页面,利用正则表达式获取VIEWSTATEEVENTVALIDATION值。

注意:

  • 正则表达式需要根据网页源码来写;
  • re的findall()返回的是一个数组,这里直接获取第一个数组元素值,所以如果正则表达式没有匹配项,就会报错,而不是空字符串,所以可能需要自行添加相应错误处理。

POST请求:

POST发送的表单需要用抓包工具分析,但一定不要忘了VIEWSTATEEVENTVALIDATION,如:

user = {
    '__EVENTVALIDATION': __EVENTVALIDATION,
    '__VIEWSTATE': __VIEWSTATE,
    # add
}

及时更新VIEWSTATEEVENTVALIDATION

可以包装成一个函数:

def update_aspx_id(html):
    global __VIEWSTATE
    global __EVENTVALIDATION
    __VIEWSTATE = regular['viewstate'].findall(content)[0]
    __EVENTVALIDATION = regular['eventvalidation'].findall(content)[0]

注意:关于global全局变量声明的问题,还可以使用传参或者数组之类的办法,我是为了方便起见。