1.1 官网下载安卓SDK(根据自己的需求下载)
1.2 新建 ANDROID_HOME 环境变量,变量值是SDK解压的路径,我的是:D:\Program Files\android-sdk_r24.4.1-windows\android-sdk-windows
1.3 增加PATH变量路径:
1) tools目录:%ANDROID_HOME%\tools
2) platform-tools目录:%ANDROID_HOME%\platform-tools
安装Tools 文件夹下Android SDK Platform-tools 、Android SDK Build-tools和Android SDK Tools,Extras文件夹下的 Google USB Driver
点击“Install 4 Packages…”—>选择Accept License—>点击 “Install” 开始安装。确定更新
安装appium
1 在cmd 输入 npm install -g appium-doctor 安装appium-doctor 输入appium-doctor 检测是否安装成功
2 官网安装Appium
3 Host 是本机IP 127.0.0.1
方法一 如果不知道appPackage
启动app 输入dumpsys window| grep mCurrentFocus
2 手机配置
因为用的是小米手机 所有拿小米手机举例子
1 在小米手机的开发者选项中选择如下图这三个选项(如果不知道开发者选项的自行百度)
2:连接数据线 选择下图这个按钮
下面小米8配置为打开手机的Appium的配置
{
“deviceName”: “Android Emulator”,
“platformName”: “Android”,
“platformVersion”: “10”,
“appPackage”: “com.miui.home”,
“appActivity”: “com.miui.home.launcher.Launcher”,
“noReset”: “true”,
“recreateChromeDriverSessions”: “true”,
“browserName”: “”
}
下面红米k20 pro配置为打开手机的Appium的配置
{
“deviceName”: “Android Emulator”,
“platformName”: “Android”,
“platformVersion”: “11”,
“appPackage”: “com.miui.home”,
“appActivity”: “com.miui.home.launcher.Launcher”,
“noReset”: “true”,
“recreateChromeDriverSessions”: “true”,
“browserName”: “”
}
导入的jar包
<dependencies>
<dependency>
<groupId>io.appiumgroupId>
<artifactId>java-clientartifactId>
<version>4.1.2version>
<exclusions>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
exclusion>
<exclusion>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
<version>22.0version>
dependency>
dependencies>
代码演示
获取闲鱼优惠价演示
package cn.1.crawler.service.impl;
import cn.1.crawler.common.util.ConfigUtils;
import cn.1.crawler.dao.XianyuDataMapper;
import cn.1.crawler.entry.XianYuDateDto;
import cn.1.crawler.entry.XianyuDto;
import cn.1.crawler.operation.BaseOperation;
import cn.1.crawler.service.XianyuCouponsInfoService;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class XianyuCouponsInfoServiceImpl extends BaseOperation implements XianyuCouponsInfoService {
private static List<XianyuDto> xianyuDtoList = new ArrayList<>();
private static AndroidDriver driver;
private static List<XianYuDateDto> xianYuDateDtoList = new ArrayList<>();
private static int endFlag;
private static final String DEFALUT_PROPERTIE_PATH="config/defalutFilePathConfig.properties";
private static Properties properties = ConfigUtils.configProperties(DEFALUT_PROPERTIE_PATH);
private static String url = properties.getProperty("url");
private static String udid = properties.getProperty("udid");
private static String reg = "([\\s\\S]*)\\n(\\d*\\u4eba\\u4ed8?\\u6b3e?\\u60f3?\\u8981?)\\n?";
private static String reg1 = "([\\s\\S]*?)¥(\\d*\\.?\\d*)";
private static Pattern compile = Pattern.compile(reg);
private static Pattern compile1 = Pattern.compile(reg1);
private static List l = new ArrayList();
@Autowired
private XianyuDataMapper xianyuDataMapper;
@Override
public void XianyuCouponsInfo() {
xianyuCoupons();
}
public void xianyuCoupons() {
DesiredCapabilities des = new DesiredCapabilities();
des.setCapability("deviceName", Pattern.compile("deviceName"));
des.setCapability("udid", udid);
des.setCapability("platformName", Pattern.compile("platformName"));
des.setCapability("platformVersion", Pattern.compile("platformVersion"));
des.setCapability("noReset", Pattern.compile("noReset"));
des.setCapability("appPackage", Pattern.compile("appPackage"));
des.setCapability("appActivity", Pattern.compile("appActivity"));
des.setCapability("recreateChromeDriverSessions", Pattern.compile("recreateChromeDriverSessions"));
des.setCapability("browserName", "");
ChromeOptions options = new ChromeOptions();
des.setCapability(ChromeOptions.CAPABILITY, options);
URL remoteUrl = null;
try {
remoteUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
driver = new AndroidDriver(remoteUrl, des);
// 设置隐士等待
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// 打开咸鱼
openxianyu();
// 输入关键字
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
yihaizuche();
// 获取数据
getData(500,"关键字");
System.out.println(xianYuDateDtoList);
xianyuDataMapper.xianyuData(xianYuDateDtoList);
xianYuDateDtoList = new ArrayList<>();
// 点击搜索
waitTime(5);
By searchBox = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View[2]");
driver.findElement(searchBox).click();
waitTime(5);
// 清空搜索框内容
By clean = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.widget.ImageView");
driver.findElement(clean).click();
// 清空集合内容
xianyuDtoList = new ArrayList<>();
// 输入关键字
haiyizuchue();
// 获取数据
getData(500,"关键字");
System.out.println(xianYuDateDtoList);
xianyuDataMapper.xianyuData(xianYuDateDtoList);
xianYuDateDtoList = new ArrayList<>();
// 点击搜索
waitTime(5);
driver.findElement(searchBox).click();
waitTime(5);
// 清空搜索框内容
driver.findElement(clean).click();
// 清空集合内容
xianyuDtoList = new ArrayList<>();
// 输入租车
zuche();
// 获取数据
getData(200,"关键字");
System.out.println(xianYuDateDtoList);
xianyuDataMapper.xianyuData(xianYuDateDtoList);
xianYuDateDtoList = new ArrayList<>();
for (int i = 0; i<20;i++){
driver.navigate().back();
}
}
public static void getData(int dataSize,String searchKeyword) {
while (true){
if (xianyuDtoList.size()>dataSize){
break;
}
// 获取集合的个数
int sizestate = xianyuDtoList.size();
System.out.println("sizestate:"+sizestate);
for (int i = 1; i<7 ; i++){
By xpath1 = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View[6]/android.view.View/android.view.View/android.view.View/android.widget.ScrollView/android.view.View[" + i + "]");
By xpath2 = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View[6]/android.view.View/android.widget.ImageView/android.view.View/android.widget.ScrollView/android.view.View["+i+"]");
By xpath = null;
if (isExist(xpath1)){
xpath = xpath1;
}else if (isExist(xpath2)){
xpath = xpath2;
}else {
continue;
}
if (driver.findElement(xpath).getText().equals("哎呀,到底了")){
break;
}
WebElement element = driver.findElement(xpath);
String text = element.getText();
Matcher matcher = compile.matcher(text);
System.out.println("----------------第"+i+"开始--------------");
String goodsName = "";
String price = "";
String people = "";
while (matcher.find()){
String s1 = matcher.group(1).replaceAll("\n", "").replaceAll("", "").replaceAll(" ","");
Matcher matcher1 = compile1.matcher(s1);
while (matcher1.find()){
goodsName = matcher1.group(1);
price = matcher1.group(2);
break;
}
people = matcher.group(2).replaceAll("\n", "").replaceAll("", "").replaceAll(" ", "");
if (goodsName.length()>200){
continue;
}
XianyuDto xianyuDto = new XianyuDto(goodsName, price, people);
if (xianyuDtoList.contains(xianyuDto)){
continue;
}
System.out.println("goodsName:"+goodsName);
System.out.println("price:"+price);
System.out.println("people: "+people);
// 获取大于两百的字符串
// 获取大于两百的字符串
endFlag = 0;
xianyuDtoList.add(xianyuDto);
xianYuDateDtoList.add(new XianYuDateDto(searchKeyword,goodsName,price,people,"闲鱼", new Date(),0));
System.out.println(xianYuDateDtoList);
System.out.println("----------------第"+i+"结束--------------");
// System.out.println(matcher.group(3).replaceAll("\n","").replaceAll("",""));
}
}
// 获取集合的个数
int sizeend = xianyuDtoList.size();
System.out.println("sizeend: "+sizeend);
if ((sizeend-sizestate)==0){
driver.swipe(423,1041,423,549,2000);
waitTime(3);
endFlag++;
if (endFlag == 3){
break;
}
continue;
}
driver.swipe(423,1541,423,349,3000);
waitTime(3);
}
}
public static void openxianyu() {
waitTime(2);
// 打开咸鱼
MobileElement el1 = (MobileElement) driver.findElementByAccessibilityId("闲鱼");
el1.click();
waitTime(10);
// 点击搜索框
By searchBox = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout");
driver.findElement(searchBox).click();
waitTime(10);
// 再次点击输入框
By xpath = By.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.widget.EditText");
driver.findElement(xpath).click();
waitTime(10);
}
/**
* 输入关键字
*/
public static void yihaizuche() {
waitTime(3);
// 输入关键字
// y
click(udid,"500","1077");
waitTime(2);
// i
click(udid,"678","1086");
waitTime(2);
// h
click(udid,"546","1214");
waitTime(2);
// a
click(udid,"96","1218");
waitTime(2);
// i
click(udid,"678","1086");
waitTime(2);
// z
click(udid,"168","1346");
waitTime(2);
// u
click(udid,"589","1083");
waitTime(2);
// c
click(udid,"365","1348");
waitTime(2);
// h
click(udid,"546","1214");
waitTime(2);
// e
click(udid,"230","1081");
waitTime(8);
// 点击关键字
click(udid,"130","975");
waitTime(8);
click(udid,"827","91");
// screenElement.click();
waitTime(12);
}
/**
* 输入关键字
*/
public static void haiyizuchue() {
waitTime(6);
// 输入关键字
// h
click(udid,"546","1214");
waitTime(2);
// a
click(udid,"96","1218");
waitTime(2);
// i
click(udid,"678","1086");
waitTime(2);
// p
click(udid,"856","1079");
waitTime(2);
// i
click(udid,"678","1086");
waitTime(2);
// 点击文字
click(udid,"130","975");
waitTime(2);
// 删除皮字
click(udid,"838","1339");
waitTime(2);
// y
click(udid,"500","1077");
waitTime(2);
// i
click(udid,"678","1086");
waitTime(2);
// e
click(udid,"227","1083");
waitTime(2);
// r
click(udid,"323","1083");
waitTime(2);
// 点击文字
click(udid,"130","975");
waitTime(2);
// 删除二字
click(udid,"838","1339");
waitTime(2);
// z
click(udid,"168","1346");
waitTime(2);
// u
click(udid,"589","1083");
waitTime(2);
// c
click(udid,"365","1348");
waitTime(2);
// h
click(udid,"546","1214");
waitTime(2);
// e
click(udid,"230","1081");
waitTime(3);
// 点击输入的关键字
click(udid,"130","975");
waitTime(3);
click(udid,"827","91");
// screenElement.click();
waitTime(7);
}
/**
* 输入关键字
*/
public static void zuche() {
waitTime(3);
// 输入关键字
// z
click(udid,"168","1346");
waitTime(2);
// u
click(udid,"589","1083");
waitTime(2);
// c
click(udid,"365","1348");
waitTime(2);
// h
click(udid,"546","1214");
waitTime(2);
// e
click(udid,"230","1081");
waitTime(3);
// 点击输入的关键字
click(udid,"130","975");
waitTime(3);
click(udid,"827","91");
// screenElement.click();
waitTime(7);
}
public static boolean isExist(By by) {
try{
driver.findElement(by);
return true;
}catch (Exception e){
return false;
}finally {
}
}
public static void waitTime(int sec) {
try {
Thread.sleep(sec * 1000);
} catch (Exception e) {
}
}
/**
* 点击
*/
public static void click(String udid , String x ,String y) {
try {
Runtime.getRuntime().exec("adb -s "+udid+" shell input tap "+x+" "+y+"");
} catch (IOException e) {
e.printStackTrace();
}
}
}