Java Selenium模拟某电商登录获取豆豆信息+JUnit单元测试

本来想用Python模拟请求,但是!!经过抓包分析,它的请求里面有两个参数eid和fp是用javaScript动态生成的。顺藤摸瓜,找到javaScript代码,结果!!我看不懂……不仅看不懂,人家是专门做了混淆的…算了,就酱吧,还是乖乖用Selenium操作。

JDLogin:

  1. 登录(有人说登录次数多了会弹验证码,不过我从logout页面登录进去,多次,也没有弹验证码)
  2. 到达我的豆豆页面
  3. 抓取豆豆信息(总数+近三个月的明细),抓明细的时候,页面上有做分页,老老实实挨个分页button点过去
  4. 获取到的明细信息处理:隐去商品号…

时间着实有限,所以只拿了自己的帐号(有多页豆豆明细数据的)和一个空白帐号(豆豆数量为0,没有豆豆交易明细数据)做测试,结果都是通过的。如下所示:
Java Selenium模拟某电商登录获取豆豆信息+JUnit单元测试_第1张图片
Java Selenium模拟某电商登录获取豆豆信息+JUnit单元测试_第2张图片

JDLoginTest:

  1. 登陆之后判断是否登录成功(页面是否包含”我的**”字符串)
  2. 到达豆豆页面,要判断是否包含”可用*豆”字符串
  3. 抓完豆豆明细数据,判断三个list长度是否相等,正常情况下应该相等(每一条豆豆明细数据包含:日期,增加或减少多少豆豆,交易名称)

JDLogin Code:

package pkg_JDLogin;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import java.util.List;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

/**
 * Created by Sophie on 03/20/2016
 */

public class JDLogin {
     
    private WebDriver dr;
    private String url;
    private String account;
    private String pwd;
    private String myJDXPATH;
    private String myBeanXPATH;
    private String datesXPATH;
    private String transacDetailsXPATH;
    private String transacNameXPATH;
    private String pageNextXPATH;
    private String total;
    private List dateDetail;
    private List transacDetail;
    private List transacName;

    public List retrieveJDBeanDatesDetails(){
        return dateDetail;
    }

    public List retrieveJDBeanTransacDetail(){
        return transacDetail;
    }

    public List retrieveJDBeanTransacName(){
        return transacName;
    }

    public JDLogin(String url, String account, String pwd,String myJDXPATH, String myBeanXPATH,
                   String datesXPATH, String transacDetailsXPATH, String transacNameXPATH, String pageNextXPATH){
        this.url = url;
        this.dr = new FirefoxDriver();
        this.dr.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        this.account = account;
        this.pwd = pwd;
        this.myJDXPATH = myJDXPATH;
        this.myBeanXPATH = myBeanXPATH;
        this.datesXPATH = datesXPATH;
        this.transacDetailsXPATH = transacDetailsXPATH;
        this.transacNameXPATH = transacNameXPATH;
        this.pageNextXPATH = pageNextXPATH;
    }

    public WebDriver login() throws Exception{
        dr.get(url);
        dr.findElement(By.id("loginname")).clear();
        dr.findElement(By.id("loginname")).sendKeys(account);
        dr.findElement(By.id("nloginpwd")).clear();
        dr.findElement(By.id("nloginpwd")).sendKeys(pwd);
        dr.findElement(By.id("loginsubmit")).click();
        //System.out.println(dr.getPageSource());
        Thread.sleep(2000);
        return dr;
    }

    public WebDriver JDBeanPage(){
        WebElement dropDown = dr.findElement(By.xpath(myJDXPATH));
        Actions act = new Actions(dr);
        act.click(dropDown).perform();
        dr.get(dr.findElement(By.xpath(myBeanXPATH)).getAttribute("href"));
        return dr;
    }

    public List getDatesDetail(WebDriver dr){
        List e = dr.findElements(By.xpath(datesXPATH));
        List result = new ArrayList();
        for (int i = 0; i < e.size(); i ++){
            result.add(e.get(i).getText());
        }

        return result;
    }

    public List getTransacDetail(WebDriver dr){
        List e = dr.findElements(By.xpath(transacDetailsXPATH));
        List result = new ArrayList();
        for (int i = 0; i < e.size(); i ++){
            result.add(e.get(i).getText());
        }

        return result;
    }

    public List getTransacName(WebDriver dr){
        List e = dr.findElements(By.xpath(transacNameXPATH));
        List result = new ArrayList();
        for (int i = 0; i < e.size(); i ++){
            result.add(e.get(i).getText());
        }

        return result;
    }

    public void getJDBeanDetails(){

        total = dr.findElement(By.cssSelector("strong.ftx01.num")).getText();

        //dates that have transactions
        dateDetail = getDatesDetail(dr);
        //gain or lost JDBean
        transacDetail = getTransacDetail(dr);
        //name of transac
        transacName = getTransacName(dr);

        Actions act = new Actions(dr);

        //get pages size
        List pageHref = dr.findElements(By.xpath("//div[@class='pagin fr']/a[not(@class) and @href]"));
        if(pageHref.size() != 0) {
    //该用户京豆交易明细至多只有一页的情况
            act.moveToElement(pageHref.get(0));
            act.click().perform();
        }
        //System.out.print(dr.getPageSource());

        for (int i = 1; i < pageHref.size(); i ++) {
            WebElement pageIcon = dr.findElement(By.xpath(pageNextXPATH));
            act.moveToElement(pageIcon);
            act.click().perform();

            //date
            dateDetail.addAll(getDatesDetail(dr));

            //gain or lost
            transacDetail.addAll(getTransacDetail(dr));

            //name of transac
            transacName.addAll(getTransacName(dr));

        }

        maskItemNumber(transacName);

        System.out.println("共有京豆:" + total + ",明细如下:\n==============================================================================");

        for(int i = 0; i < transacName.size(); i ++){
            System.out.println(dateDetail.get(i)+"\t\t\t\t\t\t"+transacDetail.get(i)+"\t\t\t\t\t\t"+transacName.get(i));
        }
    }

