【爬虫】Java爬虫爬取某招聘网站招聘信息

news2024/11/25 21:24:14

目录

前言

一、爬虫程序的基本架构

二、如何获取目标网站的页面内容

三、解析HTML页面,提取所需信息

四、代理IP的使用

五、完整代码

总结


前言

随着互联网的普及,越来越多的人开始关注网络上的招聘信息,而传统的求职方式愈发显得不够快捷、高效。爬虫技术,则能够帮助我们快速地获取互联网上的招聘信息,从而提高求职的效率。

本文介绍如何使用Java编写爬虫程序,以爬取某招聘网站的招聘信息为例,并采用代理IP提高爬取效率。文章包含以下几个部分:

1. 爬虫程序的基本架构
2. 如何获取目标网站的页面内容
3. 解析HTML页面,提取所需信息
4. 代理IP的使用
5. 完整代码

一、爬虫程序的基本架构

一个基本的爬虫程序通常由三个模块组成:获取页面、解析页面、存储数据。具体实现可以使用各种语言和库,这里我们使用Java和Jsoup库实现爬虫程序。

二、如何获取目标网站的页面内容

获取页面的方法主要有两种:使用HttpURLConnection或使用HttpClient。此处我们使用HttpClient。HttpClient是Apache Jakarta Common Project组织提供的开源Java实现的HTTP客户端软件包。它不仅可以支持HTTP协议,还可以支持HTTPS协议。并且,HttpClient提供了一些扩展功能,例如自动重定向,SSL连接等。

下面是使用HttpClient获取网页内容的示例代码:

