本方法通过,selenium自动化框架,模拟真人操作实现,无调用次数限制,很适合批量生成数据。
package selenium;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.List;
/**
* 文心一言问答
*/
public class WenXinYiYan {
static String chromeIp = "127.0.0.1";
static int chromePort = 9222;
static String chromePath = "C://Program Files//Google//Chrome//Application//chrome.exe";
WebDriver driver = null;
public static void main(String[] args) {
WenXinYiYan wxyy = new WenXinYiYan();
try{
wxyy.init();
// wxyy.initWithAddr("127.0.0.1",9221);
System.out.println(wxyy.askQuestion("你好"));
}catch (Exception e){
e.printStackTrace();
}finally {
if (wxyy.driver != null){
wxyy.driver.close();
}
}
}
public void initWithAddr(String host,int chromePort) throws IOException {
//如果浏览器未启动,则启动
if (!severIsRunning(chromeIp,chromePort,2000)){
//debug模拟式启动浏览器
String cmd = chromePath + " --remote-debugging-port=" + chromePort +" --user-data-dir=\"D:\\selenium\\ChromeProfile"+chromePort;
Runtime.getRuntime().exec(cmd);
}
// 设置ChromeDriver的路径
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver.exe");
// 通过debug端口连接已打开的浏览器实例
ChromeOptions option = new ChromeOptions();
option.setExperimentalOption("debuggerAddress", chromeIp+":"+chromePort);
driver = new ChromeDriver(option);
// 打开问心一言
if (driver.getCurrentUrl() == null || !driver.getCurrentUrl().contains("yiyan.baidu.com")){
driver.get("https://yiyan.baidu.com");
// 创建一个自定义的ExpectedCondition来等待页面完全加载
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
// 使用WebDriverWait等待页面完全加载
WebDriverWait wait = new WebDriverWait(driver, 30); // 等待时间设置为30秒
wait.until(pageLoadCondition);
sleep(1000);
}
//通过登录按钮判断是否已登录
List<WebElement> loginElements = driver.findElements(By.cssSelector("div.lpzMgwiN"));
if (loginElements.size() > 0){
throw new RuntimeException("###############登录文心一言后,重新运行####################");
}
}
public void init() throws IOException {
initWithAddr(chromeIp,chromePort);
}
/**
* 提问并返回答案
* @param question
* @return
*/
public String askQuestion(String question){
//填写问题
WebElement element = driver.findElement(By.cssSelector("p.yc-editor-paragraph"));
element.clear();
element.sendKeys(question);
//提问执行
WebElement sendBtn = driver.findElement(By.id("sendBtn"));
sendBtn.click();
//等待问题回答结束
sleep(5000);
sendBtn = driver.findElement(By.id("sendBtn"));
while(!sendBtn.isDisplayed()){
sleep(1000);
sendBtn = driver.findElement(By.id("sendBtn"));
}
//获取答案列表
List<WebElement> answerList = driver.findElements(By.id("answer_text_id"));
//返回刚提问返回的答案
return answerList.get(0).getText();
}
private void sleep(long time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* 服务端口是否已启动
* @param host 服务地址
* @param port 服务端口
* @param timeout 超时时间
* @return
*/
private boolean severIsRunning(String host,int port,int timeout){
try (Socket socket = new Socket()) {
SocketAddress socketAddress = new InetSocketAddress(host, port);
// 设置连接超时
socket.connect(socketAddress, timeout);
System.out.println("浏览器已启动");
socket.close();
return true;
} catch (IOException e) {
System.out.println("浏览器未启动");
return false;
}
}
}