Java爬虫-Jsoup爬取妹子图

腰酸推荐Java-Jsoup爬取妹子图

日常求赞,感谢老板。

欢迎关注公众号:其实是白羊。干货持续更新中…

一、先放成果

保存到本地的图我就不放了,审核过不了

我扶了下腰,不多不多。。。

二、前言背景

之前一直听爬虫爬虫的,咱也不知道是啥,但都是用Python,咱也不会啊,就会个Java。后来了解到,简单的爬虫其实就是解析页面嘛,提取自己需要的资源(嘿嘿)。再后来在工作中接到了个需求里需要解析html,度娘了一下了解到了Jsoup这个类库。需求做完了,就这么结束?怎么可能,当然是做一些有趣的事情啦。

  1. 先确定目标:练习为主选取比较容易搞的图片,于是我找到了这个妹子图
  2. 半小时过后,我开始了制定计划,爬取网站获取alt做名字,获取连接存到数据库里,以备不时之需。

三、实现过程

一)引入依赖

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.12.1</version>
</dependency>

二)了解类库

主要方法都在Jsoup类提供的静态方法:
  1.  String html = "<html><head><title>First parse</title></head>"
     + "<body><p>Parsed HTML into a doc.</p></body></html>";
     Document doc = Jsoup.parse(html);//通过Document可以获取里面的任何值
     //html必须是html哦不能是片段
    
  2. String html = "<div><p>Lorem ipsum.</p>";
    Document doc = Jsoup.parseBodyFragment(html);//解析html片段,封装成完整的html
    Element body = doc.body();//获取其中的body片段
    
  3. 重头戏来了

    Connection connect = Jsoup.connect("http://example.com/");//获取Connection
    Document document = connect.get();//Connection可以设置常规网络请求都可以设置的一些项,如:
    //connect.header("Accept-Encoding", "gzip, deflate, sdch");//设置请求头(注意要在调用get或post方法之前设置)
    //connect.cookie("auth", "token");//设置cookie
    //connect.timeout(3000);//设置响应时间等
    //这是爬取资源重要的一步哦
    String title = document.title();
    

下面是对于Document解析想要的值的方法:

查找元素
  • getElementById(String id)
  • getElementsByTag(String tag)
  • getElementsByClass(String className)
  • getElementsByAttribute(String key) (and related methods)
  • Element siblings: siblingElements(), firstElementSibling(), lastElementSibling(); nextElementSibling(), previousElementSibling()
  • Graph: parent(), children(), child(int index)
元素数据
  • attr(String key)获取属性attr(String key, String value)设置属性
  • attributes()获取所有属性
  • id(), className() and classNames()
  • text()获取文本内容text(String value) 设置文本内容
  • html()获取元素内HTMLhtml(String value)设置元素内的HTML内容
  • outerHtml()获取元素外HTML内容
  • data()获取数据内容(例如:script和style标签)
  • tag() and tagName()
操作HTML和文本
  • append(String html), prepend(String html)
  • appendText(String text), prependText(String text)
  • appendElement(String tagName), prependElement(String tagName)
  • html(String value)

以上内容参考自:更多方法使用

三)给爷爬

了解了类库,我们就可以着手开始实践解析了:

  1. 先分析下网站上的资源都在哪?

    String url = "https://www.mzitu.com/page/1/";
    Connection connect = Jsoup.connect(url);
    Document document = connect.get();
    

    我们可以看到得到的document中我们想要的资源是这样存在的:

    <img class="lazy" src="https://www.mzitu.com/static/pc/img/lazy.png" data-original="https://i.mmzztt.com/thumb/2020/04/226719_236.jpg" alt="不可描述、过不了审" width="236" height="354">
    

    ok,那么我们要的是img标签下data-original属性的值和alt属性的值。

  2. 解析获取

    //在上面代码基础上
    Elements imgs = document.getElementsByTag("img");//获取全部img
    for (Element img : imgs) {
        String src = img.attr("data-original");
        String alt = img.attr("alt");
        log.info("第{}页:alt->{};src->{}", i, alt, src);
    }
    

    到这就ok啦,alt是图片的描述可以将它作为图片的名字,src就是图片的请求地址,你可以直接将它存在数据库里,或者直接保存到本地磁盘(具体做法后面会写)

  3. 接这样结束了?怎么可能这可是有243页哎(再深的咱们就不挖了)。看下不同页的url可以写成:

    for (int i = 1; i <= 243; i++) {
        String url = "https://www.mzitu.com/page/"+ i +"/";
        //获取+解析步骤省略参考上面步骤
    }
    
  4. 执行下来你会发现,保存下来的图片后面很多都是,这个:

