Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,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
运行
AI代码解释
复制
 <!-- 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
运行
AI代码解释
复制
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
运行
AI代码解释
复制
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
运行
AI代码解释
复制
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
运行
AI代码解释
复制
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
运行
AI代码解释
复制
   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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【ES三周年】一文搞懂 ElasticSearch 和 MySQL 索引的优缺点
这段时间在维护产品的搜索功能,每次在管理台看到 elasticsearch 这么高效的查询效率我都很好奇他是如何做到的。
crossoverJie
2023/02/14
2.1K0
ElasticSearch索引 VS MySQL索引
这段时间在维护产品的搜索功能,每次在管理台看到 elasticsearch 这么高效的查询效率我都很好奇他是如何做到的。
Java团长
2020/10/26
1.5K0
ElasticSearch索引  VS  MySQL索引
10张图理解Elasticsearch核心概念
Elasticsearch(以下称之为ES)是一款基于Lucene的分布式全文搜索引擎,擅长海量数据存储、数据分析以及全文检索查询,它是一款非常优秀的数据存储与数据分析中间件,广泛应用于日志分析以及全文检索等领域,目前很多大厂都基于Elasticsearch开发了自己的存储中间件以及数据分析平台。
慕枫技术笔记
2023/03/20
7280
10张图理解Elasticsearch核心概念
用了 Elasticsearch 后,查询起飞了!
本文不会关注 ES 里面的分布式技术、相关 API 的使用,而是专注分享下“ES 如何快速检索”这个主题上面。这个也是我在学习之前对 ES 最感兴趣的部分。
杰哥的IT之旅
2021/09/27
4050
全文检索的极致之选:Elasticsearch完全指南
倒序索引也被称为“反向索引”或“反向文件”,是一种索引数据结构。倒序索引在“内容”和存放内容的“位置”之间的映射,其目的在于快速全文索引和使用最小处理代价将新文件添加进数据库。通过倒序索引,可以快速根据“内容”查到包含它的文件。这种数据结构被广泛使用在搜索引擎中,倒排索引有两种不同的索引形式:
用户1413827
2023/11/28
1.1K0
2022最新ES面试题整理(Elasticsearch面试指南系列)「建议收藏」
看到网上各式各样关于Elasticsearch面试题的文章,但是貌似都不是很全面,所以特意整理了一篇关于常见的ES面试题,已收录至面试专栏,计划更新 10/50 个常见面试题,此次先发出来 10个,后续更新,请关注我的博客,第一时间查看更新。
全栈程序员站长
2022/10/03
9.2K0
2022最新ES面试题整理(Elasticsearch面试指南系列)「建议收藏」
ElasticSearch系列之索引机制学习笔记
在上一章的学习,我们对ElasticSearch有了比较清晰的理解,然后本博客继续学习ES中比较重要的核心原理和具体实现。相对于MySQL的索引机制,大部分是基于B+树的,需要我们进行手动创建索引,但是ES的索引是不需要手动创建的,默认是自动创建索引的。所以学习ES的倒排索引可以和MySQL的索引做一个对比,进行学习,思考一下为什么ES的倒排索引可以达到近实时(NRT)的查询效率
SmileNicky
2022/05/10
7210
ElasticSearch系列之索引机制学习笔记
内存吞金兽(Elasticsearch)的那些事儿 -- 数据结构及巧妙算法
ES 本质上是一个支持全文搜索的分布式内存数据库,特别适合用于构建搜索系统。ES 之所以能有非常好的全文搜索性能,最重要的原因就是采用了倒排索引。倒排索引是一种特别为搜索而设计的索引结构,倒排索引先对需要索引的字段进行分词,然后以分词为索引组成一个查找树,这样就把一个全文匹配的查找转换成了对树的查找,这是倒排索引能够快速进行搜索的根本原因。
房上的猫
2021/08/31
5320
内存吞金兽(Elasticsearch)的那些事儿 -- 数据结构及巧妙算法
Elasticsearch 内部数据结构深度解读
最近知识星球里几个问题都问到了 doc values、store field、fielddata 等的概念。
铭毅天下
2020/10/26
6.1K0
Elasticsearch 内部数据结构深度解读
为什么 ElasticSearch 比 MySQL 更适合复杂条件搜索
熟悉 MySQL 的同学一定都知道,MySQL 对于复杂条件查询的支持并不好。MySQL 最多使用一个条件涉及的索引来过滤,然后剩余的条件只能在遍历行过程中进行内存过滤。
Bug开发工程师
2021/03/03
2.7K0
为什么 ElasticSearch 比 MySQL 更适合复杂条件搜索
elasticsearch面试常问问题_java面试题汇总
Elasticsearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据。
全栈程序员站长
2022/10/03
5340
elasticsearch面试常问问题_java面试题汇总
为什么ElasticSearch比MySQL更适合全文索引
熟悉 MySQL 的同学一定都知道,MySQL 对于复杂条件查询的支持并不好。MySQL 最多使用一个条件涉及的索引来过滤,然后剩余的条件只能在遍历行过程中进行内存过滤,对这个过程不了解的同学可以先行阅读一下《MySQL复杂where条件分析》。
程序员历小冰
2021/02/20
1.5K0
为什么ElasticSearch比MySQL更适合全文索引
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之倒排索引(三)
首先,我们需要了解传统的正向索引。在正向索引中,文档是按照它们在磁盘上的顺序进行存储的,每个文档都有一个与之关联的文档ID。如果我们要查找某个词在哪些文档中出现,就需要遍历整个文档集合,这显然是非常低效的。
公众号:码到三十五
2024/03/19
1.7K0
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之倒排索引(三)
【愚公系列】2021年11月 Elasticsearch数据库-面试题
1、可以看到,trie 树每一层的节点数是 26^i 级别的。所以为了节省空间,我们 还可以用动态链表,或者用数组来模拟动态。而空间的花费,不会超过单词数×单 词长度。 2、实现:对每个结点开一个字母集大小的数组,每个结点挂一个链表,使用左儿子右兄弟表示法记录这棵树; 3、对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度 O(1)。
愚公搬代码
2021/12/03
1.1K0
【愚公系列】2021年11月 Elasticsearch数据库-面试题
Elasticsearch 6.x版本全文检索学习之数据建模
  答:数据建模,英文为Data Modeling,为创建数据模型的过程。数据模型Data Mdel,对现实世界进行抽象描述的一种工具和方法,通过抽象的实体及实体之间联系的形式去描述业务规则,从而实现对现实世界的映射。
