Python笔记(六)--Python3实现定时自动提交问卷星问卷

大概内容如下:

  1. 利用Fiddler抓包,对点击提交所传输的数据包进行分析;(划重点)
  2. 爬取免费代理ip网站(例如:西刺代理)发布的IP地址,构建ip地址池;
  3. 引用fake_useragent库的UserAgent包,获取随机User-Agent
    (第2,3点都是为了构造http header,以应对网站的反爬虫机制。不过实测post太频繁,会报错:远端主机积极断开连接之类的)

小细节:

由于post地址采用https协议,所以如果直接使用requests方法来传参,将会报错(可能是证书相关的问题,这里就不深究了),那么可以通过以下方法解决:

import requests
requests.packages.urllib3.disable_warnings()#缺少将会报错警告,但好像不影响脚本运行
 r = requests.post(url, headers=headers, data=data, verify=False)# verify默认是True的,所以手工设置为False,

利用Fiddler抓包,对点击提交所传输的数据包进行分析

以寄信来比喻提交过程,浏览器是寄信人,服务器是收信人,那么url就是收信地址,信件记录着基本信息和正文内容(header和body)

记录下浏览器传参t的目的url
Python笔记(六)--Python3实现定时自动提交问卷星问卷_第1张图片

查看header中包含哪些信息,收集起来,用来丰富我们构建的请求头
Python笔记(六)--Python3实现定时自动提交问卷星问卷_第2张图片我们可以看到使用post方法传参,url,请求头 以及 submitdata内容(编码后的)
Python笔记(六)--Python3实现定时自动提交问卷星问卷_第3张图片
看到经解码的参数,分析submitdata 参数,可能是由题目以及所选选项的序号组成的
Python笔记(六)--Python3实现定时自动提交问卷星问卷_第4张图片
(这里如果是开放性问卷,即提交参数中包含中文,需要经过编码才能提交)

data = 'submit=1$2}2$3}3$python大法好啊'.encode("utf-8").decode("latin1")

最后我们看一下提交成功后,服务器会返回什么数据(亲测:成功返回json=10,否则返回22)
Python笔记(六)--Python3实现定时自动提交问卷星问卷_第5张图片


当做好数据收集和分析后,我可以开始编写代码了

  1. 爬取免费代理IP地址的网站,利用正侧表达式获取其公布的免费代理IP,从而丰富我们的IP地址池,然后通过random.choise(地址列表)来随机获取地址池中的IP
def Get_IP():
    headers = {     #构建简易的请求头,用于访问西刺代理网站
        'User-Agent': UserAgent().random
    }
    html = urllib.request.Request(url='https://www.xicidaili.com/nn/', headers=headers)
    html = urllib.request.urlopen(html).read().decode('utf-8')
    reg = r'(.+?)'#通过浏览器的F12查看页面元素,发现所有元素都放在td标签中,并按IP地址,端口,协议,地址,时间的顺序排列
    reg = re.compile(reg)
    #经正侧表达式匹配后将所有元素按顺序存放在列表中,但这并不是最终的结果
    pools = re.findall(reg, html)[0:499:5]#提取出其中所有的IP地址,并存放到列表中,形成地址池
    Random_IP = random.choice(pools)#随机在地址池中选出一个IP地址
    return Random_IP
  1. 构建请求头header(这里需要自己抓包收集数据(Cookie)来构建自己的请求头)
    如果一直不成功可以重新抓包更换一下coookie
def Get_Headers():
    headers = {  
        'Host':'www.wjx.cn',
        'User-Agent': UserAgent().random,#随机User-Agent,需要从fake_useragent 库中 UserAgent包
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',#以表格形式提交数据
        'Referer':'https://www.wjx.cn/m/XXXXX.aspx',#你的调查问卷链接
        'Cookie':'XXXXX',#抓包
        'X-Forwarded-For':Get_IP()#调用函数获取代理IP地址
    }
    return headers
  1. 构建传参函数用来提交参数
def Auto_WjX():
    url = '目的url'
    #data是提交的参数(填写的问卷数据需要自己按实际情况编写)
    #若包含中文参数则需要指定编码,例:data = 'submit=1$2}2$3}3$python大法好啊'.encode("utf-8").decode("latin1")
    data = "submitdata=1$1}2$3}3$1}4$2}5$1}6$2}7$2}8$1}9$1}10$1}11$1}12$1}13$1}14$1}15$1}16$1}17$1}18$1}19$1}20$1}21$1}22$1}23$1}24$1}25$2}26$3}27$3}28$2|10|13|19}29$4|10}30$3|7}31$2}32$3}33$4}34$1}35$1}36$1}37$2}38$2}39$2}40$2}41$1}42$2}43$1}44$2}45$1}46$1}47$4}48$4}49$4}50$4}51$3}52$3}53$1}54$1}55$1}56$3}57$3}58$3}59$1}60$3}61$3"
    r = requests.post(url, headers=Get_Headers(), data=data, verify=False)
    #通过测试返回数据中表示成功与否的关键数据(’10‘or '22')在开头,所以只需要提取返回数据中前两位元素
    result = r.text[0:2]
    return result
  1. 剩下的就是编写自己的mian函数了(这里就不多说了,只有一点就是休眠时间设置长一点)