不同的url请求下来的却是同一张图片,单独把url拿出来请求下,果然是请求了只有重定向到了这个图片。嗯虽然我不知道他具体是怎么做的,但我猜应该是从什么地方判断出我不是正常请求,或者是判断同一个ip请求的频率,之后就把我的每次请求都重定向到了这个图片导致我有url却看不到我想要的东西,可恶。

既然他能判断出我不是正常请求,那我们就看看正常请求和直接访问请求有什么区别吧:

正常浏览:

正常请求

url直接请求:

在这里插入图片描述

发现什么没,请求头里少了Referer,找到原因了那就试一哈。

  1. 多次正常浏览后,总结发现Referer的值是上一次浏览的url

  2. 综上在使用Jsoup时获取网页和根据url请求资源时加上一定的请求头:

    //简单写下意思(文末会赋源码)
    for (int i = 1; i <= 243; i++) {
        String url = "https://www.mzitu.com/page/" + i + "/";
        Connection connect = Jsoup.connect(url);
        connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        connect.header("Accept-Encoding", "gzip, deflate, sdch");
        connect.header("Accept-Language", "zh-CN,zh;q=0.8");
        connect.header("Sec-Fetch-Dest", "document");
        connect.header("Upgrade-Insecure-Requests", "1");
        connect.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
        connect.header("Referer", refererPageInit);
        Document document = connect.get();
        //todo 解析出需要的资源
        refererPageInit = "https://www.mzitu.com/page/" + i + "/";
    }
    

    至此你就能获取这两百多页(六七千多张图片)啦。

四、最后

各位绅士先放下手中的针线活,源码在此,觉得写的还可以的给点个赞,也可以评论浏览讨论下。

更多资源:其实是白羊

欢迎star

日常求赞

  • 如果你认为本文对你有帮助,还请「在看/转发/赞/star」,多谢
  • 如果你还发现了更好或不同的想法,还请在留言区不吝赐教,一起探讨交流修改,万分感谢

欢迎关注公众号:「其实是白羊」干货持续更新中…

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果页面使用 JavaScript 动态加载片,那么使用 Jsoup 无法直接获取到这些片的 URL,需要使用其他技术来模拟浏览器行为,比如使用 Selenium WebDriver。 以下是使用 Selenium WebDriver 和 Jsoup 爬取动态页面片的示例代码: ```java import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import java.util.List; public class Main { public static void main(String[] args) { // 设置 Selenium WebDriver 的路径 System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); // 创建 ChromeDriver 实例 WebDriver driver = new ChromeDriver(); // 打开目标页面 driver.get("https://example.com"); // 等待页面加载完成 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // 使用 Jsoup 解析 HTML Document doc = Jsoup.parse(driver.getPageSource()); // 获取片元素 Elements imgElements = doc.select("img"); // 遍历片元素 for (int i = 0; i < imgElements.size(); i++) { // 获取片 URL String imgUrl = imgElements.get(i).attr("src"); // 下载片 // ... } // 关闭 ChromeDriver driver.quit(); } } ``` 这段代码首先创建了一个 Selenium WebDriver 实例,打开了目标页面,并等待页面加载完成。然后,使用 Jsoup 解析 HTML,获取所有的片元素,遍历片元素并获取片 URL,最后可以使用 Java 的网络编程 API 或第三方库(如 Apache HttpClient)下载片。最后,关闭 ChromeDriver。需要注意的是,在实际应用中,需要根据实际情况设置适当的等待时间,以防止页面未完全加载完成导致获取不到片元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值