以前幫朋友做的搶答腳本,雖然最后沒有軟用(因為最后搶的時候頁面壓根打不開),不過在這里分享一下代碼以及思路。
首先,說說設計吧,腳本使用的是selenium+python2,因為在搶答之前我連問卷有啥字段都不知道。所以只能建立一個可能的回答,到時候把可能能自動補入的字段填進去。所以腳本是半自動的,當然,如果問卷是固定字段的就可以全自動了。
config_dict = {
'sfz':'33011111111111111', # 太長了
'csrq':u'1993-1-1',
'sjhm':'123456789',
'xm':u'張三',
'qt':'',
'xb':2,
'zz':u'杭州'
}
for n in range(1,len(question_titles)+1,1):
question_title = question_titles[n-1]
print question_title
if '身份證' in question_title:
question[n] = 'sfz'
elif '手機' in question_title or '聯系' in question_title or '電話' in question_title:
question[n] = 'sjhm'
elif '姓名' in question_title:
question[n] = 'xm'
elif '性別' in question_title:
question[n] = 'xb'
elif '生日' in question_title or '出生' in question_title:
question[n] = 'csrq'
elif '地址' in question_title or '住址' in question_title:
question[n] = 'zz'
else:
question[n] = 'qt'
這里碰到一個問題,就是日期插件的自動選擇 移除上面的readonly屬性即可把選擇形式的日期控件改成直接填值。
if 'csrq'==qname:
cop.exec_js("var setDate=document.getElementById(\"q%s\");setDate.removeAttribute('readonly');"%n);
還有一個選擇性別的單選框插件,這里我默認選擇第二個。
elif 'xb' == qname:
button = cop.find_elements_by_xpath("http://div[@for='q%s_2']"%n)[0]
Action = TouchActions(cop.driver)
Action.tap(button)
Action.perform()
最后,控制腳本到點才開始刷新頁面
while True:
time.sleep(1)
if (datetime.datetime.now().hour>=13 and datetime.datetime.now().minute>=59) or (datetime.datetime.now().hour>=14): # 18點59開搶
break
最終效果:在時間點之前運行代碼,然后腳本會一秒刷新一次頁面,然后能搶了之后會馬上自動填寫吻合預先設置的字段,然后點擊提交。
完整代碼
# -*- coding: utf-8 -*-
"""
File Name: wenjuanxin
Description :
Author : meng_zhihao
date: 2018/9/4
淘寶店地址 :https://shop560916306.taobao.com/?spm=2013.1.1000126.2.3418ab83wv5Ai2
"""
import requests
from lxml import etree
import json
import urllib
import time
import random
import datetime
import csv
import os
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.touch_actions import TouchActions
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import ConfigParser
import re
import datetime
import pdb
class Actions(ActionChains):
def wait(self, time_s):
self._actions.append(lambda: time.sleep(time_s))
return self
class ChromeOperate():
def __init__(self,url='',executable_path='',User_data_dir='',arguments=[],headless=True,mod='pc'):
option = webdriver.ChromeOptions()
if User_data_dir:
option.add_argument( '--user-data-dir=%s'%User_data_dir) # 設置成用戶自己的數據目錄
else:
import getpass
username = getpass.getuser()
default_path = 'C:\Users\%s\AppData\Local\Google\Chrome\User Data'%username #echo %LOCALAPPDATA%\Google\Chrome\User Data
if os.path.exists(default_path):
#option.add_argument('--user-data-dir=%s' % default_path)
pass
if mod=='wx':
mobile_emulation = {'deviceName': 'iPhone 6'}
option.add_experimental_option("mobileEmulation", mobile_emulation)
option.add_argument('--start-maximized')
if headless:option.add_argument('headless')
option.add_argument('google-base-url=%s' % 'https://www.baidu.com/')
for argument in arguments:
option.add_argument(argument)
if not executable_path:executable_path=r'C:\Users\Administrator\Desktop\chromedriver.exe'
self.driver = webdriver.Chrome(executable_path=executable_path,chrome_options=option)
if url:self.open(url)
def open(self,url):
self.driver.get(url) # self.driver.get(url).page_source
def open_source(self):
return self.driver.page_source
def title(self):
self.title=self.driver.title
return self.title
def quit(self):
self.driver.quit()
def find_element_by_name(self,name):
return self.driver.find_element_by_name(name)
def find_elements_by_xpath(self,xpath): #貌似不能用/text
return self.driver.find_elements_by_xpath(xpath)
def find_element_by_id(self,id):
try:
return self.driver.find_element_by_id(id)
except:
return None
def input_words(self,element,words):
element.clear()
element.send_keys(str(words))
def click_by_id(self,id):
self.driver.find_element_by_id(id).click()
def send_file(self,element,path):
element.sendKeys(path);
def wait_element(self,element_id):
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.ID, element_id))
)
def get_title(self):
print(self.driver.title)
return self.driver.title
def refresh(self):
self.driver.refresh() #
def exec_js(self,js_script):
self.driver.execute_script(js_script)
cop = ChromeOperate(executable_path=r'chromedriver.exe',headless=False,mod='wx')
config_dict = {
'sfz':'33011111111111111', # 太長了
'csrq':u'1993-1-1',
'sjhm':'123456789',
'xm':u'張三',
'qt':'',
'xb':2,
'zz':u'杭州'
}
question = {
}
def getXpath(xpath, content, charset='utf8', xml_type='HTML'): # xpath操作貌似會把中文變成轉碼&#xxxx; /text()變unicode編碼
tree = etree.HTML(content)
out = []
results = tree.xpath(xpath)
for result in results:
if 'ElementStringResult' in str(type(result)) or 'ElementUnicodeResult' in str(type(result)):
out.append(result)
else:
out.append(etree.tostring(result, encoding=charset, method=xml_type)) # 加編碼就不會變成html編碼了
return out
def get_questions(page_buf):
# 解析 q1-q6 都是什么東西
# pdb.set_trace()
question_titles = getXpath('//div[@class="field-label"]',page_buf)
for n in range(1,len(question_titles)+1,1):
question_title = question_titles[n-1]
print question_title
if '身份證' in question_title:
question[n] = 'sfz'
elif '手機' in question_title or '聯系' in question_title or '電話' in question_title:
question[n] = 'sjhm'
elif '姓名' in question_title:
question[n] = 'xm'
elif '性別' in question_title:
question[n] = 'xb'
elif '生日' in question_title or '出生' in question_title:
question[n] = 'csrq'
elif '地址' in question_title or '住址' in question_title:
question[n] = 'zz'
else:
question[n] = 'qt'
if __name__=='__main__':
timestamp=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
print timestamp
#max_num = int(mainconf.get('conf', 'max_num'))
while True:
time.sleep(1)
if (datetime.datetime.now().hour>=13 and datetime.datetime.now().minute>=59) or (datetime.datetime.now().hour>=14): # 18點59開搶
break
while True:
cop.open('https://www.wjx.top/m/34952592.aspx')
try:
source = cop.open_source()
if '到時再重新打開' in source:
time.sleep(1)
continue # 檢測是否可以填寫
get_questions(source)
qn = len(question.keys())+1
for n in range(1,qn,1):
try:
qname = question[n]
print qname
if 'csrq'==qname:
cop.exec_js("var setDate=document.getElementById(\"q%s\");setDate.removeAttribute('readonly');"%n);
qvalue = config_dict.get(qname,'')
data_ele = cop.find_element_by_id('q%s'%n)
if data_ele:
data_ele.send_keys(qvalue)
elif 'xb' == qname:
button = cop.find_elements_by_xpath("http://div[@for='q%s_2']"%n)[0]
Action = TouchActions(cop.driver)
Action.tap(button)
Action.perform()
except Exception as e:
print str(e)
#pdb.set_trace()
# cop.click_by_id('ctlNext') # 為啥
time.sleep(0.5)
button = cop.find_element_by_id('ctlNext')
Action = TouchActions(cop.driver)
Action.tap(button)
Action.perform()
break
except Exception as e:
print str(e)
time.sleep(100)
time.sleep(6000) # 全流程重試間隔
# 據說不頻繁是不會出驗證碼的!
# 填不出來的用不詳?
# 選項不夠的情況下不要繼續點擊 ,暫停掉
# 系統時間核對
# 半自動思路 手動復制字段就可以在粘貼板里生成對應信息
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
