百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

手把手教你从零开始用Java写爬虫

liuian 2025-01-07 14:14 38 浏览


本文将手把手地教大家从零开始用Java写一个简单地爬虫!

目标

爬取全景网图片,并下载到本地

收获

通过本文,你将复习到:

  • IDEA创建工程
  • IDEA导入jar包
  • 爬虫的基本原理
  • Jsoup的基本使用
  • File的基本使用
  • FileOutputStream的基本使用
  • ArrayList的基本使用
  • foreach的基本使用

说明

爬虫所用的HTM解析器为Jsoup。Jsoup可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

Jsoup相关API整理见文末附录一。

开始

一、前端分析

1、使用Chrome或其他浏览器,打开全景网,按F12进入调试模式,分析网页结构。(这里选的是“创意”=>“优山美地”)

2、找规律,看图片对应的结构是什么。可以发现,每个图片的结构都如下图红框所示。

3、找到结构后再找图片链接。进一步分析后发现,图片链接可以是下图红框部分。

4、复制到浏览器打开看看验证下。(好吧,访问这个URL直接给我下载了...)

5、前端部分分析完毕,接下来就可以用Java编码了!


二、爬取思路

通过Java向全景网发送GET请求,以获取HTML文件。Jsoup解析后寻找class=item lazy的a标签,他的child节点(即<img>)就是我们要找的目标节点了,搜索到的应当是一个ArrayList。然后遍历集合,从中搜寻图片的URL,并下载到本地保存。(更深一步,可以下载完一页后,继续下载后一页,直至全部下完。本文直讲下载第一页。提示一下,链接后面的topic/1其实就是当前页数)


三、Java编码

1、先下载Jsoup jar包,并导入到IDEA工程中。

2、新建Java工程。

3、简单测试下get请求,若请求成功,则进入下一步;若报错,检查URL是否带了中文。

注意:链接没给,否则文章审核不过,注意自己添加!!!

