【Java】使用Java实现爬虫

2023-05-16

文章目录

  • 使用Java实现爬虫
    • 一、HttpClient实现模拟HTTP访问
      • 1.1 HttpClient
      • 1.2 引入依赖
      • 1.3 创建简单的请求操作
        • 1.3.1 创建实例
        • 1.3.2 Jsoup应用
      • 1.4 爬取过程中可能出现的问题
        • 1.4.1 JS异步加载问题
        • 1.4.2 反爬技术的影响
      • 1.5 爬取需要登录的页面
        • 1.5.1 在header中直接携带Cookie
        • 1.5.2 模拟登录自动获取Cookie
    • 二、HtmlUtil实现JS异步加载页面
      • 2.1 HtmlUtil
      • 2.2 引入依赖
      • 2.3 创建简单的请求操作
        • 2.3.1 创建实例
        • 2.3.2 模拟浏览器操作
      • 2.4 爬取待登录的页面

使用Java实现爬虫

一、HttpClient实现模拟HTTP访问

1.1 HttpClient

HTTP 协议是 Internet 上使用得最多、最重要的协议之一,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。Commons HttpClient项目现已终止,不再开发。 它已被Apache HttpComponents项目里的HttpClient和HttpCore模块取代,它们提供了更好的性能和更大的灵活性。

1.2 引入依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>${httpclient.version}</version>
</dependency>
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>${jsoup.version}</version>
</dependency>

向项目中引入HttpClient和Jsoup依赖。

Jsoup用于解析获取的HTML文本,可以像JS一样通过id和class获取元素。同时Jsoup也可访问页面。

1.3 创建简单的请求操作

1.3.1 创建实例

public void testLinked() throws Exception {
	// 创建HttpClient对象
   CloseableHttpClient httpClient = HttpClients.createDefault();

   // 创建GET请求
   HttpGet httpGet = new HttpGet("https://blog.csdn.net/weixin_43347659");
   httpGet.setHeader("use-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");

   // 获取响应结果
   CloseableHttpResponse response = httpClient.execute(httpGet);

   if (response.getStatusLine().getStatusCode() == 200) {
       String html = EntityUtils.toString(response.getEntity(), "UTF-8");
       System.out.println(html);
   }

   httpClient.close();
   response.close();
}

HttpClient用于创建连接对象,如果请求方式为GET则可以创建HttpGet对象,若为POST请求可创建HttpPost对象,请求的参数为待访问的URL。

可以根据实际请求内容适当的增加header的内容。调用HttpClientexecute()方法发起请求,并创建一个CloseableHttpResponse响应对象,可以通过判断响应状态码确定请求的结果。

根据现在的一些防爬虫设置,可能需要在header添加固定的请求内容,例如hostorigin等内容区分人机,可根据实际情况设置。

1.3.2 Jsoup应用

@Test
public void testJsoup() throws Exception {
    // 创建HttpClient
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 创建GET请求
    HttpGet httpGet = new HttpGet("https://www.cnblogs.com/sam-uncle/category/1469093.html");
    httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");

    // 获取响应
    CloseableHttpResponse response = httpClient.execute(httpGet);

    // 获取页面内容
    if (response.getStatusLine().getStatusCode() == 200) {
        String html = EntityUtils.toString(response.getEntity(), "UTF-8");

        // 创建Document对象
        Document document = Jsoup.parse(html);

        // 获取博客列表
        Element blog = document.getElementsByClass("entrylist").first();
        Elements blogList = blog.getElementsByClass("entrylistItem");
        for (Element element : blogList) {
            Elements title = element.select("a[class='entrylistItemTitle'] span");
            System.out.println(title.text());
        }
    }

    response.close();
    httpClient.close();
}

通过调用Jsoupparse(String html)方法即可将原始的HTML页面解析为Document类,这样我们就能够通过getElementById(String attr)getElementsByClass(String attr)select(String classAttr)等方式获取页面中的标签元素。

Document类为org.jsoup.nodes.Document注意不要使用错类。

1.4 爬取过程中可能出现的问题

1.4.1 JS异步加载问题

随着前端技术的发展,在页面中应用AJAX、VUE和AngularJS等技术已经很普及,因此在使用HttpClient时会发现,响应的结果与页面不相同,或者响应的页面并没有所需的内容。