public String getHtml(String url) {
    String html = null;
    try {
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建HttpGet请求
        HttpGet httpGet = new HttpGet(url);
        // 执行HttpGet请求,获取HttpResponse响应
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        // 获取HttpEntity实例
        HttpEntity entity = httpResponse.getEntity();
        // 使用EntityUtils工具类将HttpEntity转换成字符串
        html = EntityUtils.toString(entity, "utf-8");
        // 关闭资源
        httpResponse.close();
        httpClient.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return html;
}

三、解析HTML页面,提取所需信息

解析HTML页面的方法通常有两种:使用正则表达式或使用HTML解析器。使用正则表达式可能会更加灵活,但是容易出错。所以,此处我们使用HTML解析器Jsoup。

Jsoup是Java的一个HTML解析器,它可以直接解析某个URL地址、HTML文本内容。它提供了类似于Jquery的语法,再加上一些API操作,可以很灵活的进行HTML解析。

下面是使用Jsoup解析HTML页面并提取信息的示例代码:

public List<Map<String, Object>> parse(String html) {
    List<Map<String, Object>> dataList = new ArrayList<>();
    // 使用Jsoup解析HTML页面
    Document document = Jsoup.parse(html);
    // 获取招聘信息列表
    Elements jobElements = document.select(".newlist .jobList");
    for (Element job : jobElements) {
        Map<String, Object> data = new HashMap<>();
        // 获取招聘信息
        String jobTitle = job.select(".zwmc div a").first().text();
        String jobUrl = job.select(".zwmc div a").first().attr("href");
        String companyName = job.select(".gsmc a").first().text();
        String companyUrl = job.select(".gsmc a").first().attr("href");
        String jobCity = job.select(".gzdd").first().text();
        String jobSalary = job.select(".zwyx").first().text();
        String jobDate = job.select(".gxsj").first().text();
        // 将信息保存到Map里
        data.put("jobTitle", jobTitle);
        data.put("jobUrl", jobUrl);
        data.put("companyName", companyName);
        data.put("companyUrl", companyUrl);
        data.put("jobCity", jobCity);
        data.put("jobSalary", jobSalary);
        data.put("jobDate", jobDate);
        // 将Map添加到列表里
        dataList.add(data);
    }
    return dataList;
}


 

以上代码使用了CSS选择器来定位目标元素,大大简化了解析过程。

四、代理IP的使用

在爬虫过程中,我们需要频繁的向目标网站发送请求,如果每次请求都使用同一个IP地址,就会被目标网站封锁,影响爬取效率。此时,代理IP是一个好的选择。

代理IP是指代理服务器上的IP地址,用来代替客户端发送请求和接收响应。代理IP可以隐藏客户端真实的IP地址,同时可以在一定程度上保护用户的隐私。

使用代理IP的方法也很简单。我们只需要在每次发送请求时,指定使用的代理IP即可。

下面是使用代理IP的示例代码:

public String getHtmlWithProxy(String url, String host, int port) {
    String html = null;
    try {
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建HttpGet请求
        HttpGet httpGet = new HttpGet(url);
        // 设置代理IP和端口
        HttpHost proxy = new HttpHost(host, port);
        RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
        httpGet.setConfig(config);
        // 执行HttpGet请求,获取HttpResponse响应
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        // 获取HttpEntity实例
        HttpEntity entity = httpResponse.getEntity();
        // 使用EntityUtils工具类将HttpEntity转换成字符串
        html = EntityUtils.toString(entity, "utf-8");
        // 关闭资源
        httpResponse.close();
        httpClient.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return html;
}

五、完整代码

以下是完整的爬虫程序代码:

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.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JobSpider {
    private static final String ZHAOPIN_URL = "https://sou.zhaopin.com/jobs/searchresult.ashx";

    public static void main(String[] args) {
        String keyword = "Java";
        String city = "北京";
        int start = 0;
        int count = 60;

        JobSpider spider = new JobSpider();
        List<Map<String, Object>> dataList = spider.spiderJobInfo(keyword, city, start, count);
        System.out.println(dataList);
    }

    public List<Map<String, Object>> spiderJobInfo(String keyword, String city, int start, int count) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        try {
            // 爬取数据
            for (int i = start; i < start + count; i += 60) {
                // 构造请求参数
                String url = String.format("%s?jl=%s&kw=%s&start=%d", ZHAOPIN_URL, city, keyword, i);
                // 获取页面HTML
                String html = getHtmlWithProxy(url, "127.0.0.1", 1080);
                // 解析HTML页面,提取信息
                List<Map<String, Object>> jobList = parse(html);
                // 将解析结果添加到结果集中
                dataList.addAll(jobList);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataList;
    }

    public String getHtml(String url) {
        String html = null;
        try {
            // 创建HttpClient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();
            // 创建HttpGet请求
            HttpGet httpGet = new HttpGet(url);
            // 执行HttpGet请求,获取HttpResponse响应
            CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
            // 获取HttpEntity实例
            HttpEntity entity = httpResponse.getEntity();
            // 使用EntityUtils工具类将HttpEntity转换

成字符串
            html = EntityUtils.toString(entity, "utf-8");
            // 关闭资源
            httpResponse.close();
            httpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return html;
    }

    public String getHtmlWithProxy(String url, String host, int port) {
        String html = null;
        try {
            // 创建HttpClient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();
            // 创建HttpGet请求
            HttpGet httpGet = new HttpGet(url);
            // 设置代理IP和端口
            HttpHost proxy = new HttpHost(host, port);
            RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
            httpGet.setConfig(config);
            // 执行HttpGet请求,获取HttpResponse响应
            CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
            // 获取HttpEntity实例
            HttpEntity entity = httpResponse.getEntity();
            // 使用EntityUtils工具类将HttpEntity转换成字符串
            html = EntityUtils.toString(entity, "utf-8");
            // 关闭资源
            httpResponse.close();
            httpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return html;
    }

    public List<Map<String, Object>> parse(String html) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        // 使用Jsoup解析HTML页面
        Document document = Jsoup.parse(html);
        // 获取招聘信息列表
        Elements jobElements = document.select(".newlist .jobList");
        for (Element job : jobElements) {
            Map<String, Object> data = new HashMap<>();
            // 获取招聘信息
            String jobTitle = job.select(".zwmc div a").first().text();
            String jobUrl = job.select(".zwmc div a").first().attr("href");
            String companyName = job.select(".gsmc a").first().text();
            String companyUrl = job.select(".gsmc a").first().attr("href");
            String jobCity = job.select(".gzdd").first().text();
            String jobSalary = job.select(".zwyx").first().text();
            String jobDate = job.select(".gxsj").first().text();
            // 将信息保存到Map里
            data.put("jobTitle", jobTitle);
            data.put("jobUrl", jobUrl);
            data.put("companyName", companyName);
            data.put("companyUrl", companyUrl);
            data.put("jobCity", jobCity);
            data.put("jobSalary", jobSalary);
            data.put("jobDate", jobDate);
            // 将Map添加到列表里
            dataList.add(data);
        }
        return dataList;
    }
}

总结

本文介绍了如何使用Java编写爬虫程序,以爬取某招聘网站的招聘信息为例,并采用代理IP提高爬取效率。本文主要包括爬虫程序的基本架构、如何获取目标网站的页面内容、解析HTML页面,提取所需信息、代理IP的使用以及完整代码和运行截图等内容。

爬虫技术无疑为我们提供了更多的信息来源,但在使用时也需要注意合法性,尊重网站的规则和隐私,避免对网站造成不友好的影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1186594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

壹基金防灾减灾宣传进社区 提升家庭安全能力

11月7日&#xff0c;瑞金市赋能济困公益协会、蓝天救援队等联合沙洲坝镇红都新城社区一起走进梦想家园小区&#xff0c;开展家庭安全计划社区活动包挑战赛活动暨壹基金安全家园项目防灾减灾宣传社区行活动。 活动中&#xff0c;志愿者针对从洪涝灾害、风灾、火灾、雪灾、地质灾…

k8s:kubectl 详解

目录 1 kubectl 2 基本信息查看 2.1 查看 master 节点状态 2.2 查看命名空间 2.3 查看default命名空间的所有资源 2.4 创建命名空间app 2.5 删除命名空间app 2.6 在命名空间kube-public 创建副本控制器&#xff08;deployment&#xff09;来启动Pod&#xff08;nginx-wl…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(二)

新增员工功能开发 1. 新增员工1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.2 代码开发1.2.1 设计DTO类1.2.2 Controller层1.2.3 Service层接口1.2.4 Service层实现类1.2.5 Mapper层 1.3 功能测试1.3.1 接口文档测试 1.4 代码完善1.4.1 问题一1.4.2 问题二1.…

从零开始的C++(十四)

继承&#xff1a; 作用&#xff1a;减少重复代码&#xff0c;简化程序。 用法&#xff1a; class b&#xff1a;public a {//...b中成员 } 在如上代码中&#xff0c;b类以public的方式继承了a类。规定a类是父类、基类&#xff0c;b类是子类、派生类。 关于继承方式&#xf…

Tcl语言:SDC约束命令create_generated_clock详解(下)

相关阅读 Tcl语言https://blog.csdn.net/weixin_45791458/category_12488978.html?spm1001.2014.3001.5482 设定生成时钟特性 前文的末尾提到&#xff0c;当使用-divide by或-multiply_by选项创建生成时钟时&#xff0c;会根据master clock的时钟周期派生出生成时钟的周期&am…

【Java 进阶篇】Java Filter 快速入门

欢迎来到这篇有关 Java Filter 的快速入门指南&#xff01;如果你是一名 Java 开发者或者正在学习 Java Web 开发&#xff0c;Filter 是一个强大的工具&#xff0c;可以帮助你管理和控制 Web 应用程序中的请求和响应。本文将向你解释 Filter 的基本概念&#xff0c;如何创建和配…

安全认证框架Shiro入门学习(shiro概述和shiro入门小案例);后续整合SpringBoot,应用程序安全;

权限概述 什么是权限 什么是权限 权限管理&#xff0c;一般指根据系统设置的安全策略或者安全规则&#xff0c;用户可以访问而且只能访问自己被授权的资源&#xff0c;不多不少。权限管理几乎出现在任何系统里面&#xff0c;只要有用户和密码的系统。 权限管理再系统中一般分…

小米6安装Ubuntu Touch系统也不是很难嘛

序言 这个文章是用来解说,小米6如何安装Ubuntu Touch系统 正文 安装这个系统需要注意的几点 1.手机必须已经解BL锁 2.没了 安装步骤 先双击打开压缩包查看,按照第一步第二步来进行执行,下面是解压图片 第一步 1.打开第一个文件夹 复制刷入rec的命令.txt里面的内容,然后打开红…

pytorch(小土堆)深度学习

第五节课讲项目的创建和对比 第六节&#xff1a;Dataset,Dataloader Dataset提供一种方式区获取数据及其label(如何获取每一个数据及其label&#xff0c;告诉我们总共有多少的数据) Dataloader为后面的网络提供不同的数据形式 第七节&#xff1a;Dataset类代码实战 显示图片 f…

挑战100天 AI In LeetCode Day05(热题+面试经典150题)

挑战100天 AI In LeetCode Day05&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-72.1 题目2.2 题解 三、面试经典 150 题-73.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&am…

开源的全能维护 U 盘工具:Ventoy

开源的全能维护 U 盘工具&#xff1a;Ventoy 本篇文章聊聊迄今为止&#xff0c;我用着最舒服的一款开源 U 盘启动工具&#xff0c;Ventoy。 写在前面 好久不见&#xff0c;接下来计划写一个比较连续的内容&#xff0c;就先从最小的处着手吧。 经过长久的折腾&#xff0c;除…

Docker本地镜像发布到阿里云或私有库

本地镜像发布到阿里云流程 &#xff1a; 1.自己生成个要传的镜像 2.将本地镜像推送到阿里云: 阿里云开发者平台:开放云原生应用-云原生&#xff08;Cloud Native&#xff09;-云原生介绍 - 阿里云 2.1.创建仓库镜像&#xff1a; 2.1.1 选择控制台&#xff0c;进入容器镜像服…

Makefile 总述

目录 一、Makefile 里有什么&#xff1f; 1、显式规则 2、隐晦规则 3、变量的定义 4、文件指示 5、注释 二、Makefile 的文件名 三、引用其它的 Makefile 四、环境变量 MAKEFILES 五、make 的工作方式 一、Makefile 里有什么&#xff1f; Makefile 里主要包含了五个东…

Ps:图层蒙版的基本操作

点击图层蒙版缩览图选中图层蒙版之后&#xff0c;方可进行图层蒙版的操作。 反相蒙版 Invert 将图层蒙版上的白色转换为黑色&#xff0c;黑色转换为白色。 方法一&#xff1a; Ps菜单&#xff1a;图像/调整/反相 Adjustments/Invert 方法二&#xff1a; 快捷键&#xff1a;Ctrl…

window10单机部署hbase-2.5.5-hadoop3

一、介绍 hbase是什么&#xff0c;Hbase是一个分布式&#xff0c;可扩展&#xff0c;支持海量数据存储的noSQL数据库 二、下载hbase https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.5.6/ 三、配置hbase环境变量 三、修改hbase配置文件 在hbase-env.cmd添加如下配置…

【算法-链表2】反转链表 和 两两交换链表节点

今天&#xff0c;带来链表相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 反转链表 1. 思路 链表操作的本质是修改连接关系&#xff0c;本题我们需要反转链表&#xff0c;也就是每次都让当前节点的next指向自己的上一个。而题目给的是单链表&#xf…

Linux tail命令:显示文件结尾的内容

tail 命令和 head 命令正好相反&#xff0c;它用来查看文件末尾的数据&#xff0c;其基本格式如下&#xff1a; [rootlocalhost ~]# tail [选项] 文件名 此命令常用的选项及含义 【例 1】查看 /etc/passwd 文件最后 3 行的数据内容。 [rootlocalhost ~]# tail -n 3 /etc/passwd…

jmeter接口自动化部署jenkins教程

首先&#xff0c;保证本地安装并部署了jenkins&#xff0c;jmeter&#xff0c;xslproc 我搭建的自动化测试框架是jmeterjenkinsxslproc ---注意&#xff1a;原理是&#xff0c;jmeter自生成的报告jtl文件&#xff0c;通过xslproc工具&#xff0c;再结合jmeter自带的模板修改&…

Linux - 进程程序替换 - C/C++ 如何实现与各个语言之间的相互调用 - 替换环境变量

前言 我们之前利用 fork&#xff08;&#xff09;函数来创建子进程&#xff0c;这种方式是 父子进程 共用一个代码&#xff0c;只是在代码当中使用了 if-else 语句来分流&#xff0c;达到父子进程运行不同的代码块的目的。但是其实本质上&#xff0c;还是父子共用一个代码和数…

C进阶-编译环境与预处理

本章重点&#xff1a; 程序的翻译环境 程序的执行环境 详解&#xff1a;C语言程序的编译链接 预定义符号介绍 预处理指令#define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令#include 预处理指令#undef 条件编译 1. 程序的翻译环境和执行环境 在ANSI C的任何一…