Python はアンケートのスターを自動的に記入します
Pythonを使用してスマート認証とスライド認証によりアンケートを自動入力します
1. ブラウザドライバをダウンロードする
Python によるアンケートの自動入力はブラウザのドライバーに依存する必要がありますが、ここでは Google Chrome を使用するため、chromedriver をダウンロードする必要があり、ダウンロードしたバージョンはブラウザのバージョンと一致している必要があります。
- まずはGoogle Chromeを開き、「ヘルプ」→「Google Chromeについて」をクリックし、ブラウザのバージョンを確認してください。図に示すように:
Google Chromeのバージョンが確認できます
バージョンを表示した後、リンク「CNPM Binaries Mirror」を開いて、対応するシステムの対応するバージョンの Google Chrome ドライバーをダウンロードします。図に示すように:
ここではubuntuシステムを使用しているため、linuxバージョンをダウンロードしました(他のOSでも同様です)
ダウンロードが完了したら、解凍
して実行権限を構成します。
cd chromedriver_linux64
chmod +x chromedriver
次に、それをusr/bin
ディレクトリに移動します。
sudo mv chromedriver /usr/bin/
テスト
次にテストが実行されます。
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_opt = Options() # 创建参数设置对象.
chrome_opt.add_argument('--headless') # 无界面化.
chrome_opt.add_argument('--disable-gpu') # 配合上面的无界面化.
chrome_opt.add_argument('--window-size=1366,768') # 设置窗口大小, 窗口大小会有影响.
chrome_opt.add_argument("--no-sandbox") #使用沙盒模式运行
# 创建Chrome对象并传入设置信息.
browser = webdriver.Chrome(chrome_options=chrome_opt)
url = "https://www.baidu.com/"
browser.get(url)
print(browser.page_source)
browser.quit()
Baidu のホームページの HTML コードがインターフェースに入力されれば成功です。
2. Seleniumの基本構成
Selenium の本質は、実際のユーザーが操作しているかのように、ブラウザを駆動することでブラウザの動作を完全にシミュレートすることです。このツールの主な機能は次のとおりです。 ブラウザとの互換性をテストする - アプリケーションをテストして、さまざまなブラウザやオペレーティング システムで適切に動作するかどうかを確認します。システム機能のテスト - ソフトウェア機能とユーザー要件を検証するための回帰テストを作成します。
Selenium ライブラリは、端末コマンドを介してインストールできますpip install selenium
。
以下は一般的な Selenium の基本構成です。
import random # 用于产生随机数
import time # 用于延时
from selenium.webdriver.common.by import By #导入By包进行元素定位
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
#实例化一个启动参数对象
chrome_options = Options()
#添加启动参数
chrome_options.add_argument(
'user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"') # 添加请求头
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# 防止被识别
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) #设置开发者模式启动
chrome_options.add_experimental_option('useAutomationExtension', False) # 关闭selenium对chrome driver的自动控制
# chrome_options.maximize_window() # 网页最大化
#chrome_options.add_argument('headless') #设置浏览器以无界面方式运行
上記は、user-agent
ご使用のオペレーティング システムに応じて変更する必要があります。ここでは Linux システムを使用します。
この値は次のようにして取得できます。
Google Chrome を開き、Baidu Web ページを開き (他の Web ページでも問題ありません)、開発者モードを開き (F12 を押します)、Baidu Web ページ上のリンクをクリックし、Baidu ページに戻り、開発者モードを選択して、一番下までスライドしますNetwork
。以下で見るuser-agent
ことができます
3. 回答コード
- ドライバーを設定する
browser = webdriver.Chrome(options=chrome_options) #设置驱动程序,启动浏览器 (实现以特定参数启动)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'}) #用来执行Chrome开发这个工具命令
- アンケート内容を取得する
browser.get('https://www.***.**/**/*****.aspx') # 获取问卷信息(此处填问卷链接)
- 複数の選択肢
# 问题1的点击 (性别)
randomId = random.randint(1, 2) # 随机点击第一个选项或第二个选项
#js实现方式
js = "document.getElementById(\"q1_" + str(randomId) + "\").checked = true"
browser.execute_script(js) #使用js实现点击的效果(调用js方法,同时执行javascript脚本)
js = "document.getElementById(\"q1_" + str(randomId) + "\").click()"
browser.execute_script(js) #使用js实现点击的效果(调用js方法,同时执行javascript脚本)
# 延时 太快会被检测是脚本
time.sleep(1)
# 问题2 (年龄)
randomId = random.randint(2, 4) # 随机数,5个多选框 随机点击
# js实现方式
js = "document.getElementById(\"q2_" + str(randomId) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q2_" + str(randomId) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
- 複数の選択肢
# 问题5
randomId = random.randint(1, 3) # 随机数选择(选多少个)
for i in range(1, randomId + 1): # 循环 实现多选效果
randomId1 = random.randint(1, 6) #随机选择第1到第6个选项之一
# 两种js实现方式
js = "document.getElementById(\"q5_" + str(randomId1) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q5_" + str(randomId1) + "\").click()"
browser.execute_script(js)
# 延时
time.sleep(1)
- 空欄を埋める
# 问题25
#自定义要填的内容
block = ["定义第1个填空","定义第2个填空","定义第3个填空","定义第4个填空","定义第5个填空","定义第6个填空","无"]
#在上述内容中随机选择一个填入
randomId = random.randint(0, 5) #(数值下标从0开始)
#在题目中随机输入上述内容
browser.find_element_by_id("q25").send_keys(block[randomId])
# 延时
time.sleep(0.1)
4. 送信 + スマート検証 + スライダー検証
- 送信
まず、アンケートのソース コードを確認し、HTML コード内の送信ボタンの位置を見つけて、図に示すように「送信」ボタンの xpath をコピーします。
#点击提交
submit = browser.find_element_by_xpath("//*[@id='ctlNext']") #网页源代码的xpath
submit.click() #点击
#延时 太快会被检测是脚本
time.sleep(0.5)
- スマート検証
确认
同様に、智能验证提示框
HTML コード内の位置を見つけて、対応するボタンの xpath をコピーします (xpath は変更される可能性があります。次のコードが使用できない場合は、上記の方法を使用して新しい xpath をコピーし、ボタンの xpath を置き換えます) 。次のコード)
# 模拟点击智能验证按钮
# 先点确认
browser.find_element(By.XPATH,'//*[@id="layui-layer1"]/div[3]/a').click()
time.sleep(1)
# 再点智能验证提示框,进行智能验证
browser.find_element_by_xpath("//div[@id='captcha']").click()
- スライダーの検証
from selenium.webdriver import ActionChains
def get_track(distance): # distance为传入的总距离
# 移动轨迹
track = []
# 当前位移
current = 0
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
# 加速度
a = 100 + current*random.random()
v0 = v
# 当前速度
v = v0 + a * t
# 移动距离
# move = v0 * t + 1 / 2 * a * t * t
move = v0 * t + a * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
return track # track列表 返回的是整个滑动条的多个焦点,可以模拟鼠标的缓慢滑动
def move_to_gap(driver,slider, tracks): # slider是要移动的滑块,tracks是要传入的移动轨迹
ActionChains(driver).click_and_hold(slider).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.1)
ActionChains(driver).release().perform()
上記の get_track 関数は、軌跡リスト (移動軌跡を含む) を返し、現在の変位 current=0、時間間隔 t=0.2、および初速度 v=0 を定義し、現在の距離が距離より小さいかどうかを判断します。判定文で入力した値 合計距離が確定すると、加速度 a と速度 v という物理学の知識から変位を計算し、電流に加算します。
我改了一下原作者的代码,将加速度的大小随着current大小不规则变化,因为我发现固定加速度会使滑块验证多一个刷新重新验证,随机的加速度来滑动保证每次滑动都不太一样来防止检测出来
move_to_gap 関数
①ActionChains(ドライバー).click_and_hold(スライダー).perform()中
click_and_hold(slider)---点击鼠标左键,不松开,其中slider为需要定位要移动的滑块
(例如huakuai = driver.find_element_by_css_selector('#nc_1_n1z'))
perform()---执行该动作;
②次に線路を横断します
ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()中
move_by_offset(xoffset=x, yoffset=0)---鼠标向右移动x的px
③ActionChains(driver).release().perform()中
release()---释放
main関数で使用し、スマート検証の後ろに置き、最後にブラウザを閉じます
try:
huakuai = browser.find_element_by_css_selector('#nc_1_n1z')
move_to_gap(browser,huakuai, get_track(328))
time.sleep(2)
except:
pass
finally:
browser.quit() # 关闭浏览器
5. 完全なコード例
特定のアンケートはそれに応じて変更する必要があります
import random # 用于产生随机数
import time # 用于延时
from selenium.webdriver.common.by import By #导入By包进行元素定位
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ActionChains
#实例化一个启动参数对象
chrome_options = Options()
#添加启动参数
chrome_options.add_argument(
'user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"') # 添加请求头
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# 防止被识别
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) #设置开发者模式启动
chrome_options.add_experimental_option('useAutomationExtension', False) # 关闭selenium对chrome driver的自动控制
# chrome_options.maximize_window() # 网页最大化
#chrome_options.add_argument('headless') #设置浏览器以无界面方式运行
def get_track(distance): # distance为传入的总距离
# 移动轨迹
track = []
# 当前位移
current = 0
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
# 加速度
a = 100 + current*random.random()
v0 = v
# 当前速度
v = v0 + a * t
# 移动距离
# move = v0 * t + 1 / 2 * a * t * t
move = v0 * t + a * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
return track # track列表 返回的是整个滑动条的多个焦点,可以模拟鼠标的缓慢滑动
def move_to_gap(driver,slider, tracks): # slider是要移动的滑块,tracks是要传入的移动轨迹
ActionChains(driver).click_and_hold(slider).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.1)
ActionChains(driver).release().perform()
num = 120
man = int(num*0.06)
woman = num - man
for epoch in range(num):
browser = webdriver.Chrome(options=chrome_options) #设置驱动程序,启动浏览器 (实现以特定参数启动)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'}) #用来执行Chrome开发这个工具命令
browser.get('https://www.wjx.cn/xx/xxx.aspx') # 获取问卷信息(此处填问卷链接)
# 问题1的点击 (性别)
if man>0 and woman>0:
sex = random.randint(1, 2) # 随机点击第一个选项或第二个选项
if sex == 1:
man -= 1
else:
woman -= 1
elif man>0 and woman==0:
sex = 1
man -= 1
elif man==0 and woman>0:
sex = 2
woman -= 1
else:
break
#js实现方式
js = "document.getElementById(\"q1_" + str(sex) + "\").checked = true"
browser.execute_script(js) #使用js实现点击的效果(调用js方法,同时执行javascript脚本)
js = "document.getElementById(\"q1_" + str(sex) + "\").click()"
browser.execute_script(js) #使用js实现点击的效果(调用js方法,同时执行javascript脚本)
# 延时 太快会被检测是脚本
time.sleep(1)
# 问题2 (年龄)
if sex == 1:
seq = [2, 3]
weights = [0.7,0.3]
elif sex == 2:
seq = [1, 2, 3, 4, 5]
weights = [0.35,0.45,0.1,0.09,0.01]
age = random.choices(seq,weights)[0]
# js实现方式
js = "document.getElementById(\"q2_" + str(age) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q2_" + str(age) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
# 问题3 教龄
if age == 1:
teachyear = 1
elif age == 2:
teachyear = random.randint(1,2)
elif age == 3:
teachyear = random.randint(2,4)
elif age == 4:
teachyear = random.randint(3,4)
elif age == 5:
teachyear = 4
# js实现方式
js = "document.getElementById(\"q3_" + str(teachyear) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q3_" + str(teachyear) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
# 问题3 学历
if age == 1 or 2:
seq = [2,3,4]
weights = [0.4,0.5,0.1]
edu = random.choices(seq,weights)[0]
elif age == 3 or 4:
seq = [3, 4]
weights = [0.2,0.8]
edu = random.choices(seq,weights)[0]
elif age == 5:
edu = 4
# js实现方式
js = "document.getElementById(\"q4_" + str(edu) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q4_" + str(edu) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
# 问题3 婚育
if age == 1:
seq = [2,3]
weights = [0.15,0.85]
marry = random.choices(seq,weights)[0]
elif age == 2:
seq = [1,2,3]
weights = [0.4,0.35,0.25]
marry = random.choices(seq,weights)[0]
elif age == 3 or 4:
seq = [1,2,3]
weights = [0.9,0.09,0.01]
marry = random.choices(seq,weights)[0]
elif age == 5:
marry = 1
# js实现方式
js = "document.getElementById(\"q5_" + str(marry) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q5_" + str(marry) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
for i in range(6,32):
if i == 8:
if edu == 2:
seq = [2,3,4]
weights = [0.4,0.35,0.15]
else:
seq = [2,3,4,5]
weights = [0.1,0.25,0.4,0.25]
elif i == 21:
if teachyear in [3,4]:
seq = [2,3,4,5]
weights = [0.1,0.2,0.3,0.4]
elif teachyear == 2:
seq = [1,2,3,4,5]
weights = [0.1,0.2,0.5,0.2,0.1]
else:
seq = [1,2,3,4,5]
weights = [0.4,0.3,0.2,0.07,0.03]
elif teachyear in [3,4]:
seq = [1,2,3,4]
weights = [0.1,0.45,0.35,0.1]
elif teachyear == 2:
seq = [2,3,4,5]
weights = [0.1,0.35,0.45,0.1]
elif teachyear == 1:
seq = [3,4,5]
weights = [0.25,0.4,0.35]
pressure = random.choices(seq,weights)[0]
# js实现方式
js = "document.getElementById(\"q"+str(i)+"_" + str(pressure) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q"+str(i)+"_" + str(pressure) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
for i in range(32,42):
seq = [2,3,4,5]
weights = [0.05,0.15,0.5,0.3]
pressure = random.choices(seq,weights)[0]
# js实现方式
js = "document.getElementById(\"q"+str(i)+"_" + str(pressure) + "\").checked = true"
browser.execute_script(js)
js = "document.getElementById(\"q"+str(i)+"_" + str(pressure) + "\").click()" # 拼接字符串的方式 js找到对应id 点击按钮
browser.execute_script(js)
# 延时
time.sleep(0.1)
#点击提交
submit = browser.find_element_by_xpath("//*[@id='ctlNext']") #网页源代码的xpath
submit.click() #点击
#延时 太快会被检测是脚本
time.sleep(0.5)
# 模拟点击智能验证按钮
# 先点确认
browser.find_element(By.XPATH,'//*[@id="layui-layer1"]/div[3]/a').click()
time.sleep(1)
# 再点智能验证提示框,进行智能验证
browser.find_element_by_xpath("//div[@id='captcha']").click()
time.sleep(4)
try:
huakuai = browser.find_element_by_css_selector('#nc_1_n1z')
move_to_gap(browser,huakuai, get_track(328))
time.sleep(2)
except:
pass
finally:
print("No.{} Finished".format(epoch))
print("man has {}, woman has {}".format(man,woman))
browser.quit()