别先生
2019/11/14
9510
面试题之 ElasticSearch 是如何建立索引的?
现在有了 ElasticSearch,就可以直接使用基于 Lucene 的各种检索功能,ElasticSearch 是一个基于 Lucene 的分布式全文检索框架,在 Lucene 类库的基础上实现,可以避免直接基于 Lucene 开发,这一点和 Java 中 Netty 对 IO/NIO 的封装有些类似。
wayn
2024/03/02
2480
面试题之 ElasticSearch 是如何建立索引的?
何时使用Elasticsearch而不是MySql
MySQL 和 Elasticsearch 是两种不同的数据管理系统,它们各有优劣,适用于不同的场景。本文将从以下几个方面对它们进行比较和分析:
wayn
2023/08/09
8940
何时使用Elasticsearch而不是MySql
2021年春招Elasticsearch面试题
1、可以看到,trie 树每一层的节点数是 26^i 级别的。所以为了节省空间,我们还可以用动态链表,或者用数组来模拟动态。而空间的花费,不会超过单词数×单词长度。2、实现:对每个结点开一个字母集大小的数组,每个结点挂一个链表,使用左儿子右兄弟表示法记录这棵树;3、对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度 O(1)。
zls365
2021/04/23
1.3K0
2021年春招Elasticsearch面试题
为什么 Apache Doris 是比 Elasticsearch 更好的实时分析替代方案?
Elasticsearch 是一款开源的分布式检索引擎,广泛应用于日志分析、全文搜索和数据监控等领域。凭借其强大的实时搜索能力和灵活的查询语言,在市场上获得了广泛认可。然而,在过去两年,我们注意到一个趋势,很多 Elasticsearch 用户倾向于采用 Apache Doris 替代 Elasticsearch。
SelectDB技术团队
2025/03/27
3730
触类旁通Elasticsearch:原理
ES被设计为处理海量数据的高性能搜索场景。海量数据具体说至少应该是数亿文档,而高性能具体说就是从数亿文档中任意搜索需要的信息,应该在秒级返回结果。既然ES的一切都是为了性能而设计,从逻辑设计和物理设计两个角度考察ES的数据组织,对于理解ES的工作原理会有帮助。
用户1148526
2019/05/25
7920
推荐阅读
相关推荐
【ES三周年】一文搞懂 ElasticSearch 和 MySQL 索引的优缺点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验