前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用Selenium爬取动态网页如何绕开CloudFlare 5秒盾【示例】

使用Selenium爬取动态网页如何绕开CloudFlare 5秒盾【示例】

作者头像
Cheng_Blog
发布于 2023-05-20 06:24:49
发布于 2023-05-20 06:24:49
1.1K00
代码可运行
举报
文章被收录于专栏:Cheng's BlogCheng's Blog
运行总次数:0
代码可运行
默认已经安装好chromeDrive

1. 导入引用

代码语言:javascript
代码运行次数:0
运行
复制
 <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.0-jre</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>

2. 这里需要创建几个类,后面会用到

代码语言:javascript
代码运行次数:0
运行
复制
public class ChromiumDriver extends RemoteWebDriver {

    public ChromiumDriver(Capabilities capabilities) {
        this(new ChromiumDriverCommandExecutor("goog", ChromeDriverService.createDefaultService()), capabilities, ChromeOptions.CAPABILITY);
    }

    protected ChromiumDriver(CommandExecutor commandExecutor, Capabilities capabilities, String capabilityKey) {
        super(commandExecutor, capabilities);

    }

    /**
     * Launches Chrome app specified by id.
     *
     * @param id Chrome app id.
     */
    public void launchApp(String id) {
        execute(ChromiumDriverCommand.LAUNCH_APP, ImmutableMap.of("id", id));
    }

    /**
     * Execute a Chrome Devtools Protocol command and get returned result. The
     * command and command args should follow
     * <a href="https://chromedevtools.github.io/devtools-protocol/">chrome devtools
     * protocol domains/commands</a>.
     */
    public Map<String, Object> executeCdpCommand(String commandName, Map<String, Object> parameters) {

        @SuppressWarnings("unchecked")
        Map<String, Object> toReturn = (Map<String, Object>) getExecuteMethod().execute(ChromiumDriverCommand.EXECUTE_CDP_COMMAND,
                ImmutableMap.of("cmd", commandName, "params", parameters));

        return ImmutableMap.copyOf(toReturn);
    }

    @Override
    public void quit() {
        super.quit();
    }
}
代码语言:javascript
代码运行次数:0
运行
复制
final class ChromiumDriverCommand {
    private ChromiumDriverCommand() {}

    static final String LAUNCH_APP = "launchApp";
    static final String GET_NETWORK_CONDITIONS = "getNetworkConditions";
    static final String SET_NETWORK_CONDITIONS = "setNetworkConditions";
    static final String DELETE_NETWORK_CONDITIONS = "deleteNetworkConditions";
    static final String EXECUTE_CDP_COMMAND = "executeCdpCommand";

    // Cast Media Router APIs
    static final String GET_CAST_SINKS = "getCastSinks";
    static final String SET_CAST_SINK_TO_USE = "selectCastSink";
    static final String START_CAST_TAB_MIRRORING = "startCastTabMirroring";
    static final String GET_CAST_ISSUE_MESSAGE = "getCastIssueMessage";
    static final String STOP_CASTING = "stopCasting";

    static final String SET_PERMISSION = "setPermission";
}
代码语言:javascript
代码运行次数:0
运行
复制
public class ChromiumDriverCommandExecutor extends DriverCommandExecutor {

    private static Map<String, CommandInfo> buildChromiumCommandMappings(String vendorKeyword) {
        String sessionPrefix = "/session/:sessionId/";
        String chromiumPrefix = sessionPrefix + "chromium";
        String vendorPrefix = sessionPrefix + vendorKeyword;

        HashMap<String, CommandInfo> mappings = new HashMap<>();

        mappings.put(ChromiumDriverCommand.LAUNCH_APP,
                new CommandInfo(chromiumPrefix + "/launch_app", HttpMethod.POST));

        String networkConditions = chromiumPrefix + "/network_conditions";
        mappings.put(ChromiumDriverCommand.GET_NETWORK_CONDITIONS,
                new CommandInfo(networkConditions, HttpMethod.GET));
        mappings.put(ChromiumDriverCommand.SET_NETWORK_CONDITIONS,
                new CommandInfo(networkConditions, HttpMethod.POST));
        mappings.put(ChromiumDriverCommand.DELETE_NETWORK_CONDITIONS,
                new CommandInfo(networkConditions, HttpMethod.DELETE));

        mappings.put( ChromiumDriverCommand.EXECUTE_CDP_COMMAND,
                new CommandInfo(vendorPrefix + "/cdp/execute", HttpMethod.POST));

        // Cast / Media Router APIs
        String cast = vendorPrefix + "/cast";
        mappings.put(ChromiumDriverCommand.GET_CAST_SINKS,
                new CommandInfo(cast + "/get_sinks", HttpMethod.GET));
        mappings.put(ChromiumDriverCommand.SET_CAST_SINK_TO_USE,
                new CommandInfo(cast + "/set_sink_to_use", HttpMethod.POST));
        mappings.put(ChromiumDriverCommand.START_CAST_TAB_MIRRORING,
                new CommandInfo(cast + "/start_tab_mirroring", HttpMethod.POST));
        mappings.put(ChromiumDriverCommand.GET_CAST_ISSUE_MESSAGE,
                new CommandInfo(cast + "/get_issue_message", HttpMethod.GET));
        mappings.put(ChromiumDriverCommand.STOP_CASTING,
                new CommandInfo(cast + "/stop_casting", HttpMethod.POST));

        mappings.put(ChromiumDriverCommand.SET_PERMISSION,
                new CommandInfo(sessionPrefix + "/permissions", HttpMethod.POST));

        return unmodifiableMap(mappings);
    }