因此可以从其他的思路来实现,例如我们可以通过访问内部接口获取响应值,通过这种方法可以跳过对页面的分析,直接获取想要的结果。主要难点在于分析该内容调用的接口。

例如我们查看CSDN的博客页面,点击搜索框可看到CSDN会推送热门的搜索信息,但是如果查看当前页面的网页源码是无法搜索到该内容的。

在这里插入图片描述

此时我们可以打开F12,查看页面的所有请求

在这里插入图片描述

此时我们可以只选择Fetch/XHR查看页面所有调用的接口,从中找到正确的接口。根据实际请求中携带参数和header的信息,编写代码。

@Test
public void testApi() {
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpGet httpGet = new HttpGet("https://silkroad.csdn.net/api/v2/assemble/list/channel/search_hot_word?new_hot_flag=1&channel_name=pc_hot_word&size=20&user_name=weixin_43347659&platform=pc&imei=10_20960811560-1623721797026-245775");
    httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
    httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
    httpGet.setHeader("Content-Type", "application/json;charset=UTF-8");
    httpGet.setHeader("Origin", "https://blog.csdn.net");
    httpGet.setHeader("Accept-Encoding", "gzip, deflate, br");

    try {
    	CloseableHttpResponse response = httpClient.execute(httpGet);

    	if (response.getStatusLine().getStatusCode() == 200) {
    		System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));
		}
    } catch (IOException e) {
    	e.printStackTrace();
    } finally {
        response.close();
    }
    
    httpClient.close();
}

一般勾选保留日志停用缓存已防止页面发生重定向时丢失以前的请求内容。

1.4.2 反爬技术的影响

具体可查看知乎贴做爬虫怎可不知反爬虫?如何做反反爬虫。

1.5 爬取需要登录的页面

当需要获取登录后的页面信息时,就绕不开Cookie的问题。在请求时携带正确的Cookie值可直接跳过登录操作。该问题可通过两种方案解决。

1.5.1 在header中直接携带Cookie

在设置请求头时,可以直接绑定Cookie值,该Cookie值可以通过实际访问时查看请求内容获取,示例:

@Test
public void testCookie() throws Exception {
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpGet httpGet = new HttpGet("https://mall.csdn.net/myorder?spm=1001.2014.3001.5137");
    httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
    httpGet.setHeader("Cookie", "yourCookie");

    CloseableHttpResponse response = httpClient.execute(httpGet);
    if (response.getStatusLine().getStatusCode() == 200) {
        System.out.println("==============================开始打印页面==============================");
        System.out.println(EntityUtils.toString(response.getEntity()));
        System.out.println("==============================结束打印页面==============================");
    }

    httpClient.close();
    response.close();
}

对于携带Cookie的方式登录存在一个问题,就是cookie存在有效期,当有效期过了之后就需要重新更换cookie,所以如果需要持续性的自动爬取数据,就存在很大弊端。

1.5.2 模拟登录自动获取Cookie

在发送请求时可以将登录信息添加到HttpPost中去尝试请求登录,如果登录成功,登录后的Cookie会保留在HttpClient中,再请求其他页面时则会跳过登录。

以CSDN的登录为例,通过F12查找登录接口,根据请求头信息,配置HttpPost

@Test
public void testLogin() throws Exception {
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("https://passport.csdn.net/v1/register/pc/login/doLogin");
    httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
    httpPost.setHeader("Accept", "application/json, text/plain, */*");
    httpPost.setHeader("Accept-Encoding", "gzip, deflate, br");
    httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
    httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
    httpPost.setHeader("Host", "passport.csdn.net");
    httpPost.setHeader("Origin", "https://passport.csdn.net");
    httpPost.setHeader("Referer", "https://passport.csdn.net/login?code=applets");

    // 配置登录参数
    List<NameValuePair> pairList = new ArrayList<NameValuePair>();
    pairList.add(new BasicNameValuePair("loginType", "1"));
    pairList.add(new BasicNameValuePair("pwdOrVerifyCode", "password"));
    pairList.add(new BasicNameValuePair("uaToken", ""));
    pairList.add(new BasicNameValuePair("userIdentification", "username"));
    pairList.add(new BasicNameValuePair("webUmidToken", ""));

    httpPost.setEntity(new UrlEncodedFormEntity(pairList, HTTP.UTF_8));

    CloseableHttpResponse response = httpClient.execute(httpPost);

    if (response.getStatusLine().getStatusCode() == 200) {
        System.out.println("登录成功");
        // 这里要注销请求,否则会影响后续的请求
        httpPost.abort();

        HttpGet httpGet = new HttpGet("https://mall.csdn.net/myorder?spm=1001.2014.3001.5137");
        httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");

        CloseableHttpResponse response1 = httpClient.execute(httpGet);
        if (response1.getStatusLine().getStatusCode() == 200) {
            System.out.println("==============================开始打印页面==============================");
            System.out.println(EntityUtils.toString(response1.getEntity()));
            System.out.println("==============================结束打印页面==============================");
        }
        response1.close();
    }

    response.close();
    httpClient.close();
}