    public void maskItemNumber(List transacName){
        StringBuffer s ;
        for (int i = 0; i < transacName.size(); i ++){
            if(transacName.get(i).toString().contains("商品")){
                s = new StringBuffer(transacName.get(i).toString());
                for(int j = 0; j < s.length(); j ++){
                    if (Character.isDigit(s.charAt(j)))
                        s.setCharAt(j,'*');
                }
                transacName.set(i,s.toString());
            }
        }
    }


    public void tearDown() throws Exception{
        dr.quit();
    }

    public static void main(String[] args) throws Exception {
        String url = "https://passport.jd.com/uc/login?ltype=logout";

        Scanner s = new Scanner(System.in);
        System.out.println("请输入帐号:");
        String account = s.nextLine();

        System.out.println("请输入密码:");
        String pwd = s.nextLine();

        String myJDXPATH = "//li[@id='ttbar-myjd']/div[1]/i[@class='ci-right']/s";
        String myBeanXPATH = "//li[@id='ttbar-myjd']/div[2]/div[@class='otherlist']/div[@class='fore2']/div[2]/a";
        String datesXPATH = "//span[@class='ftx03']";
        String transacDetailsXPATH = "//table[@class='tb-void']/tbody/tr/td[2]/span";
        String transacNameXPATH = "//table[@class='tb-void']/tbody/tr/td[3]";
        String pageNextXPATH = "//div[@class='pagin fr']/a[@class='current']/following-sibling::a[1]";
        JDLogin jd = new JDLogin(url,  account,  pwd, myJDXPATH,  myBeanXPATH, datesXPATH,  transacDetailsXPATH,  transacNameXPATH,  pageNextXPATH);
        jd.login();
        jd.JDBeanPage();
        jd.getJDBeanDetails();
        jd.tearDown();
    }
}

JUnit测试代码:

package pkg_JDLogin;

import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import static  org.junit.Assert.*;
import java.util.Scanner;
import static org.hamcrest.Matchers.*;
import java.util.List;
/**
 * Created by Sophie on 16/3/20.
 */
public class JDLoginTest {
     
    private JDLogin jd;
    private WebDriver dr;

    @Before
    public void setUpBefore(){
        String url = "https://passport.jd.com/uc/login?ltype=logout";

        //Scanner s = new Scanner(System.in);
        //System.out.println("请输入帐号:");
        String pwd = "***";

        //System.out.println("请输入密码:");
        String account = "***";

        String myJDXPATH = "//li[@id='ttbar-myjd']/div[1]/i[@class='ci-right']/s";
        String myBeanXPATH = "//li[@id='ttbar-myjd']/div[2]/div[@class='otherlist']/div[@class='fore2']/div[2]/a";
        String datesXPATH = "//span[@class='ftx03']";
        String transacDetailsXPATH = "//table[@class='tb-void']/tbody/tr/td[2]/span";
        String transacNameXPATH = "//table[@class='tb-void']/tbody/tr/td[3]";
        String pageNextXPATH = "//div[@class='pagin fr']/a[@class='current']/following-sibling::a[1]";
        jd = new JDLogin(url,  account,  pwd, myJDXPATH,  myBeanXPATH, datesXPATH,  transacDetailsXPATH,  transacNameXPATH,  pageNextXPATH);
        }

    @Test
    public void test() throws Exception {

        //login
        dr = jd.login();
        org.junit.Assert.assertThat( dr.getPageSource(),containsString("我的京东"));

        //JD bean page
        dr = jd.JDBeanPage();
        org.junit.Assert.assertThat(dr.getPageSource(), containsString("可用京豆"));

        //JD bean details
        jd.getJDBeanDetails();

        List dates= jd.retrieveJDBeanDatesDetails();
        List transacDetails = jd.retrieveJDBeanTransacDetail();
        List transacName = jd.retrieveJDBeanTransacName();

        //System.out.println("Dates Size: "+dates.size() + "TransacName Size: "+ transacName.size() + "Transac Details Size: "+ transacDetails.size() );

        org.junit.Assert.assertEquals("抓取京豆明细异常:数据条数不匹配", dates.size(),transacDetails.size());
        org.junit.Assert.assertEquals("抓取京豆明细异常:数据条数不匹配", dates.size(),transacName.size());

        for(int i = 0; i < transacName.size(); i ++){
            for (int j = 0; j < transacName.get(i).length(); j ++){
                org.junit.Assert.assertFalse("敏感信息未隐藏: 第 " + i+1 + "条数据", Character.isDigit(transacName.get(i).charAt(j)));
            }
        }

    }

    @After
    public void testTearDown() throws Exception {
        jd.tearDown();
    }
}

你可能感兴趣的:(java,selenium,JUnit)