概要
基于spring boot,selenium的问卷星自动化脚本,安装即用。可以参考我的部署网站autoq13.top
项目支持需要:
jdk版本:17
chrome
chromedriver
官网下载地址:https://googlechromelabs.github.io/chrome-for-testing/(下载不了私信我)
项目gitee地址:https://gitee.com/tkf111/auto-survey-filler
整体框架
技术细节
ip代理配置
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
public class ProxyConfig {
// 代理服务器配置
private String proxyHost;
private int proxyPort;
private long lastUpdateTime; // 记录代理更新时间
// 预热配置
@Value("${proxy.warmup.timeout:30000}")
private int warmupTimeout; // 预热超时时间,默认30秒
@Value("${proxy.warmup.test-urls:https://www.wjx.cn/vm/examle.aspx}") // 默认问卷星URL,使用ip代理时候换成你的
private String[] warmupTestUrls; // 预热测试URL列表,默认为问卷星URL
@Value("${proxy.max-use-time:1800000}")
private long maxUseTime; // 代理最大使用时间,默认30分钟
@Value("${proxy.retry-count:3}")
private int maxRetryCount; // 最大重试次数
@Value("${proxy.retry-interval:2000}")
private long retryInterval; // 重试间隔时间(ms)
}
这里需要修改测试链接,就是你要填写的问卷星链接,使用ip代理时候会测试是否能够成功访问这个链接
private String fetchProxyFromApi() {
try {
String apiUrl = "http://v2.api.juliangip.com/company/postpay/getips?auto_white=1&num=1&pt=1&result_type=text&split=1&trade_no=6652588192186751&sign=548a4dd56afe2dd53e4c3a6997e22863"; // 这里填写API地址
if (apiUrl == null) {
log.error("代理API URL未配置");
return null;
}
log.info("开始请求代理API,URL: {}", apiUrl);
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int responseCode = conn.getResponseCode();
log.info("代理API响应码: {}", responseCode);
if (responseCode != HttpURLConnection.HTTP_OK) {
log.error("代理API请求失败,响应码: {}", responseCode);
return null;
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String response = reader.readLine();
log.info("成功获取代理响应: {}", response);
return response;
}
} catch (Exception e) {
log.error("请求代理API失败:{}", e.getMessage());
return null;
}
}
这里修改String apiUrl =""为你的api代理地址
浏览器以及端口配置
webdriver:
cache:
path: ./drivers
chrome:
binary: ${WEBDRIVER_CHROME_BINARY:D:\\plug\\chrome\\chrome-win64 (1)\\chrome-win64\\chrome.exe}
driver: ${WEBDRIVER_CHROME_DRIVER:D:\\plug\\chrome\\chromedriver-win64 (1)\\chromedriver-win64\\chromedriver.exe}
server:
port: 8080
这里需要修改成你自己的路径,注意不要有中文,chrome和driver版本要一致,官网地址https://googlechromelabs.github.io/chrome-for-testing/,端口随意
题型适配
import com.example.wenmini.entity.QuestionnaireFillRequest;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@Service
@Slf4j
public class QuestionChoice {
private static final Random random = new Random();
private static final int WAIT_TIMEOUT = 10;
// 单选题
public void handleSingleChoice(WebElement question, QuestionnaireFillRequest.QuestionConfigDto config, Long taskId) {
List<WebElement> options = question.findElements(By.cssSelector(".ui-radio"));
if (options.isEmpty() || config.getOptions() == null || config.getOptions().isEmpty()) {
return;
}
int selectedIndex = getRandomIndexByPercentage(config.getOptions());
if (selectedIndex >= 0 && selectedIndex < options.size()) {
options.get(selectedIndex).click();
log.info("单选题选择了第{}个选项", selectedIndex + 1);
}
}
......
}
目前只适配了单选题,多选题,文本题,有需要可以在这里继续添加。
错误处理,填写调试
/**
* 创建新的WebDriver实例
*/
public WebDriver createWebDriver(boolean useProxy) {
try {
log.info("开始创建WebDriver实例...");
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
ChromeOptions options = new ChromeOptions();
// 设置Chrome二进制文件路径
if (chromeBinaryPath != null && !chromeBinaryPath.isEmpty()) {
options.setBinary(chromeBinaryPath);
}
// 配置代理
if (useProxy) {
configureProxy(options);
}
// 设置无头模式
options.addArguments("--headless=new");
// 配置浏览器首选项
configureBrowserPreferences(options);
// 添加Chrome启动参数
addChromeArguments(options);
// 设置随机User-Agent
options.addArguments("--user-agent=" + fingerprintGenerator.generateUserAgent());
// 创建WebDriver实例
WebDriver driver = new ChromeDriver(options);
// 配置超时设置
configureTimeouts(driver);
// 注入动态指纹
injectFingerprint(driver);
log.info("WebDriver实例创建成功");
return driver;
} catch (Exception e) {
log.error("创建WebDriver实例失败:{}", e.getMessage());
throw new RuntimeException("创建WebDriver实例失败", e);
}
}
有需要调试的话可以注释掉DriverService中的无头模式(默认开启,启动程序后不会弹出chrome,而是在后台运行,看不到填写细节,出现错误时候可以关闭无头模式,追踪填写过程)