    public ChromiumDriverCommandExecutor(String vendorPrefix, DriverService service) {
        super(service, buildChromiumCommandMappings(vendorPrefix));
    }
}

3. 开发工具类,获取ChromiumDriver

代码语言:javascript
代码运行次数:0
运行
复制
public static ChromiumDriver getChromiumDriver() {
        // 设置谷歌浏览器驱动,我放在项目的路径下,这个驱动可以帮你打开本地的谷歌浏览器
        String driverFilePath = "你的chromedriver路径";
        if (!StringUtils.isEmpty(driverFilePath)){
            System.setProperty("webdriver.chrome.driver", driverFilePath);
        }


        // 设置对谷歌浏览器的初始配置 开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        String[] a = { "enable-automation" };
        options.setExperimentalOption("excludeSwitches", a);
        options.addArguments("--headless");
        options.addArguments("window-size=1920,1080");
        String ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36";
        options.addArguments(String.format("--user-agent=%s", ua));

        options.addArguments("--no-sandbox");
        options.addArguments("--disable-gpu");
        options.addArguments("--disable-dev-shm-usage");
        options.setBinary("/usr/bin/google-chrome");

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


        //执行cdp命令,修改webdriver的值为undefined
        ChromiumDriver driver = new ChromiumDriver(chromeCaps);
        HashMap<String, Object> cdpCmd = new HashMap<String, Object>();
        cdpCmd.put("source", "Object.defineProperty(navigator, 'webdriver', {get: () => undefined }); ");
        driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", cdpCmd);

        return driver;
    }

4. 开发工具类,获取网页

代码语言:javascript
代码运行次数:0
运行
复制
   public static String convertHtml(String url) {
        ChromiumDriver chromiumDriver = getChromiumDriver();
        try {
            chromiumDriver.get(url);
            Thread.sleep(6000);
            return chromiumDriver.getPageSource();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            chromiumDriver.quit();
        }
    }

发表时间:2023-05-19

