Java Selenium抓取网页

最近自己在做一个项目使用Selenium抓取数据,发现升级Google Chrome 84版本会出现 被检测出来使用 就不给你返回数据,导致无法使用,抓狂了一段时间没有解决方案,以下都是亲测成功总结,百度搜索都是千遍一律的结果,有许多坑。

防止网站检测出Selenium的window.navigator.webdriver属性

1.升级Selenium 版本

<!-- selenium解析器 -->

        <dependency>

            <groupId>org.seleniumhq.selenium</groupId>

            <artifactId>selenium-java</artifactId>

            <version>4.0.0-alpha-6</version>

        </dependency>


java.lang.NoSuchMethodError: 'byte[] kotlin.collections.ArraysKt.copyInto

升级版本的时候会遇到包版本冲突的问题,解决方法:

<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib -->

        <dependency>

            <groupId>org.jetbrains.kotlin</groupId>

            <artifactId>kotlin-stdlib</artifactId>

            <version>1.3.70</version>

        </dependency>



2. 使用官方插件CDP命令 屏蔽window.navigator.webdriver属性值

ChromeOptions options =new ChromeOptions();

//不提示“Chrome正受到自动测试软件控制” 

options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation") );

options.setExperimentalOption("useAutomationExtension", false);

Map map =new HashMap();

map.put("source","Object.defineProperties(navigator, {webdriver:{get:()=>undefined}})");

driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument",map);


3. ChromeDriver 对应本地浏览器的版本




selenium是一个自动化网页测试业务流程工具,也可以用来爬取网页数据。

谷歌驱动下载 ChromeDriver 2.35   

我本地Google Chrome 84.0.4147.125(正式版本) (64 位)

也可以用,但是selenium升级后用不了CDP命令。


http://npm.taobao.org/mirrors/chromedriver/

下载chromeDriver:http://chromedriver.storage.googleapis.com/index.html

<dependency>

            <groupId>org.seleniumhq.selenium</groupId>

            <artifactId>selenium-java</artifactId>

            <version>3.141.59</version>

</dependency>

selenium 依赖了com.google.guava 25.0-jre注意重复依赖问题

重复依赖报错:

java.lang.IllegalAccessError: tried to access method com.google.common.util.concurrent.SimpleTimeLimiter.<init>(Ljava/util/concurrent/ExecutorService;)V

解决方法 找出低版本的另一个依赖排除com.google.guava依赖:

<exclusion>

    <groupId>com.google.guava</groupId>

    <artifactId>guava</artifactId>

</exclusion>

我的冲突就是io.springfox包含了com.google.guava 20.0,该项目的pom.xml依赖下加上以上的语句来排除依赖


Selenium 3.0使用firefox

https://github.com/mozilla/geckodriver/releases



###java###

private static WebDriverdriver;

private static ChromeDriverServiceservice;

public static void createAndStartService() {

    service =new ChromeDriverService.Builder()

    .usingDriverExecutable(new File("C:\\Program Files (x86)\\webDriver\\chromedriver.exe"))

    .usingAnyFreePort()

    .build();

     try {

            service.start();

     }catch (IOException e) {

            e.printStackTrace();

     }

}

public static void createDriver(URL url, String urlPath){

    driver =new RemoteWebDriver(url, DesiredCapabilities.chrome());

    //driver.get(urlPath);  //打开一个页面访问

    try {

        /**

        * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1);

        * Arg0:等待的时间长度,int 类型 ; Arg1:等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。

        */

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    } catch (Exception e) {

        e.printStackTrace();

    }

    //获取当前浏览器的信息

    System.out.println("Title:" +driver.getTitle());

    System.out.println("currentUrl:" +driver.getCurrentUrl());

}


private void createDriver(URL url, String urlPath){

try {

        if(url ==null){

            url=service.getUrl();

        }

        ChromeOptions options =new ChromeOptions();

        //不提示“Chrome正受到自动测试软件控制”

        options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});

        options.setExperimentalOption("useAutomationExtension", false);

        //driver = new ChromeDriver(service, options);

        //driver = new RemoteWebDriver(url, DesiredCapabilities.chrome());

        //不加载图片,加快访问速度

        Map prefs =new HashMap();

        prefs.put("profile.managed_default_content_settings.images", 2);

        options.setExperimentalOption("prefs", prefs);

        //使用本地的Google浏览器,一次只能打开一个

        options.addArguments("user-data-dir=C:/Users/Administrator/AppData/Local/Google/Chrome/User Data");

        driver =new ChromeDriver(service, options);

        //解决,对window.navigator.webdriver的检测机制

        JavascriptExecutor executor = (JavascriptExecutor)driver;

        executor.executeScript("Object.defineProperties(navigator, {webdriver:{get:()=>undefined}});");

        if(StringUtils.isNotEmpty(urlPath)) {

                driver.get(urlPath);

        }

