Java 爬虫零基础入门:从 HTTP 到 Jsoup 实战

🎯 适合人群 :Java 初学者、爬虫新手

⏱️ 阅读时长 :30 分钟

📌 你将收获:掌握 HTTP 请求、Jsoup 解析、实战爬取网页数据


📖 目录


一、爬虫基础知识

1.1 什么是爬虫?

爬虫:自动访问网页并提取数据的程序

应用场景

  • 数据采集(新闻、电商、招聘)
  • 价格监控
  • 竞品分析
  • SEO 监控

1.2 爬虫工作流程

复制代码
① 发送 HTTP 请求 → ② 接收响应(HTML)
③ 解析 HTML → ④ 提取数据 → ⑤ 存储数据

1.3 合法性说明

⚠️ 重要提示

  • ✅ 爬取公开数据
  • ✅ 遵守 robots.txt
  • ❌ 禁止爬取个人隐私
  • ❌ 禁止商业侵权

二、HTTP 请求入门

2.1 使用 HttpURLConnection

java 复制代码
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class SimpleHttpExample {
    
    public static String sendGet(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        
        // 设置请求方法
        conn.setRequestMethod("GET");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        
        // 读取响应
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(conn.getInputStream())
        );
        
        StringBuilder result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line);
        }
        reader.close();
        
        return result.toString();
    }
}

2.2 使用 Apache HttpClient(推荐)

添加依赖

xml 复制代码
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

基础使用

java 复制代码
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;

public class HttpClientExample {
    
    public static String sendGet(String url) throws IOException {
        // 创建 HttpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        
        // 创建 GET 请求
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("User-Agent", "Mozilla/5.0");
        
        // 执行请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
        
        // 获取响应内容
        String html = EntityUtils.toString(response.getEntity(), "UTF-8");
        
        // 关闭资源
        response.close();
        httpClient.close();
        
        return html;
    }
}

三、Jsoup 解析 HTML

3.1 添加依赖

xml 复制代码
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version>
</dependency>

3.2 基础使用

java 复制代码
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class JsoupExample {
    
    public static void main(String[] args) throws IOException {
        // 方式1:从 URL 加载
        Document doc = Jsoup.connect("https://example.com").get();
        
        // 方式2:从 HTML 字符串解析
        String html = "<html><body><h1>标题</h1></body></html>";
        Document doc2 = Jsoup.parse(html);
        
        // 获取标题
        String title = doc.title();
        
        // CSS 选择器
        Elements links = doc.select("a[href]");
        for (Element link : links) {
            String url = link.attr("href");
            String text = link.text();
            System.out.println(text + ": " + url);
        }
    }
}

3.3 CSS 选择器

选择器 说明 示例
tag 标签选择器 doc.select("div")
.class class 选择器 doc.select(".title")
#id id 选择器 doc.select("#content")
[attr] 属性选择器 doc.select("a[href]")
parent > child 子选择器 doc.select("div > p")

四、实战案例

4.1 爬取豆瓣电影 Top250

java 复制代码
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DoubanSpider {
    
    public static void main(String[] args) throws IOException {
        List<Movie> movies = new ArrayList<>();
        
        // 爬取前 3 页
        for (int page = 0; page < 3; page++) {
            String url = "https://movie.douban.com/top250?start=" + (page * 25);
            
            Document doc = Jsoup.connect(url)
                .userAgent("Mozilla/5.0")
                .timeout(5000)
                .get();
            
            // 解析电影列表
            Elements items = doc.select(".item");
            for (Element item : items) {
                String title = item.select(".title").first().text();
                String rating = item.select(".rating_num").first().text();
                String quote = item.select(".inq").text();
                
                Movie movie = new Movie(title, rating, quote);
                movies.add(movie);
                
                System.out.println(movie);
            }
            
            // 休眠避免被封
            Thread.sleep(1000);
        }
    }
}

class Movie {
    private String title;
    private String rating;
    private String quote;
    
    // 构造方法、toString 省略
}

