本文目录导读:

我来为你详细介绍Java实现爬虫的几种常见方案和完整案例。
基础爬虫方案
Maven依赖配置
<dependencies>
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- HTML解析器 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.3</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
简单爬虫示例 - 抓取网页内容
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class SimpleCrawler {
public static void main(String[] args) {
String url = "https://example.com/news";
crawl(url);
}
public static void crawl(String url) {
try {
// 发送HTTP请求并获取HTML文档
Document document = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.timeout(5000)
.get();
// 解析标题
String title = document.title();
System.out.println("页面标题: " + title);
// 提取所有链接
Elements links = document.select("a[href]");
for (Element link : links) {
String href = link.attr("abs:href");
String text = link.text();
System.out.println("链接: " + text + " -> " + href);
}
// 提取特定元素
Elements newsItems = document.select(".news-item");
for (Element item : newsItems) {
String title_text = item.select(".title").text();
String desc = item.select(".description").text();
System.out.println("新闻标题: " + title_text);
System.out.println("描述: " + desc);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
高级爬虫框架 - WebMagic
添加依赖
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.5</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.5</version>
</dependency>
WebMagic爬虫示例
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
public class WebMagicCrawler implements PageProcessor {
// 配置爬虫设置
private Site site = Site.me()
.setRetryTimes(3) // 重试次数
.setSleepTime(1000) // 请求间隔
.setTimeOut(10000) // 超时时间
.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
@Override
public void process(Page page) {
// 爬取列表页
if (page.getUrl().regex("https://example.com/list/\\d+").match()) {
// 添加分页链接到待爬取队列
page.addTargetRequests(page.getHtml().links().regex("https://example.com/list/\\d+").all());
// 添加详情页链接到待爬取队列
page.addTargetRequests(page.getHtml().links().regex("https://example.com/detail/\\d+").all());
}
// 爬取详情页
if (page.getUrl().regex("https://example.com/detail/\\d+").match()) {
// 提取数据
String title = page.getHtml().xpath("//h1[@class='title']/text()").get();
String content = page.getHtml().xpath("//div[@class='content']/html()").get();
String author = page.getHtml().css(".author", "text").get();
String date = page.getHtml().xpath("//span[@class='date']/text()").get();
// 保存数据到resultItems
page.putField("title", title);
page.putField("content", content);
page.putField("author", author);
page.putField("date", date);
page.putField("url", page.getUrl().toString());
}
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
// 启动爬虫
Spider.create(new WebMagicCrawler())
.addUrl("https://example.com/list/1") // 起始URL
.addPipeline(new ConsolePipeline()) // 控制台输出
.addPipeline(new JsonFilePipeline("data")) // 保存为JSON文件
.thread(5) // 线程数
.run(); // 运行
}
}
使用HttpClient + Jsoup
完整爬虫工具类
import org.apache.http.HttpEntity;
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.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AdvancedCrawler {
private CloseableHttpClient httpClient;
private Map<String, String> headers;
public AdvancedCrawler() {
this.httpClient = HttpClients.createDefault();
this.headers = new HashMap<>();
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
headers.put("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
}
// 获取网页内容
public String getPageContent(String url) throws IOException {
HttpGet httpGet = new HttpGet(url);
// 设置请求头
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity, "UTF-8");
}
}
// 解析并提取数据
public void parseAndExtract(String html) {
Document doc = Jsoup.parse(html);
// 使用CSS选择器
Elements elements = doc.select("div.article");
for (Element element : elements) {
String title = element.select("h2.title").text();
String summary = element.select("p.summary").text();
String link = element.select("a").attr("href");
System.out.println("标题: " + title);
System.out.println(" " + summary);
System.out.println("链接: " + link);
}
// 使用正则表达式提取邮箱
String text = doc.text();
Pattern emailPattern = Pattern.compile("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b");
Matcher matcher = emailPattern.matcher(text);
while (matcher.find()) {
System.out.println("邮箱: " + matcher.group());
}
}
// 带会话的爬取(处理登录等)
public void crawlWithSession() throws IOException {
// 实现登录并维持会话
CloseableHttpClient sessionClient = HttpClients.custom()
.setDefaultRequestConfig(null)
.build();
// 添加Cookie处理
// 实际使用时需要添加CookieStore
}
public static void main(String[] args) {
AdvancedCrawler crawler = new AdvancedCrawler();
try {
String content = crawler.getPageContent("https://example.com");
crawler.parseAndExtract(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据持久化 - 保存到数据库
import java.sql.*;
import java.util.List;
import java.util.ArrayList;
public class DataPersistence {
private Connection connection;
public DataPersistence() {
// 初始化数据库连接
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/crawler",
"username",
"password"
);
} catch (Exception e) {
e.printStackTrace();
}
}
// 保存爬取的数据
public void saveArticle(String title, String content, String url) {
String sql = "INSERT INTO articles (title, content, url, crawl_time) VALUES (?, ?, ?, NOW())";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
pstmt.setString(1, title);
pstmt.setString(2, content);
pstmt.setString(3, url);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 批量保存
public void batchSave(List<Article> articles) {
String sql = "INSERT INTO articles (title, content, url) VALUES (?, ?, ?)";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
for (Article article : articles) {
pstmt.setString(1, article.getTitle());
pstmt.setString(2, article.getContent());
pstmt.setString(3, article.getUrl());
pstmt.addBatch();
}
pstmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 文章实体类
static class Article {
private String title;
private String content;
private String url;
// getters and setters
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
}
}
反爬虫处理
import java.util.Random;
public class AntiCrawlStrategy {
private static Random random = new Random();
// 随机User-Agent
private static String[] USER_AGENTS = {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15",
"Mozilla/5.0 (iPad; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15"
};
// 获取随机User-Agent
public static String getRandomUserAgent() {
return USER_AGENTS[random.nextInt(USER_AGENTS.length)];
}
// 添加请求延迟
public static void delay() {
try {
// 随机延迟1-3秒
Thread.sleep(1000 + random.nextInt(2000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 使用代理IP
public static String getProxyIP() {
// 实际使用时从代理池获取
return "http://proxy-ip:port";
}
}
完整爬虫运行示例
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CrawlerRunner {
public static void main(String[] args) {
// 使用线程池控制并发
ExecutorService executor = Executors.newFixedThreadPool(5);
// 爬取多个URL
String[] urls = {
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
};
for (String url : urls) {
executor.submit(() -> {
try {
// 添加延迟避免被封
Thread.sleep(1000);
// 执行爬取
AdvancedCrawler crawler = new AdvancedCrawler();
String content = crawler.getPageContent(url);
crawler.parseAndExtract(content);
System.out.println("成功爬取: " + url);
} catch (Exception e) {
System.err.println("爬取失败: " + url);
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
注意事项
- 遵守robots.txt协议
- 设置合理的请求频率
- 处理异常和重试机制
- 数据去重和增量爬取
- 遵守网站使用条款
- 注意数据隐私和版权问题
这个案例覆盖了从简单到复杂的Java爬虫实现,你可以根据实际需求选择合适的方案,爬虫技术要合法使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播