当前位置:   article > 正文

Java爬虫——Selenium Java详解及案例_java selenium爬取数据案例

java selenium爬取数据案例

一些基础的知识可以通过以下链接先了解:
https://www.jianshu.com/p/20526e2ac3b1

import com.bbt.companyreg.skuhelper.service.HttpProxyIPPoolService;
import com.bbt.companyreg.skuhelper.service.impl.HttpProxyIPPoolServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

/**
 * Created by wuming on 2020/6/10 11:03
 */
@Slf4j
public class WebDriverUtil {
    private static ChromeDriver webDriver;
    public static String ip;
    public static ChromeDriver getWebDriver() {
        String driver = null;
        if(isOSWindow()){
            driver = "D:\\chromedriver\\chromedriver.exe";
        }else{
            driver = "/usr/bin/driver/chromedriver";
        }
        System.setProperty("webdriver.chrome.driver", driver);
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized"); // 启动时自动最大化窗口
        options.addArguments("--disable-popup-blocking"); // 禁用阻止弹出窗口
        options.addArguments("no-sandbox"); // 启动无沙盒模式运行
        options.addArguments("disable-extensions"); // 禁用扩展
        options.addArguments("no-default-browser-check"); // 默认浏览器检查
        options.setHeadless(Boolean.TRUE);//设置chrome 无头模式
        options.addArguments("--headless");//不用打开图形界面。
        //这里设置访问的ip
        options.addArguments("--proxy-server=http://" + ip);
        webDriver = new ChromeDriver(options);
        //  webDriver.manage().window().maximize();
        // 与浏览器同步非常重要,必须等待浏览器加载完毕,隐式等待30s
        webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        //设置页面超时时间,有时候浏览器会处于假死状态,设置这个解决。
        webDriver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);
        return webDriver;
    }

    public static void closeDriver() {
        webDriver.close();
        webDriver = null;
    }

    //判断当前是否linux系统
    public static boolean isOSWindow() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("os.name");
        if (os != null && os.toLowerCase().indexOf("windows") > -1) {
            return true;
        } else {
            return false;
        }
    }


    public static String getIp(){
        String ip = null;
        Integer port = null;
        for(int i=0;i<6;i++){
            HttpProxyIPPoolService httpProxyIPPoolService = new HttpProxyIPPoolServiceImpl();
            List<HttpProxyIPPoolServiceImpl.IPData> ips = httpProxyIPPoolService.getNextIP();
            HttpProxyIPPoolServiceImpl.IPData ipData = ips.get(0);
            port = Integer.valueOf(ipData.getPort());
            ip = ipData.getIp();
            if(test(ip, port)){
                return ip+":"+port;
            }
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return ip+":"+port;
    }
    
    //可以通过这种方式筛选出速度比较快的ip
    private static boolean test(String ip, Integer port) {
        try {
           CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet("www.baidu.com");
            HttpHost proxy = new HttpHost(ip, port);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .setConnectTimeout(200)
                    .setSocketTimeout(200)
                    .setConnectionRequestTimeout(200)
                    .build();
            httpGet.setConfig(requestConfig);
//            //设置请求头信息
//            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like " +
//                    "Gecko) Chrome/62.0.3202.94 Safari/537.36");
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if (response == null) {
                log.warn("当前ip不可用:重新获取---"+ip);
                return false;
            } else {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return true;
                }
            }
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        log.warn("当前ip不可用:"+ip);
        return false;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
//显示等待的方式让这两个按钮加载完毕
    private void loadElement(){
        (new WebDriverWait(webDriver,10))
                .until(ExpectedConditions.elementToBeClickable(By.className(skuBtn)));
        (new WebDriverWait(webDriver,10))
                .until(ExpectedConditions.elementToBeClickable(By.className(skuActionBtn)));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

显示等待,隐式等待和强制等待的区别:

在实际使用selenium时,等待下个等待定位的元素出现,特别是web端加载的过程,都需要用到等待,而等待方式的设置是保证脚本稳定有效运行的一个非常重要的手段,在selenium中(appium通用)常用的等待分为显示等待WebDriverWait()、隐式等待implicitly_wait()、强制等待sleep()三种,下面我们就分别介绍一下这三种等待的区别
sleep(): 强制等待,设置固定休眠时间。后脚本的执行过程中执行 sleep()后线程休眠,而另外两种线程不休眠。
implicitly_wait():隐式等待,是设置的全局等待。设置等待时间,是对页面中的所有元素设置加载时间,如果超出了设置时间的则抛出异常。隐式等待可以理解成在规定的时间范围内,浏览器在不停的刷新页面,直到找到相关元素或者时间结束。
WebDriverWait():显示等待,是针对于某个特定的元素设置的等待时间,在设置时间内,默认每隔一段时间检测一次当前页面某个元素是否存在,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关操作,如果超过设置时间检测不到则抛出异常。默认检测频率为0.5s,默认抛出异常为:NoSuchElementException。

注意:
1.Java使用chromedriver的时候,同一个时间内只能够打开一个虚拟浏览器,不能使用多线程的方式同时打开多个chrome。

2.访问的频率也不能太快,要适当使用sleep降低访问频率,否则会被网站监测出来,网址很快被封。

3.当我们在一段时间内多次去爬取同一个网站的数据的时候,我们的ip可能会被ban,此时我们需要用到代理ip,使用一些免费的代理服务器的话,网络可能不稳定。此时可以去网上找些付费的,例如我之前使用过的小象代理。每个月也就100多。

public class HttpProxyIPPoolServiceImpl implements HttpProxyIPPoolService {
	private static String IP_URL = "https://api.xiaoxiangdaili.com/ip/get";
	private static String appKey="";
	private static String appSecret="";
	private static String cnt = "5";
	private static String wt = "json";

	@Override
	public List<IPData> getNextIP() {
		String responseJson = null;
		try {
			responseJson = Jsoup.connect(IP_URL).method(Connection.Method.GET)
					.header("Content-Type", "application/json;charset=UTF-8").data("appKey", appKey, "appSecret", appSecret, "cnt", cnt, "wt", wt)
					.ignoreHttpErrors(true).ignoreContentType(true).timeout(2000).get().text();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		log.info("responseJson:" + responseJson);

		XiaoXiangResultDto result = JSONObject.parseObject(responseJson, XiaoXiangResultDto.class);
		log.info("result IP:" + result.getData().get(0).getIp() + ", port:" + result.getData().get(0).getPort() + ", during:" + result.getData().get(0).getDuring());
		return result.getData();
	}

	public static class IPData {
		private String ip;
		private String port;
		private String realIp;
		private int during;
		public String getIp() {
			return ip;
		}
		public void setIp(String ip) {
			this.ip = ip;
		}
		public String getPort() {
			return port;
		}
		public void setPort(String port) {
			this.port = port;
		}
		public String getRealIp() {
			return realIp;
		}
		public void setRealIp(String realIp) {
			this.realIp = realIp;
		}
		public int getDuring() {
			return during;
		}
		public void setDuring(int during) {
			this.during = during;
		}
	}

	@Data
	private static class XiaoXiangResultDto {
		private int code;
		private boolean success;
		private String msg;
		private List<IPData> data;
		public int getCode() {
			return code;
		}
		public void setCode(int code) {
			this.code = code;
		}
		public boolean isSuccess() {
			return success;
		}
		public void setSuccess(boolean success) {
			this.success = success;
		}
		public String getMsg() {
			return msg;
		}
		public void setMsg(String msg) {
			this.msg = msg;
		}
		public List<IPData> getData() {
			return data;
		}
		public void setData(List<IPData> data) {
			this.data = data;
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/89707
推荐阅读
相关标签
  

闽ICP备14008679号