4.2 爬取博客文章

java 复制代码
public class BlogSpider {
    
    public static void main(String[] args) throws IOException {
        String url = "https://blog.csdn.net/xxx/article/list/1";
        
        Document doc = Jsoup.connect(url)
            .userAgent("Mozilla/5.0")
            .get();
        
        // 文章列表
        Elements articles = doc.select(".article-item-box");
        
        for (Element article : articles) {
            String title = article.select("h4 a").text();
            String link = article.select("h4 a").attr("href");
            String summary = article.select(".content").text();
            
            System.out.println("标题: " + title);
            System.out.println("链接: " + link);
            System.out.println("摘要: " + summary);
            System.out.println("---");
        }
    }
}

五、常见问题

5.1 中文乱码

java 复制代码
// 设置编码
String html = EntityUtils.toString(response.getEntity(), "UTF-8");

// Jsoup 设置编码
Document doc = Jsoup.parse(html, "UTF-8");

5.2 请求被拦截

java 复制代码
// 设置 User-Agent
httpGet.setHeader("User-Agent", "Mozilla/5.0");

// 添加更多请求头
httpGet.setHeader("Referer", "https://www.google.com");
httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9");

5.3 超时设置

java 复制代码
// Jsoup 超时
Document doc = Jsoup.connect(url).timeout(10000).get();

// HttpClient 超时
RequestConfig config = RequestConfig.custom()
    .setConnectTimeout(5000)
    .setSocketTimeout(10000)
    .build();
httpGet.setConfig(config);

六、面试题

面试题 1:爬虫的基本流程是什么?

参考答案

  1. 发送 HTTP 请求
  2. 接收 HTML 响应
  3. 解析 HTML(Jsoup)
  4. 提取数据
  5. 存储数据(数据库/文件)

面试题 2:如何处理反爬虫?

参考答案

  1. 设置 User-Agent
  2. 添加请求头(Referer、Cookie)
  3. 设置延时(避免频繁请求)
  4. 使用代理 IP
  5. 处理验证码

面试题 3:Jsoup 和正则表达式的区别?

参考答案

对比 Jsoup 正则表达式
易用性 简单(CSS 选择器) 复杂
健壮性 好(容错)
性能 一般
推荐 小数据量

面试题 4:爬虫如何避免被封?

参考答案

  1. 控制请求频率(延时)
  2. 使用代理 IP 池
  3. 模拟真实用户行为
  4. 遵守 robots.txt
  5. 分布式爬虫

总结

HTTP 请求 :HttpClient、HttpURLConnection

HTML 解析 :Jsoup(CSS 选择器)

实战案例 :豆瓣电影、博客文章

反爬虫:User-Agent、延时、代理

下一篇预告:进阶爬虫技术(动态网页、多线程、WebMagic 框架)

相关推荐
一个public的class10 小时前
前后端 + Nginx + Gateway + K8s 全链路架构图解
前端·后端·nginx·kubernetes·gateway
身如柳絮随风扬1 天前
Dubbo 与 Spring Cloud 终极对比:RPC 框架 vs 微服务生态
spring cloud·rpc·dubbo
一个有温度的技术博主1 天前
Spring Cloud 入门与实战:从架构拆分到核心组件详解
spring·spring cloud·架构
uNke DEPH1 天前
SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
spring cloud·gateway·sentinel
慕容卡卡1 天前
你所不知道的RAG那些事
java·开发语言·人工智能·spring boot·spring cloud
dLYG DUMS1 天前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
ERBU DISH2 天前
当遇到 502 错误(Bad Gateway)怎么办
gateway
Ken_11152 天前
SpringCloud系列(61)--Nacos之服务配置中心的介绍与使用
spring cloud
Ken_11152 天前
SpringCloud系列(62)--Nacos之命名空间、分组和DataID三者之间的关系
spring cloud
Ken_11152 天前
SpringCloud系列(63)--Nacos读取不同配置之DataID配置方案
spring cloud