本站文章除注明转载/出处外,皆为作者原创,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
深入typeclass_Haskell笔记4
OOP中的Class是对象模板,用来描述现实事物,并封装其内部状态。FP中没有内部状态一说,所以Class在函数式上下文指的就是接口。派生自某类(deriving (SomeTypeclass))是说具有某类定义的行为,相当于OOP中的实现了某个接口,所以具有接口定义的行为
ayqy贾杰
2019/06/12
5440
Monoid_Haskell笔记9
数学世界里,0是加法单位元,1是乘法单位元(identity element),例如:
ayqy贾杰
2019/06/12
8650
类型_Haskell笔记3
::读作“类型为”(has type),告诉编译器变量name是String类型(即[Char]类型)的
ayqy贾杰
2019/06/12
9750
类型_Haskell笔记3
七夕送礼很发愁?自己编写一个区块链送女友吧~
作者 | Michael Burge 责编 | 贾维娣 Bitcoin和Ethereum提供一个处理资金、合同和所有权令牌的分散式手段。从技术层面来看,他们具有很多移动部件,并提供了一种演示编程语言的好方法。 本协议将开发一个简单的块状数据结构,以便在Haskell中演示: 编写二进制串行器和解串器 使用加密原语来计算哈希值 根据预算时间自动调整矿工难度 我们将其命名为Haskoin。请注意,在未来条款出来之前,它不会有任何关于网络和钱包安全的问题。 什么是区块链? 在编写任何应用软件之前的第一步总是需要
区块链大本营
2018/05/10
9560
Scalaz(8)- typeclass:Monoid and Foldable
该文章介绍了如何使用Monoid类型进行并行计算和并行序列化。首先介绍了Monoid的概念,以及如何使用Scalaz库中的Monoid类型进行并行计算。然后介绍了如何使用Monoid类型进行并行序列化,并提供了几个例子。最后还介绍了如何使用Monoid类型进行并行处理,并提供了几个例子。
用户1150956
2018/01/05
1.1K0
Zipper_Haskell笔记13
数据结构不可变,所以对其进行增、删、改等操作的结果只能是重新创建一份新的数据结构,例如:
ayqy贾杰
2019/06/12
5420
Zipper_Haskell笔记13
python内置函数
取绝对值 a = abs(-95) print(a) 值有一个为假,就全为假 a = all([True,True,False]) print(a) 有一个为真,就全为真 a = any([False,True,True]) print(a) 返回一个可打印的对象字符串方式表示 a = ascii('0x\10000') b = ascii('b\x19') print(a,b) 将整数转换成二进制字符串 a= bin(95) print(a) 将以个数据转换成8进制 a = oct(95)
Wyc
2018/09/11
7120
python内置函数
从惰性IO说起_Haskell笔记6
从硬盘读文件时并不会一次性全读入内存,而是一点一点的流式读取。文本文件的话,默认buffer是line-buffering,即一次读一行,二进制文件的话,默认buffer是block-buffering,一次读一个chunk,其具体大小取决于操作系统
ayqy贾杰
2019/06/12
2.4K0
Monadic Function_Haskell笔记12
只是把context换成了Monad而已,此外没什么区别。并且对于遵守Functor laws和Monad laws的类型,这两个函数是完全等价的,例如:
ayqy贾杰
2019/06/12
9660
python3 内置函数详解
内置函数详解 abs(x) 返回数字的绝对值,参数可以是整数或浮点数,如果参数是复数,则返回其大小。 # 如果参数是复数,则返回其大小。 >>> abs(-25) 25 >>> abs(25) 25 all(iterable) all()会循环括号内的每一个元素,如果括号内的所有元素都是真的,或者如果iterable为空,则返回True,如果有一个为假的那么就返回False >>> all([]) True >>> all([1,2,3]) True >>> all([1,2,""]) Fa
程序员同行者
2018/06/22
9620
newtype_Haskell笔记8
在List场景,xs <*> ys表示从左侧xs中取出函数作用于右侧ys中的每一项,有两种实现方式:
ayqy贾杰
2019/06/12
6900
Haskell 函数语法
guard由跟在函数名及参数后边的竖线标志,通常竖线都是靠右一个缩进排成一列。一个guard就是一个布尔表达式,如果是True,就使用对应的函数体。最后的一个guard往往是otherwise,它的定义就是简单一个otherwise = True。
Orlion
2024/09/02
1320
python笔记day2
name = {'name1':'Carrick','name2','Tina'}
py3study
2020/01/08
8930
Go Map 【Go语言圣经笔记】
哈希表是一种巧妙并且实用的数据结构。它是一个无序的key/value对的集合,其中所有的key都是不同的,然后通过给定的key可以在常数时间复杂度内检索、更新或删除对应的value。
Steve Wang
2021/12/06
7680
Go Map 【Go语言圣经笔记】
python面试题搜集:史上最全python面试题详解(一)
得到的最大数字在3925-3929之间浮动,这个是和计算机有关系的,不然也不会是一个浮动的数字了(数学逻辑讲求严谨)
宇宙之一粟
2020/10/26
1.4K0
铁定不纯的IO_Haskell笔记5
一直有个疑惑,Haskell号称纯函数式语言,那么铁定不纯的场景(肯定有副作用,或者操作本身就是副作用)如何解决?
ayqy贾杰
2019/06/12
1.4K0
热爱函数式的你,句句纯正的 Haskell【类型篇】
---- theme: github 每次看到干尸鬼鲛起舞,都有一种说不出的难受,不行,发出来,让大家一起难受难受~🐶 Haskell 是一门纯的函数式语言。 也就是说计算机主要是通过函数来完成的(像在数学中一样),而不是通过“先做这个,再做那个”的命令式操作顺序进行的(像在主流的编程语言中一样)。—— Simon Peyton Jones 初见😀 什么是 Haskell ?我们从 wiki 上可以找到以下要点: Haskell 是一种标准化的,通用的纯函数式编程语言,有惰性求值和强静态类型; 在H
掘金安东尼
2022/09/19
1.1K0
热爱函数式的你,句句纯正的 Haskell【类型篇】
Python常用函数
and,or,not运算符的优先级按从低到高,not运算拥有最优先级,只比素有运算符低一级
py3study
2020/01/17
1K0
learn-haskell
引言 Haskell不同于Scala,是一门纯函数式语言,它强制使用者使用函数式语法而没有妥协。 是一门强类型定义的静态类型语言。它的**类型模型基于推断理论(in-ferred)**并被公认为是函数语言中最高效的类型系统之一。你会发现该类型系统支持多态语义并有助于人们作出十分整洁清晰的设计。 支持Erlang风格的模式匹配(pattern matching)和哨兵表达式。你也能在Haskell中发现Clojure风格的惰性求值(lazyevaluation)以及与Clojure和Erlang相同的列表推导
刘笑江
2018/05/28
1.2K0
Haskell 自定义type与typeclass
那么如何解读上面的表达式呢? 首先data关键字后边的BookInfo是新类型的名字,我们称BookInfo为*类型构造器*。类型构造器用于指代(refer)类型。类型名字的首字母必须大写,因此类型构造器的首字母也必须大写。 接下来的Book是*值构造器*(或者称:*数据构造器*)的名字,类型的值就是由值构造器创建的。 Book之后的Int String [String] 是类型的组成部分 在这个例子中,Int表示书ID, String表示书名,[String]表示作者
Orlion
2024/09/02
1530
相关推荐
深入typeclass_Haskell笔记4
更多 >
目录
  • 默认已经安装好chromeDrive
  • 1. 导入引用
  • 2. 这里需要创建几个类,后面会用到
  • 3. 开发工具类,获取ChromiumDriver
  • 4. 开发工具类,获取网页
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档