def main():
    global PostNum
    for i in range(10):
        result = Auto_WjX()
        if int(result) in [10]:#循环10次,调用10次Auto_WjX函数(亲测提交10次,成功5次,50%的成功率)
            print('[ Response : %s ]  ===> 提交成功!!!!' % result)
            PostNum += 1
        else:
            print('[ Response : %s ]  ===> 提交失败!!!!' % result)
        time.sleep(30)  # 设置休眠时间,这里要设置足够长的休眠时间
    print('脚本运行结束,成功提交%s份调查报告' % PostNum)  # 总结提交成功的数量,并打印

if __name__ == '__main__':
    main()

放上完整代码

import requests
import urllib.request
from fake_useragent import UserAgent
import re
import random
import time

requests.packages.urllib3.disable_warnings()
PostNum = 0

def Get_Headers():
    headers = {  
        'Host':'www.wjx.cn',
        'User-Agent': UserAgent().random,
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
        'Referer':'https://www.wjx.cn/m/38072076.aspx',
        'Cookie':'UM_distinctid=169ced4487c381-0eb21ff10e540a-784a5037-144000-169ced4487e128f; CNZZDATA4478442=cnzz_eid%3D198455657-1553952914-%26ntime%3D1555839771; .ASPXANONYMOUS=b8bj7o8d1QEkAAAAZjU3NjRkOWEtYzZjNC00ZDg4LTkxZmQtODdkMWZmZmYzM2EyPkFcM46KG2F_Bo62rCi-B5EyW9M1; acw_tc=2f624a1d15539532106003838e1bce9d7d440f74597e79e5b0c885288baa35; jac38072076=19904652; Hm_lvt_21be24c80829bd7a683b2c536fcf520b=1553953297,1553953308,1553953311,1555841361; Hm_lpvt_21be24c80829bd7a683b2c536fcf520b=1555841361',
        'X-Forwarded-For':Get_IP()
    }
    return headers

def Get_IP():
    headers = {
        'User-Agent': UserAgent().random
    }
    html = urllib.request.Request(url='https://www.xicidaili.com/nn/', headers=headers)
    html = urllib.request.urlopen(html).read().decode('utf-8')
    reg = r'(.+?)'
    reg = re.compile(reg)
    pools = re.findall(reg, html)[0:499:5]
    Random_IP = random.choice(pools)
    return Random_IP

def Auto_WjX():
    url = 'https://www.wjx.cn/joinnew/processjq.ashx?curid=38072076&starttime=2019%2F4%2F21%2018%3A09%3A16&source=directphone&submittype=1&ktimes=482&hlv=1&rn=3661365232.19904652&t=1555841474155&jqnonce=b3931762-39e9-4136-a3a8-087e62f3497d&jqsign=%601%3B13540%2F1%3Bg%3B%2F6314%2Fc1c%3A%2F2%3A5g40d16%3B5f'
    data = "submitdata=1$1}2$3}3$1}4$2}5$1}6$2}7$2}8$1}9$1}10$1}11$1}12$1}13$1}14$1}15$1}16$1}17$1}18$1}19$1}20$1}21$1}22$1}23$1}24$1}25$2}26$3}27$3}28$2|10|13|19}29$4|10}30$3|7}31$2}32$3}33$4}34$1}35$1}36$1}37$2}38$2}39$2}40$2}41$1}42$2}43$1}44$2}45$1}46$1}47$4}48$4}49$4}50$4}51$3}52$3}53$1}54$1}55$1}56$3}57$3}58$3}59$1}60$3}61$3"
    r = requests.post(url, headers=Get_Headers(), data=data, verify=False)
    result = r.text[0:2]
    return result

def main():
    global PostNum
    for i in range(10):
        result = Auto_WjX()
        if int(result) in [10]:
            print('[ Response : %s ]  ===> 提交成功!!!!' % result)
            PostNum += 1
        else:
            print('[ Response : %s ]  ===> 提交失败!!!!' % result)
        time.sleep(30)  # 设置休眠时间,这里要设置足够长的休眠时间
    print('脚本运行结束,成功提交%s份调查报告' % PostNum)  # 总结提交成功的数量,并打印

if __name__ == '__main__':
    main()

仅供研究学习,勿要滥用

你可能感兴趣的:(Python3)