该案例为失败案例,由于登录方式多变,可能出现的验证码等人机校验,导致用户登录的难度加大,例如上述案例,直接访问登录接口后,会直接重定向到人机验证界面,导致无法正常登录。有些页面也存在在前端进行密码加密,导致无法获取正确的密码。

因此上述例子只是提供一个思路。

二、HtmlUtil实现JS异步加载页面

2.1 HtmlUtil

htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。是一个没有界面的浏览器,运行速度迅速。是junit的扩展之一。

2.2 引入依赖

<dependency>
	<groupId>net.sourceforge.htmlunit</groupId>
	<artifactId>htmlunit</artifactId>
	<version>${htmlutil.version}</version>
</dependency>

2.3 创建简单的请求操作

2.3.1 创建实例

@Test
public void testLinked() {
    try (WebClient webClient = new WebClient(BrowserVersion.CHROME)) {
        webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常
        webClient.getOptions().setActiveXNative(false);
        webClient.getOptions().setCssEnabled(false);//是否启用CSS
        webClient.getOptions().setJavaScriptEnabled(true); //很重要,启用JS
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要,设置支持AJAX

        //开始请求网站
        HtmlPage loginPage = webClient.getPage("https://ent.sina.com.cn/film/");
        webClient.waitForBackgroundJavaScript(30000);//该方法阻塞线程

        System.out.println("=================开始打印页面=================");
        System.out.println(loginPage.asXml());
        System.out.println("=================结束打印页面=================");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

对webClient的配置很重要,尤其是setAjaxController()方法,使得模拟页面可以支持AJAX异步加载。

对于Vue和AngularJS渲染的页面HtmlUtil在其处理上也不是太好,加载JS也只能加载原始页面中包含的内容,

2.3.2 模拟浏览器操作

HtmlUtil可以创建一个无界面的浏览器,所以可以通过代码对文本框赋值和进行点击操作,完成一些简单的操作。示例:

@Test
public void testSearch() {
    WebClient webClient = new WebClient(BrowserVersion.CHROME);

    // 设置当前的AJAX控制器
    webClient.setAjaxController(new NicelyResynchronizingAjaxController());
    // 设置CSS支持
    webClient.getOptions().setCssEnabled(false);
    // 设置JavaScript是否启用
    webClient.getOptions().setJavaScriptEnabled(true);
    // 设置ActiveX是否启用
    webClient.getOptions().setActiveXNative(false);
    // 设置访问错误时是否抛出异常
    webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
    // 设置JS报错时是否抛出异常
    webClient.getOptions().setThrowExceptionOnScriptError(false);

    try {
        HtmlPage htmlPage = webClient.getPage("https://www.csdn.net/");
        // 阻塞当前线程,直到指定时间后结束
        webClient.waitForBackgroundJavaScript(10*1000);

        // 获取搜索框
        HtmlInput search = (HtmlInput) htmlPage.getByXPath("//*[@id=\"toolbar-search-input\"]").get(0);
        search.setAttribute("value", "HtmlUtil用法");

        // 点击搜索
        HtmlButton button = (HtmlButton) htmlPage.getByXPath("//*[@id=\"toolbar-search-button\"]").get(0);
        HtmlPage newHtmlPage = button.click();

        System.out.println("=============打印页面=============");
        System.out.println(newHtmlPage.asXml());
        System.out.println("=============打印页面=============");
    } catch (IOException e) {
    	e.printStackTrace();
    }

}

该示例通过访问CSDN的首页,为搜索框赋值,操作点击后可获取搜索结果。

由于CSDN的搜索结果是通过Vue框架加载,所以无法获取到最终的结果。

2.4 爬取待登录的页面

操作与2.3.2节类似,主要思路为获取登录页面,为表单元素添加用户名和密码,再通过click()方法点击登录按钮,提交表单,登录成功后会自动将cookie存放在WebClient中,可通过WebClient再次访问其他需要登录的页面。

相较于HttpClient,HtmlUtil可以直接操作页面比访问接口相对容易,但是针对于Vue框架和需要验证码登录的页面还是存在问题。


参考资料:

HtmlUnit 官网

HtmlUtil API文档

HttpClient 官网

HttpClient API文档

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java】使用Java实现爬虫 的相关文章

  • 滤波、传感器融合、IMU合GPS可以测量哪些物理量

    目录 结论IMU加速度计陀螺仪GPS 原理加速度计陀螺仪GPS 传感器融合滤波算法线性互补滤波卡尔曼滤波KF扩展卡尔曼滤波EKF 小结 结论 IMU paxhawk pixhack自带的IMU xff08 惯性测量模块 xff09 包含以下
  • 学习过程中提出的疑问

    目录 如何在simulink中编译两个应用并烧录到飞控中 xff1f 如何自定义地面站QGC接收到的MAVLink消息 xff1f xff08 MAVLink inspector xff09 航点 航路生成器 xff1f 如何在simuli
  • PX4学习笔记

    目录 网址PX4 io网页指导Pixhawk PX4 APM ArduPilot关系硬件照片 示意图逻辑图 集多旋翼控制框架软件框架 辅助工具 软件 使用方法source insight新建工程 导入PX4源码source insight
  • H无穷控制理论与应用案例分析

    0 知识背景 概念 定义 内稳定 xff1a BIBO稳定 xff1a 镇定 xff1a 对于一个控制系统来说 xff0c 如果通过某种反馈可以使系统实现渐近稳定 xff0c 即闭环系统极点具有负实部 xff0c 则称该系统是能镇定的 信号
  • ADRC从入门到放弃0

    ADRC xff1a 自抗扰控制器 其中 xff0c 在对自抗扰理论的 研究中 xff0c 引入了带宽概念这一个崭新的思路 xff0c 极大的简化了自抗扰技术使用时参数整定 的问题 xff0c 同时时域分析的方法可以发现利用带宽的概念还有利
  • 直升机建模

    目录 引子tips模型的组成 引子 duck不必陷入细节 xff0c 比如坐标转换 xff0c 忽而略微小项目 tips x 表示两个向量的叉乘 模型的组成 刚体运动学 xff1a 描述平移运动与转动运动 xff0c 即位移 xff08 线
  • 模糊PID(自适应模糊PID、fuzzy PID)的基本原理及应用举例 by 研三笔记

    目录 1 控制框图2 概述3 基本原理3 1 一些基本的概念 定义3 2 模糊化3 3 模糊推理3 4 清晰化 xff08 解模糊 反模糊化 xff09 3 5 模糊PID3 6 使用 fis文件 4 利用matlab模糊控制工具箱设计模糊
  • 3d目标检测

    目录 知网论文阅读笔记关键词 key words现状 摘要 碎片知识点3D检测算法分类根据其使用的数据类型为三类 xff1a 按照点云不同的特征表达方式分类 1 xff1a 其他分类方法 1 xff1a 根据传感器分类 2 xff1a 根据
  • kex_exchange_identification: Connection closed by remote hostConnection closed by ::1 port 22

    kex exchange identification Connection closed by remote hostConnection closed by 1 port 22 缘起 拉代码仓库出错 xff0c 还挺常见 https 错
  • 基于线性矩阵不等式LMI的鲁棒H无穷控制算法设计,多性能指标的H无穷控制算法推导,多面体模型

    catalogue 关键字一些符号和特殊表示预备知识正文 xff08 一 xff09 不确定系统的数学表示 xff08 二 xff09 线性时不变定常系统的LMI稳定性定理 xff08 判据 xff09 2 1 系统模型2 2 当u 61
  • python与其他语言的不同之处--语法拾遗

    八戒你说呢 基本语法空行的使用行与缩进import 与 from import命令行参数变量的使用列表Tuple xff08 元组 xff09 Set xff08 集合 xff09 Dictionary xff08 字典 xff09 Pyt
  • 深度学习入门篇1

    1 目前流行的深度学习框架简介 深度学习框架 xff08 点击跳转 xff09 2 神经网络工具箱torch autograd与torch nn torch autograd库虽然实现了自动求导与梯度反向传播 xff0c 但如果我们要完成一
  • 3D点云的基本操作(基于PCL编程)

    知识储备 右手系 右手 xff0c 拇指 xff0c 食指 xff0c 中指 xff0c 分别是x y z的正方向 左手系则同理 旋转矩阵 本质 xff1a 两个坐标系之间的旋转关系 用途 xff1a 旋转点云 原理 xff1a 设传感器的
  • uCOS-III 应用开发指南—基于 STM32F103系列

    uCOS III 应用开发指南 基于 STM32F103系列 嵌入式经典教材 实例截图 文件 xff1a 590m com f 25127180 490253580 defdec xff08 访问密码 xff1a 551685 xff09
  • 无人机飞行控制源码(android)

    旨在为大学生 航模爱好者 创客提供可二次开发的迷你四轴飞行器原型 是一个完全开源的项目 xff0c 包括源代码 xff0c 原理图 xff0c 设计思路等 可以通过它学习四轴飞行器相关知识 xff0c 也可以在上面进行二次开发 xff0c
  • 通过git下载github分支(最详细)

    文章目录 一 git下载指定分支代码到本地A 前提 xff1a B 具体步骤 xff1a 二 git下载github所有分支代码到本地具体步骤 xff1a 一 git下载指定分支代码到本地 任务一 xff1a 下载地址为https gith
  • CSS基线对齐的理解以及处理

    相信大家都会遇到同行不同盒子中文本的内容不能对齐的情况 xff0c 而不知道这是为何 xff1f 其实这是因为基线对齐的原因 什么是基线对齐 xff1f 先让我们来看一张图片 xff1a 到这里我们的疑惑是不是少了一些 xff1f 基线对齐
  • Eigen求解大型稀疏对称矩阵(Cholesky分解)

    参考自Eigen文档 代码如下 xff1a span class token macro property span class token directive hash span span class token directive ke
  • CMake的基本使用方法与install命令

    源代码 main cpp文件如下 span class token macro property span class token directive hash span span class token directive keyword
  • docker常用命令总结

    docker常用命令总结 span class token function uname span span class token parameter variable r span span class token comment 查看

随机推荐

  • 基于STC15的飞控设计(1)飞控电路设计

    前言 学校举办的无人机比赛 xff0c 要求使用stc15系列芯片设计飞控 xff0c 然后完成一台四轴的无人机进行穿越障碍的比赛 xff0c 第一次设计飞控 xff0c 如果有什么设计得不好的希望大家多多指教 这个博客算是制作流程的记录
  • STM32F407霸天虎FreeRTOS学习笔记——移植FreeRTOS到开发板上

    STM32F407霸天虎FreeRTOS学习笔记 移植FreeRTOS到开发板上 FreeRTOS源码获取移植第一步 xff1a 创建文件夹Keilmain c 实验效果 FreeRTOS源码获取 在移植之前 xff0c 首先要获取到 Fr
  • 倒立摆及其应用//2021-2-23

    前言 xff1a 以前搞电赛的时候搞过Pid平衡小车 xff0c 倒立摆基本实现方法与平衡小车差不多 xff0c 有一次刚院跑到实验室唠嗑 xff0c 问你知不知道倒立摆的应用 xff1f 我说不知道 xff0c 他说航天火箭 xff0c
  • TypeError: Cannot convert a symbolic Keras input/output to a numpy array.

    问题类型 TypeError Cannot convert a symbolic Keras input output to a numpy array This error may indicate that you re trying
  • 自己的学习记录

    从今天开始学习如何使用Java来写数据库课程设计的作业 xff01 xff01 xff01
  • Tsai分享:资源分享(1)——视觉SLAM十四讲及视频

    Tsai分享 xff1a 资源分享 xff08 1 xff09 视觉SLAM十四讲及视频 一 视觉SLAM十四讲 如若转载请附上链接 xff1a https blog csdn net weixin 43338642 article det
  • pycharm如何查看python文件的工作目录

    在找bug的过程中发现python文件的工作目录和存放目录地址有可能是不一样的 xff0c pathlib路径操作中的pathlib Path cwd 获取的是工作目录而不是存放目录地址发现工作目录和存放目录地址不同的时候一定要修改过来 x
  • C++中vector的用法详解

    文章目录 构造函数增加函数删除函数遍历函数判断函数大小函数交换函数赋值函数改变空间 构造函数 span class token comment vector 创建一个空vector span vector span class token
  • 华为技术面

    文章目录 手撕代码流程题目描述方法介绍面试官评价思维扩展 项目描述技术问题内存说明下C 43 43 的内存分配情况 xff0c 栈和队列的区别以及程序员如何分配回收内存 xff1f C 43 43 程序员和Java程序员有一个很大的区别 x
  • 华东师范大学计算机学硕2023考研经验贴

    文章目录 1 个人经历1 1 一战1 2 二战1 3 心态 2 初试2 1 政治2 2 英语2 3 数学2 4 408 3 复试3 1 机试A 数字猜想B 特殊质数C 最小字符串D 数字排序E 整数分解 3 2 英语面试3 3 综合面试 1
  • Go后端部署服务器

    go后端部署服务器方式一 xff1a xff08 最简单 xff09 和暑假做重点场所项目部署一样 xff0c 简单 xff0c 无脑 xff0c 手动 xff0c 麻烦 span class token number 1 span spa
  • 数据分析实用python程序

    文章目录 1 pdf转txt2 判断txt文件是否为空3 获取txt文件每一行4 获取文件夹所有文件名5 读写xlsx表格6 遍历txt每个字符7 字符串中字符替换 1 pdf转txt span class token comment de
  • 51单片机之数码管

    1 静态数码管原理图 LED数码管根据LED的不同接法分为两类 xff1a 共阴和共阳 为了显示数字或字符 xff0c 必须对数字或字符进行编码 七段数码管加上一个小数点 xff0c 共计8段 因此为LED显示器提供的编码正好是一个字节 共
  • 银行排队模拟(队列)

    银行排队模拟程序 队列类Queue ifndef span class token constant QUEUE H span define span class token constant QUEUE H span struct Rec
  • C/C++中struct和class的区别

    目录 struct class struct和class的区别 struct struct是描述一个数据结构的集合 xff0c 像一周有七天 xff0c 你可以把一周看成是一个结构体 xff0c 然后在结构体里面定义一个数组来存放这个七天
  • java枚举(enum)使用详解

    文章目录 前言一 枚举类型定义二 访问成员三 遍历四 在switch xff08 xff09 中使用枚举五 方法1 内置方法1 1 ordinal 用于返回成员的索引1 2 compareTo 用于比较枚举类型中两个成员的索引值1 3 va
  • 分析url从输入到展过程中的页面优化、performance

    浏览器会开启一个线程处理URL请求 url从输入到展示页面的过程 1 输入网址 2 DNS解析 3 建立tcp连接 xff08 请求队列queuing 请求等待stalled 4 客户端发送HTPP请求 5 服务器处理请求 6 服务器响应请
  • 双重锁单例模式

    不忘初心 xff0c 思考梦开始的地方 普通的懒汉式和饿汉式都不用管 简单实现一下线程安全的方式 span class token keyword public span span class token keyword class spa
  • VScode神仙插件,程序员必备

    前言 Visual Studio Code VS Code 是微软2015年推出的一个轻量但功能强大的源代码编辑器 xff0c 基于 Electron 开发 xff0c 支持 Windows Linux 和 macOS 操作系统 它内置了对
  • 【Java】使用Java实现爬虫

    文章目录 使用Java实现爬虫一 HttpClient实现模拟HTTP访问1 1 HttpClient1 2 引入依赖1 3 创建简单的请求操作1 3 1 创建实例1 3 2 Jsoup应用 1 4 爬取过程中可能出现的问题1 4 1 JS