/**

* WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1);

* Arg0:等待的时间长度,int 类型 ; Arg1:等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。

*/

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    }catch (Exception e) {

e.printStackTrace();

    }

}



参数设置

ChromeOptions options =new ChromeOptions();

//不提示“Chrome正受到自动测试软件控制”  Collections.singletonList("enable-automation")

//options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});

//options.setExperimentalOption("useAutomationExtension", false);

//打开cmd 进入到Google Chrome目录下运行如下命令:

//chrome.exe --remote-debugging-port=9222 --user-data-dir="F:\selenum\AutomationProfile"

//options.setExperimentalOption("debuggerAddress","127.0.0.1:9222");

//设置代理

//options.addArguments("--proxy-server=http://127.0.0.1:8080");

//driver = new RemoteWebDriver(url, DesiredCapabilities.chrome());

//不加载图片,加快访问速度 1允许  2禁止

//Map prefs = new HashMap();

//prefs.put("profile.managed_default_content_settings.images", 1);

//options.setExperimentalOption("prefs", prefs);

//使用本地的Google浏览器,一次只能打开一个

//options.addArguments("user-data-dir=C:/Users/Administrator/AppData/Local/Google/Chrome/User Data");



//关闭驱动并退出

public static void doCloseQuit(){

        if(driver != null) {

            driver.close();

            driver.quit();

        }

    }

driver.findElement(By.id("login_id")).clear(); //获取id是login_id的元素,并清除内容

driver.findElement(By.id("login_id")).sendKeys("xxx"); //获取id是login_id的元素,并输入xxx内容

driver.findElement(By.id("continueBtn")).click(); //获取id是continueBtn的元素,并模拟执行点击事件

.sendKeys(Keys.ENTER);  //相当于按键盘上的Enter(回车)


//骚操作By.xpath,任意的去匹配你要获取的元素,下面就是获取id是rptBody元素内的div内的table元素

By by = By.xpath(".//*[@id='rptBody']/div/table");

WebElement tableElement =driver.findElement(by);


这种写法是如果在div内有多个table获取的是第一个table元素

By by = By.xpath(".//*[@id='rptBody']/div/table[1]");


//同级元素

By by = By.xpath(".//input[@id='ids']/../span");


//执行js脚本方法

String jString="Login()";

((JavascriptExecutor)driver).executeScript(jString);


下拉选择框获取选中的值

WebElement selectWebElement = driver.findElement(By.id("_jt_page_size"));

Select select = new Select(selectWebElement);

String s = select.getFirstSelectedOption().getText();



//如果你需要获取 iframe 内的元素需要一下流程才能获取:

//进入到 iframe 内

WebElement iframe =driver.findElement(By.id("iframe"));

driver.switchTo().frame(iframe);


//获取iframe 内元素的操作

...


// 回到主窗口

driver.switchTo().defaultContent();


/**

* 浏览器后台运行,向下滑动

* @param url

* @return

*/

public static DocumentgetDocument(String url){

Document doc =null;

    //可使用的浏览器有:IE浏览器(webdriver.ie.driver)

//火狐浏览器  (webdriver.gecko.driver)

//谷歌浏览器 (webdriver.chrome.driver)

//                  是使用那个浏览器                                  chromedriver所在的位置

    System.setProperty("webdriver.chrome.driver", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe");

    // InternetExplorerDriver()  浏览器

// FirefoxDriver()            火狐浏览器

//谷歌浏览器

    WebDriver driver =null;

    //创建chrome参数对象

    ChromeOptions options =new ChromeOptions();

    //浏览器后台运行

    options.addArguments("headless");

    driver =new ChromeDriver(options);

    driver.get(url);

    //等待几秒

    try {

//向下滚动  方法一

//JavascriptExecutor js = (JavascriptExecutor)driver;

//js.executeScript("scrollTo(0,20000)");

//向下滚动 方法二

        ((JavascriptExecutor)driver).executeScript("scrollTo(0,10000)");

        Thread.sleep(20000);

    }catch (InterruptedException e) {

        e.printStackTrace();

    }

doc = Jsoup.parse(driver.getPageSource());

    //关闭浏览器

    driver.close();

    driver.quit();

    return doc;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343