Python はアンケートのスターを自動的に記入します

Python はアンケートのスターを自動的に記入します

参考リンク1
参考リンク2

Pythonを使用してスマート認証とスライド認証によりアンケートを自動入力します

1. ブラウザドライバをダウンロードする

Python によるアンケートの自動入力はブラウザのドライバーに依存する必要がありますが、ここでは Google Chrome を使用するため、chromedriver をダウンロードする必要があり、ダウンロードしたバージョンはブラウザのバージョンと一致している必要があります。

  • まずはGoogle Chromeを開き、「ヘルプ」→「Google Chromeについて」をクリックし、ブラウザのバージョンを確認してください。図に示すように:

20230319172412

Google Chromeのバージョンが確認できます

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-aqQaduZ9-1679225429575)(null)]

バージョンを表示した後、リンク「CNPM Binaries Mirror」を開いて、対応するシステムの対応するバージョンの Google Chrome ドライバーをダウンロードします。図に示すように:

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-UHwdhigs-1679225429555)(null)]

ここではubuntuシステムを使用しているため、linuxバージョンをダウンロードしました(他のOSでも同様です)

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-XeZNta5z-1679225429521)(null)]

ダウンロードが完了したら、解凍
して実行権限を構成します。

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ことができます

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-qTSV0jhW-1679225434664)(null)]

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 をコピーします。

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-UZHTCgEw-1679225429594)(null)]

#点击提交
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()

おすすめ

転載: blog.csdn.net/weixin_48319333/article/details/129655031