java操作selenium(二)-微博自动登录后回复

简单介绍下逻辑
步骤:
1.登录
先判断是否有cookie,有cookie直接登录,cookie失效使用账号密码登录,开始尝试登录,登录时会判断是否需要验证码(我用的是云打码平台,百度一下就知道了,这里就不做阐述,代码关于打码平台的没放出来,需要的去网上百度下)
2.回复 ps:这些id都是微博的,爬虫可以拿到
url就不用说了,我们肯定要到这个微博页面,自然需要微博的链接
content就是要回复的内容
comm_id和pid如果都为空,那就是对话题的回复
comm_id不为空,pid为空就是对以及评论的回复
comm_id和pid都不为空,就是对二级评论的回复,pid对应一级评论id
3.对话题的回复结果
成功,返回我们回复的这条评论的id
失败
无法回复(用户设置,不让评论)
对一级评论的回复结果
成功,返回我们回复的这条评论的id
失败
对二级评论的回复结果
成功,返回我们回复的这条评论的id
失败

 public static void main(String[] args) throws InterruptedException {
        try {
            SeleniumDriver instance = SeleniumDriver.getInstance();
            // String url = "https://weibo.com/6349791448/H6HN8vdb4?type=comment#_rnd1546914289648";
            String url = "https://weibo.com/1640016932/HaItFxbA1?ref=feedsdk&type=comment#_rnd1546917218511";
            String content = "ee";
            String comm_id = "4325613483241748";
            String pid = "4325542939353552";

     
            String res = instance.reply("https://weibo.com/1843911585/HaxHv0BXA?refer_flag=1001030103_&type=comment", content, null, null);
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

话不多说,上代码

import com.alibaba.fastjson.JSON;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadPoolExecutor;
import javax.imageio.ImageIO;
import com.lucky.tancms.tancms.util.ConstantUtil;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
import org.codehaus.plexus.util.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
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.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by rui on 2018/11/24.
 */
public class SeleniumDriver {

    private static final Logger logger = LoggerFactory.getLogger(SeleniumDriver.class);
    private static WebDriver driver = null;
    private int login_time = 0; // 登录次数

    private SeleniumDriver() {
        logger.info("初始化SeleniumDriver");
        System.setProperty("webdriver.chrome.driver","C:\\Users\\admin\\Downloads\\chromedriver.exe");
        try {
            /*Map<String, Object> contentSettings = new HashMap<String, Object>();
            contentSettings.put("images", 2);

            Map<String, Object> preferences = new HashMap<String, Object>();
            preferences.put("profile.default_content_setting_values", contentSettings);
            */
            ChromeOptions options = new ChromeOptions();
            //--headless
            options.addArguments("--test-type --no-sandbox --disable-dev-shm-usage --disable-gpu --disable-infobars");
            options.addArguments("--enable-strict-powerful-feature-restrictions");
            //options.setExperimentalOption("prefs", preferences);

            DesiredCapabilities caps = DesiredCapabilities.chrome();
            caps.setCapability(ChromeOptions.CAPABILITY, options);

            driver = new ChromeDriver(caps);
            driver.manage().window().maximize();

            login();
        } catch (Exception e) {
            logger.error("driver初始化失败" + e.toString() + "\n" + Arrays.toString(e.getStackTrace()));
            e.printStackTrace();
        }
    }

    private void login() throws Exception {
        logger.info("driver初始化完成,准备跳转到登录页面");
        driver.get("https://weibo.com/");
        // logger.info(MyLog.getInfo() + " 登录页面");
        Thread.sleep(15000);

        driver.manage().deleteAllCookies();
        // 1、通过cookie登录
        String path = SeleniumDriver.class.getResource("").getPath();
        String cookie_path = path + "cookies.txt";
        try {
            Map<String, String> cookies = loadCookies(cookie_path);

            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
                driver.manage().addCookie(new Cookie(cookie.getKey(), cookie.getValue()));
            }

            Thread.sleep(1000);
            driver.navigate().refresh();
            Thread.sleep(20000);

            // 2、判断通过cookie是否登录成功
            int loop_num = 0;
            while (loop_num < 3) {
                boolean login_status = getLoginStatus();

                if (login_status) {
                    break;
                } else {
                    // 等待5秒,再次判断
                    loop_num ++;
                    Thread.sleep(5000);
                }
            }
        } catch (Exception e) {
            System.out.println("加载cookie失败。。。");
        }

        boolean login_status = getLoginStatus();
        // 如果还未登录成功,则重新登录
        if (login_status) {
            return;
        } else {
            try {
                // 登录
                WebElement login_name = driver.findElement(By.xpath("//*[@id=\"loginname\"]"));
                JavascriptExecutor js = (JavascriptExecutor) driver;

                if (login_name != null) {
                    js.executeScript("arguments[0].click();", login_name);
                    js.executeScript("arguments[0].value = '';", login_name);

                    for (String str : "18911976770".split("")) {
                        js.executeScript("arguments[0].value +='" + str + "';", login_name);

                        Thread.sleep(600);
                    }
                }

                WebElement password = driver.findElement(By.xpath("//div[@node-type='normal_form']/div[@class='info_list password']"
                        + "/div[@class='input_wrap']/input[@type='password']"));
                if (password != null) {
                    js.executeScript("arguments[0].click();", password);
                    js.executeScript("arguments[0].value = '';", password);

                    // password.sendKeys("hht525252");
                    for (String str : "miao...123".split("")) {
                        js.executeScript("arguments[0].value +='" + str + "';", password);
                        Thread.sleep(600);
                    }
                }

                // 判断是否需要输入验证码
                try {
                    WebElement login_btn = driver.findElement(By.xpath("//div[@node-type='normal_form']/div[@class='info_list login_btn']/a[@node-type='submitBtn']"));
                    if (login_btn != null) {
                        js.executeScript("arguments[0].click();", login_btn);
                    }

                    Thread.sleep(3000);

                    WebElement verifycode_div = driver.findElement(By.xpath("//div[@node-type='verifycode_box']"));

                    if (verifycode_div.isDisplayed()) {
                        // 请求云打码平台,获得验证码
                        String captcha_path = path + "captcha.png";
                        String code = getVerifyCode(captcha_path);

                        WebElement verifycode_input = driver.findElement(By.xpath("//input[@name='verifycode']"));
                        for(String str : code.split("")) {
                            verifycode_input.sendKeys(str);
                            Thread.sleep(300);
                        }
                    } else {
                        System.out.println("***** 不需要输入验证码 *****");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("***** 不需要输入验证码 *****");
                }

                WebElement login_btn = driver.findElement(By.xpath("//div[@node-type='normal_form']/div[@class='info_list login_btn']/a[@node-type='submitBtn']"));
                if (login_btn != null) {
                    js.executeScript("arguments[0].click();", login_btn);
                }

                Thread.sleep(30000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 判断是否登录成功
            login_status = getLoginStatus();

            if (login_status) {
                // 保存cookie
                saveCookies(cookie_path);
            } else {
                if (login_time < 3) {
                    // 未登录成功,重新登录
                    login();
                } else {
                    throw new Exception(" ***** 登录失败 *****");
                }
            }
        }

        Thread.sleep(10000);
    }

	/**
     * 获得验证码
     * @return
     */
    private String getVerifyCode(String captchaPath) throws Exception {
        // 1、获得验证码图片
        File file = new File(captchaPath);
        if (file.exists()) {
            file.delete();
        }

        getCaptchaImage(captchaPath);
        // 2、请求,获得验证码
        String verifyCode = CYDM.getVerifyCode(captchaPath);

        return verifyCode;
    }

    private void getCaptchaImage(String fileName) throws Exception {
        // 1、获取验证码图片位置
        Map<String, Integer> pos = getVerifycodeImagePos();
        int top = pos.get("top").intValue();
        int left = pos.get("left").intValue();
        int height = pos.get("height").intValue();
        int width = pos.get("width").intValue();

        File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        BufferedImage screen_img = ImageIO.read(screen);
        BufferedImage captcha_img = screen_img.getSubimage(left, top, width, height);
        ImageIO.write(captcha_img, "png", screen);
        // 2、保存
        FileUtils.copyFile(screen, new File(fileName));
    }

	/**
     * 获得验证码图片位置
     * @return
     */
    private Map<String, Integer> getVerifycodeImagePos() throws Exception {
        try {
            WebElement verifycode_image = new WebDriverWait(driver, 10).until(new ExpectedCondition<WebElement>() {

                @Override
                public WebElement apply(@NullableDecl WebDriver webDriver) {
                    return webDriver.findElement(By.xpath("//img[@node-type='verifycode_image']"));
                }
            });

            int width = verifycode_image.getSize().getWidth();
            int height = verifycode_image.getSize().getHeight();

            // 得到元素坐标
            Point p = verifycode_image.getLocation();
            Map<String, Integer> map = new HashMap<>();
            map.put("top", p.getY());
            map.put("left", p.getX());
            map.put("height", height);
            map.put("width", width);

            return map;
        } catch (Exception e) {
            throw new Exception("***** 获取验证码图片失败 *****");
        }
    }

    /**
     * 加载cookie
     **/
    private Map<String, String> loadCookies(String path) throws Exception {
        File file = new File(path);
        if (!file.exists()) {
            throw new Exception("***** not found cookies file");
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
        Map<String, String> cookies = new HashMap<>();
        String content = null;

        while ((content = reader.readLine()) != null) {
            String[] cookie = content.split(";");

            for (String str : cookie) {
                String[] tmp = str.split(":");
                cookies.put(tmp[0], tmp[1]);
            }
        }

        reader.close();

        return cookies;
    }

    /**
     * 保存cookie
     **/
    private void saveCookies(String path) throws Exception {
        Set<Cookie> cookies = driver.manage().getCookies();
        StringBuilder data = new StringBuilder();

        for (Cookie cookie : cookies) {
            data.append(cookie.getName()).append(":").append(cookie.getValue()).append(";");
        }

        File file = new File(path);
        if (!file.exists()) {
            file.createNewFile();
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));
        writer.write(data.toString());
        writer.flush();
        writer.close();
    }

    /**
     * 获得登录状态
     **/
    private boolean getLoginStatus() {
        try {
            driver.findElement(By.xpath("//div[@class='gn_nav']/ul[@class='gn_nav_list']/li/a[@class='gn_name']"));

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public Cookie getCookie(String s) {
        Cookie cookie = null;
        Map<String, Object> map = JSON.parseObject(s, Map.class);
        String domain = map.get("domain").toString();
        Boolean httpOnly = Boolean.parseBoolean(map.get("httpOnly").toString());
        String name = map.get("name").toString();
        String path = map.get("path").toString();
        boolean secure = Boolean.parseBoolean(map.get("secure").toString());
        String value = map.get("value").toString();

        if (map.containsKey("expiry")) {
            String expiry = map.get("expiry").toString();
            cookie = new Cookie(name, value, domain, path, null, secure, httpOnly);
        } else {
            cookie = new Cookie(name, value, domain, path, null, secure, httpOnly);
        }
        return cookie;
    }

    private static class SeleniumDriverHolder {
        public static final SeleniumDriver SELENIUM_DRIVER = new SeleniumDriver();
    }

    public static SeleniumDriver getInstance() {
        return SeleniumDriverHolder.SELENIUM_DRIVER;
    }

    public WebDriver getDriver() {
        return driver;
    }

    public String reply(String url, String replyCont, String comm_id, String pid) throws Exception {
        WebDriver driver = SeleniumDriver.getInstance().getDriver();
        driver.get(url);

        boolean is_logined = getLoginStatus();

        if (!is_logined) {
            System.out.println("***** 未登录 *****");
            try {
                login();
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
        }

        Thread.sleep(7000);
        JavascriptExecutor js = (JavascriptExecutor) driver;
        try {

            List<WebElement> comment_list = driver
                    .findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));

            if ("-1".equals(pid)) { // 一级评论
                String first_comment_id = null;
                if (comment_list.size() > 0) {
                    first_comment_id = comment_list.get(0).getAttribute("comment_id");
                }
                int parsed_num = 0;
                // int total_num = 0;

                while (true) {
                    // total_num += comment_list.size();

                    for (WebElement commDiv : comment_list) {
                        try {
                            String comment_id = commDiv.getAttribute("comment_id");
                            parsed_num ++;
                            js.executeScript("arguments[0].scrollIntoView();", commDiv);

                            if (comm_id.equals(comment_id)) {
                                // 找到相应的div,点击回复,输入内容
                                WebElement replay_span = commDiv.findElement(By.xpath(".//a[@action-type='reply']"));
                                js.executeScript("arguments[0].click();", replay_span);
                                Thread.sleep(500);
                                WebElement textarea = commDiv.findElement(By.xpath(".//textarea[@node-type='textEl']"));
                                textarea.sendKeys(replyCont);
                                Thread.sleep(800);

                                // 提交
                                WebElement do_reply = commDiv.findElement(By.xpath(".//a[@action-type='doReply']"));
                                js.executeScript("arguments[0].click();", do_reply);
                                Thread.sleep(500);

                                // 获得评论id
                                // String comm_id = null;
                                // List<WebElement> list_box = commDiv.findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));
                                List<WebElement> list_box = commDiv.findElements(By.xpath(".//div[@class='list_box_in S_bg3']/div[@class='list_ul']/div"));
                                if (list_box.size() > 0) {
                                    String new_comm_id = list_box.get(0).getAttribute("comment_id");

                                    if (first_comment_id.equals(new_comm_id)) {
                                        // 相同,则评论失败
                                        System.out.println("***** 评论失败");
                                    } else {
                                        return new_comm_id;
                                    }
                                } else {
                                    return null;
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    comment_list.clear();
                    Thread.sleep(3000);
                    comment_list = driver
                            .findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));

                    if (comment_list.size() - parsed_num > 1) {
                        comment_list = comment_list.subList(parsed_num - 1, comment_list.size() - 1);
                        continue;
                    } else {
                        // 查看更多
                        try {
                            WebElement more_comment = driver.findElement(By.xpath(".//a[@action-type='click_more_comment']"));
                            ((JavascriptExecutor) driver).executeScript("arguments[0].click();", more_comment);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        Thread.sleep(5000);

                        comment_list = driver
                                .findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));

                        if (comment_list.size() - parsed_num > 1) {
                            comment_list = comment_list.subList(parsed_num - 1, comment_list.size() - 1);
                            continue;
                        } else {
                            break;
                        }
                    }
                }

            } else if (pid != null){    // 二级评论
                int parsed_num = 0;

                while (true) {

                    for (WebElement commDiv : comment_list) {
                        try {
                            String comment_id = commDiv.getAttribute("comment_id");
                            parsed_num ++;
                            js.executeScript("arguments[0].scrollIntoView();", commDiv);

                            if (pid.equals(comment_id)) {
                                // 找到相应的评论,再找其二级评论
                                Thread.sleep(2000);
                                while (true) {
                                    try {
                                        WebElement child_more_comment = commDiv.findElement(By.xpath(".//div[@node-type='more_child_comment']/div[@class='WB_text']/a[@action-type='click_more_child_comment_big']"));
                                        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", child_more_comment);
                                        Thread.sleep(2000);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        break;
                                    }
                                }

                                List<WebElement> child_comments = commDiv.findElements(By.xpath(".//div[@node-type='child_comment']"));
                                child_comments = child_comments.get(1).findElements(By.xpath("./div"));
                                for (WebElement childCommDiv : child_comments) {
                                    try {
                                        String child_comment_id = childCommDiv.getAttribute("comment_id");
                                        js.executeScript("arguments[0].scrollIntoView();", childCommDiv);

                                        if (comm_id.equals(child_comment_id)) {
                                            // 找到相应的评论,点击“回复”,输入回复内容,提交
                                            WebElement reply_a = childCommDiv
                                                    .findElement(By.xpath(".//a[@action-type='reply']"));
                                            js.executeScript("arguments[0].click();", reply_a);
                                            Thread.sleep(1000);
                                            WebElement textarea = childCommDiv
                                                    .findElement(By.xpath(".//textarea[@node-type='textEl']"));
                                            textarea.sendKeys(replyCont);
                                            Thread.sleep(800);

                                            WebElement reply_btn = childCommDiv.findElement(By.xpath(".//a[@action-type='doReply']"));
                                            js.executeScript("arguments[0].click();", reply_btn);
                                            Thread.sleep(2000);

                                            // 获得comment_id
                                            // String comm_id = null;
                                            List<WebElement> list_box = commDiv
                                                    .findElements(By.xpath(".//div[@class='list_box_in S_bg3']"));

                                            if (list_box.size() > 1) {
                                                // 评论成功,有两个“list_box_in S_bg3”div
                                                // 取第一个,即为刚刚增加的评论
                                                WebElement new_comm = list_box.get(0);

                                                WebElement new_comm_div = new_comm.findElement(By.xpath(
                                                        ".//div[@node-type='child_comment']/div[@class='list_li S_line1 clearfix']"));
                                                comm_id = new_comm_div.getAttribute("comment_id");

                                                return comm_id;
                                            } else {
                                                // 评论失败
                                                System.out.println("评论失败");
                                                return null;
                                            }
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        System.out.println("对二级评论回复失败");
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println(String.format("对评论()回复失败"));
                        }
                    }

                    comment_list.clear();
                    Thread.sleep(3000);
                    comment_list = driver
                            .findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));

                    if (comment_list.size() - parsed_num > 1) {
                        comment_list = comment_list.subList(parsed_num - 1, comment_list.size() - 1);

                        continue;
                    } else {

                        try {
                            // 查看是否有“查看更多”
                            WebElement more_comment = driver.findElement(By.xpath(".//a[@action-type='click_more_comment']"));

                            ((JavascriptExecutor) driver).executeScript("arguments[0].click();", more_comment);
                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println("***** 没有更多 *****");
                        }
                        Thread.sleep(5000);

                        comment_list = driver
                                .findElements(By.xpath(".//div[@class='list_box']/div[@node-type='comment_list']/div"));

                        if (comment_list.size() - parsed_num > 1) {
                            comment_list = comment_list.subList(parsed_num - 1, comment_list.size() - 1);
                            continue;
                        } else {
                            break;
                        }
                    }
                }


            } else {

                try{
                    WebElement comm_div = driver.findElement(By.xpath("//div[@class=\"WB_feed_publish clearfix\"]"));

                    Thread.sleep(1000);
                    logger.info("获取定位的唯一div");
                    WebElement reply = comm_div.findElement(By.xpath(".//*/textarea[@node-type=\"textEl\"]"));
                    js.executeScript("arguments[0].click();", reply);
                    logger.info("获取输入框并点击");
                    Thread.sleep(1000);
                    js.executeScript("arguments[0].value='" + replyCont.replaceAll("'", "\\'") + "';", reply);
                    Thread.sleep(1000);
                    logger.info("输入内容");
                    WebElement submit = comm_div.findElement(By.xpath(".//*/a[@class=\"W_btn_a\"]"));
                    js.executeScript("arguments[0].click();", submit);
                    logger.info("提交");
                    Thread.sleep(15000);
                    return "";

                }catch (Exception e){
                    e.printStackTrace();
                    logger.error(MyLog.getInfo() + "  " + e.toString() + "  回复失败  url:" + url + "  内容:" + replyCont + "\n" + Arrays.toString(e.getStackTrace()));
                    try {
                        Thread.sleep(3000);
                        driver.findElement(By.xpath("//span[@class=\"W_icon icon_rederrorS\"]"));
                        logger.error("无法回复");
                        return "error";
                    } catch (Exception e1) {
                    }
                    return null;
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            try {
                Thread.sleep(3000);
                driver.findElement(By.xpath("//span[@class=\"W_icon icon_rederrorS\"]"));
                logger.error("无法回复");
                return "error";
            } catch (Exception e1) {
            }
            return null;
        }

        return null;
    }



    public void quik() throws InterruptedException {
        Thread.sleep(1000);
        driver.quit();
        logger.info("关闭浏览器");
    }

    public static void main(String[] args) throws InterruptedException {
        try {
            SeleniumDriver instance = SeleniumDriver.getInstance();
            // String url = "https://weibo.com/6349791448/H6HN8vdb4?type=comment#_rnd1546914289648";
            String url = "https://weibo.com/1640016932/HaItFxbA1?ref=feedsdk&type=comment#_rnd1546917218511";
            String content = "ee";
            String comm_id = "4325613483241748";
            String pid = "4325542939353552";

       
            String res = instance.reply("https://weibo.com/1843911585/HaxHv0BXA?refer_flag=1001030103_&type=comment", content, null, null);
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orange大数据技术探索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值