package com.sxf;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class Main {
    public static void main(String[] args) {
        try {
            Document doc = Jsoup.connect("").get(); //这里加链接
            System.out.println(doc);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


4、寻找class为item lazy的元素,找到他的child节点,返回ArrayList。并将图片的URL单独提取出来。

注意:链接没给,否则文章审核不过,注意自己添加!!!

注意:链接没给,否则文章审核不过,注意自己添加!!!


5、我们先尝试用Jsoup下载一张图片试试效果。

注意:链接没给,否则文章审核不过,注意自己添加!!!

// 获取response
Connection.Response imgRes = Jsoup.connect(URLS.get(0)).ignoreContentType(true).execute();
FileOutputStream out = (new FileOutputStream(new java.io.File("demo.jpg")));
// imgRes.body() 就是图片数据
out.write(imgRes.bodyAsBytes());
out.close();

可以看到在当前工程路径下,生成了demo.jpg图片,并且显示正常!

6、接下来,我们要创建一个文件夹,用来专门存放图片。

File相关API整理见文末附录二。

//当前路径下创建Pics文件夹
File file = new File("Pics");
file.mkdir();
System.out.println(file.getAbsolutePath());


7、接下来开始遍历图片并下载。由于图片较多,为了简单起见,我们保存图片时候的名称,就从1开始依次增吧。

// 遍历图片并下载
int cnt = 1;
for (String str : URLS) {
    System.out.println(">> 正在下载:"+str);
    // 获取response
    Connection.Response imgRes = Jsoup.connect(str).ignoreContentType(true).execute();
    FileOutputStream out = (new FileOutputStream(new java.io.File(file, cnt+".jpg")));
    // imgRes.body() 就是图片数据
    out.write(imgRes.bodyAsBytes());
    out.close();
    cnt ++;
}

运行结果


到此编码部分也结束了,完整代码见文末附件三!


附录一

Jsoup(HTML解析器)

继承关系:Document继承Element继承Node。TextNode继承Node。
->java.lang.Object
  ->org.jsoup.nodes.Node
    ->org.jsoup.nodes.Element
      ->org.jsoup.nodes.Document
html文档:Document
元素操作:Element
节点操作:Node

官方API:https://jsoup.org/apidocs/org/jsoup/nodes/Document.html
  
一、解析HTML并取其内容
  Document doc = Jsoup.parse(html);

二、解析一个body片断
  Document doc = Jsoup.parseBodyFragment(html);
  Element body = doc.body();

三、从一个URL加载一个Document
  Document doc = Jsoup.connect("http://example.com")
    .data("query", "Java")
    .userAgent("Mozilla")
    .cookie("auth", "token")
    .timeout(3000)
    .post();
  String title = doc.title();

四、从一个文件加载一个文档
  File input = new File("/tmp/input.html");
  // baseUri 参数用于解决文件中URLs是相对路径的问题。如果不需要可以传入一个空的字符串
  Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");  

五、使用DOM方法来遍历一个文档
  1、查找元素
  getElementById(String id)
  getElementsByTag(String tag)
  getElementsByClass(String className)
  getElementsByAttribute(String key) // 和相关方法
  // 元素同级
  siblingElements()
  firstElementSibling()
  lastElementSibling()
  nextElementSibling()
  previousElementSibling()
  // 关系
  parent()
  children()
  child(int index)

  2、元素数据
  // 获取属性attr(String key, String value)设置属性
  attr(String key)
  // 获取所有属性
  attributes()
  id()
  className()
  classNames()
  // 获取文本内容text(String value) 设置文本内容
  text()
  // 获取元素内HTMLhtml(String value)设置元素内的HTML内容
  html()
  // 获取元素外HTML内容
  outerHtml()
  // 获取数据内容(例如:script和style标签)
  data()
  tag()
  tagName()

  3、操作HTML和文本
  append(String html)
  prepend(String html)
  appendText(String text)
  prependText(String text)
  appendElement(String tagName)
  prependElement(String tagName)
  html(String value)
  
六、使用选择器语法来查找元素(类似于CSS或jquery的选择器语法)
  //带有href属性的a元素
  Elements links = doc.select("a[href]"); 
  //扩展名为.png的图片
  Elements pngs = doc.select("img[src$=.png]");
  //class等于masthead的div标签
  Element masthead = doc.select("div.masthead").first(); 
  //在h3元素之后的a元素
  Elements resultLinks = doc.select("h3.r > a"); 

七、从元素抽取属性、文本和HTML
  1、要取得一个属性的值,可以使用Node.attr(String key) 方法
  2、对于一个元素中的文本,可以使用Element.text()方法
  3、对于要取得元素或属性中的HTML内容,可以使用Element.html(), 或 Node.outerHtml()方法
  4、其他:
    Element.id()
    Element.tagName()
    Element.className()
    Element.hasClass(String className)


附录二

File类

*java.io.File类用于表示文件或目录。*
创建File对象:
// 文件/文件夹路径对象
File file = new File("E:/...");
// 父目录绝对路径 + 子目录名称
File file = new File("..." ,"");
// 父目录File对象 + 子目录名称  
File file = new File("...","...");
file.exists():判断文件/文件夹是否存在
file.delete():删除文件/文件夹
file.isDirectory():判读是否为目录
file.isFile():判读是否为文件夹
file.mkdir():创建文件夹(仅限一级目录)
file.mkdirs():创建多及目录文件夹(包括但不限一级目录)
file.createNewFile():创建文件
file.getAbsolutePath():得到文件/文件夹的绝对路径
file.getName():得到文件/文件夹的名字
file.String():同样是得到文件/文件夹的绝对路径等于file.getAbsolutePath()
file.getParent():得到父目录的绝对路径


附录三

完整代码

package com.sxf;
?
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
?
public class Main {
    public static void main(String[] args) {
        try {
            Document doc = Jsoup.connect("https://www.quanjing.com/creative/topic/1").get();
            // 寻找class为item lazy的元素,返回ArrayList。
            Elements items = doc.getElementsByClass("item lazy");
            ArrayList<String> URLS = new ArrayList<>();
            // 将图片的URL单独提取出来。
            for (Element i : items) {
                URLS.add(i.child(0).attr("src"));
            }
            // 当前路径下创建Pics文件夹
            File file = new File("Pics");
            file.mkdir();
            String rootPath = file.getAbsolutePath();
            System.out.println(">> 当前路径:"+rootPath);
            // 遍历图片并下载
            int cnt = 1;
            for (String str : URLS) {
                System.out.println(">> 正在下载:"+str);
                // 获取response
                Connection.Response imgRes = Jsoup.connect(str).ignoreContentType(true).execute();
                FileOutputStream out = (new FileOutputStream(new java.io.File(file, cnt+".jpg")));
                // imgRes.body() 就是图片数据
                out.write(imgRes.bodyAsBytes());
                out.close();
                cnt ++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

相关推荐

教你把多个视频合并成一个视频的方法

一.情况介绍当你有一个m3u8文件和一个目录,目录中有连续的视频片段,这些片段可以连成一段完整的视频。m3u8文件打开后像这样:m3u8文件,可以理解为播放列表,里面是播放视频片段的顺序。视频片段像这...

零代码编程:用kimichat合并一个文件夹下的多个文件

一个文件夹里面有很多个srt字幕文件,如何借助kimichat来自动批量合并呢?在kimichat对话框中输入提示词:你是一个Python编程专家,完成如下的编程任务:这个文件夹:D:\downloa...

Java APT_java APT 生成代码

JavaAPT(AnnotationProcessingTool)是一种在Java编译阶段处理注解的工具。APT会在编译阶段扫描源代码中的注解,并根据这些注解生成代码、资源文件或其他输出,...

Unit Runtime:一键运行 AI 生成的代码,或许将成为你的复制 + 粘贴神器

在我们构建了UnitMesh架构之后,以及对应的demo之后,便着手于实现UnitMesh架构。于是,我们就继续开始UnitRuntime,以用于直接运行AI生成的代码。PS:...

挣脱臃肿的枷锁:为什么说Vert.x是Java开发者手中的一柄利剑?

如果你是一名Java开发者,那么你的职业生涯几乎无法避开Spring。它如同一位德高望重的老国王,统治着企业级应用开发的大片疆土。SpringBoot的约定大于配置、SpringCloud的微服务...

五年后,谷歌还在全力以赴发展 Kotlin

作者|FredericLardinois译者|Sambodhi策划|Tina自2017年谷歌I/O全球开发者大会上,谷歌首次宣布将Kotlin(JetBrains开发的Ja...

kotlin和java开发哪个好,优缺点对比

Kotlin和Java都是常见的编程语言,它们有各自的优缺点。Kotlin的优点:简洁:Kotlin程序相对于Java程序更简洁,可以减少代码量。安全:Kotlin在类型系统和空值安全...

移动端架构模式全景解析:从MVC到MVVM,如何选择最佳设计方案?

掌握不同架构模式的精髓,是构建可维护、可测试且高效移动应用的关键。在移动应用开发中,选择合适的软件架构模式对项目的可维护性、可测试性和团队协作效率至关重要。随着应用复杂度的增加,一个良好的架构能够帮助...

颜值非常高的XShell替代工具Termora,不一样的使用体验!

Termora是一款面向开发者和运维人员的跨平台SSH终端与文件管理工具,支持Windows、macOS及Linux系统,通过一体化界面简化远程服务器管理流程。其核心定位是解决多平台环境下远程连接、文...

预处理的底层原理和预处理编译运行异常的解决方案

若文章对您有帮助,欢迎关注程序员小迷。助您在编程路上越走越好![Mac-10.7.1LionIntel-based]Q:预处理到底干了什么事情?A:预处理,顾名思义,预先做的处理。源代码中...

为“架构”再建个模:如何用代码描述软件架构?

在架构治理平台ArchGuard中,为了实现对架构的治理,我们需要代码+模型描述所要处理的内容和数据。所以,在ArchGuard中,我们有了代码的模型、依赖的模型、变更的模型等,剩下的两个...

深度解析:Google Gemma 3n —— 移动优先的轻量多模态大模型

2025年6月,Google正式发布了Gemma3n,这是一款能够在2GB内存环境下运行的轻量级多模态大模型。它延续了Gemma家族的开源基因,同时在架构设计上大幅优化,目标是让...

比分网开发技术栈与功能详解_比分网有哪些

一、核心功能模块一个基本的比分网通常包含以下模块:首页/总览实时比分看板:滚动展示所有正在进行的比赛,包含比分、比赛时间、红黄牌等关键信息。热门赛事/焦点战:突出显示重要的、关注度高的比赛。赛事导航...

设计模式之-生成器_一键生成设计

一、【概念定义】——“分步构建复杂对象,隐藏创建细节”生成器模式(BuilderPattern):一种“分步构建型”创建型设计模式,它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建...

构建第一个 Kotlin Android 应用_kotlin简介

第一步:安装AndroidStudio(推荐IDE)AndroidStudio是官方推荐的Android开发集成开发环境(IDE),内置对Kotlin的完整支持。1.下载And...