【Java】爬虫,能不能再详细讲讲?万字长文送给你!

【Java】爬虫,数据持久化到MongoDB 前言 先上几盘菜尝尝: MongoDB是什么?【博客园】惨绿少年《MongoDB 入门篇》 MongoDB怎么安装?【菜鸟教程】《Windows 平台安装 MongoDB》 MongoDB快速上手?【优快云】Xuych_《java连接mongoDB 并进行增删改查操作》 MongoDB全部用法?【菜鸟教程】《MongoDB 教程》 再送你一个MongoDB可视化操作工具: 【... 阅读详情

前言

本文仅用于学习知识探讨,绝无其它恶意。

前两篇基础文章链接:

《【Java】爬虫,看完还爬不下来打我电话 》

《【Java】爬虫,数据持久化到MongoDB》

本文打算再详细的讲讲一些流程细节,另外,最后有写到如何分析爬取下来的内容。

在开始正文之前,还要说清一件事:我是小白,能不能学会爬虫?

答:学不会,别学了,放弃吧。赶紧拿起手机,打游戏吧。这么热的天,哪凉快哪去,千万别遭这个罪。

正文

静态与动态网页

​ 我所理解的静态网页就是,浏览器中右键查看源代码,源码内容与用户看到的内容一致;动态网页就是,源码中找不到用户所看到的内容(部分)。

​ 这就有意思了,源码中都没有的内容,那是怎么呈现出来的?答案就是通过二次加载甚或多次加载得到。

​ 存在即合理,简单想想就能想通,倘若我点进去一个网页,加载半天一片空白,很大概率我是会不耐烦的。所以势必要一部分一部分的加载进去,有些东西还需要我点击“加载更多“之后才会加载。

爬静态网页的流程

  1. 第一步就是学习框架,Java首推Jsoup框架。
  2. 省省吧,静态网页没有第二步。
  3. 为了整体格式,这里要凑够三行。

爬动态网页的流程

  1. 第一步依然是学习框架,Java首推cdp4j框架。
  2. 学会“抓包”。
  3. 可以了,爬虫就这么点东西,都凑不够三步。
第一步 学习cdp4j框架

​ 因为是全英文网站,可能有些人会产生抵触的心理。但是,类名总能看懂吧:Code Samples地址

cdp4j样例代码这上面的代码我挨个运行过一遍,最后用到我这个项目里的只需要上面红框4个即可。

第二步 学会“抓包“

​ 有些人吃包子还需要用筷子夹,我向来都是用手抓 :)

​ “抓包”这个动词看起来很神秘,高深莫测。其实,就是看网页。东北话:瞅!瞪大眼睛瞅就可以成为抓包了,只不过需要瞅对地方。这个对的地方就是浏览器开发者工具,谷歌浏览器是右键->检查;火狐浏览器是右键->查看元素;搜狗、360浏览器是右键->审查元素;或者,统统按F12。推荐使用Chrome浏览器,因为好用,另外cdp4j框架使用前提就是安装Chrome浏览器。这里有个坑,请认准Chrome官网下载地址和官方图标:除此图标之外,任何图标都是假的Chrome。配色不一样、中间不是蓝点等等,都是假的Chrome。

​ Chrome浏览器安装好并不能使用,需要点右上角的三个点,然后选设置,或者直接在地址栏输入chrome://settings/

设置

​ 将搜索引擎设置为国内的搜索引擎,谷歌浏览器不能用谷歌搜索引擎,说起来也是令人欷歔(不知道国外的百度浏览器能否使用百度搜索引擎 : )

百度搜索引擎

进入开发者工具后,刷新一下页面,然后先点击Network再点击Type按响应类型排序,如下图:

抓包
​ 现在这个过程就叫“抓包”,至于能不能抓到,那看你有没有那个眼力劲了。

​ 当我们点击Type之后,Network响应的数据就会进行按类别进行排序。因为动态网页和静态网页的区别就在于数据不是一口气加载进来的,而是先加载浏览器地址栏URL,响应后再加载对应的脚本去后台获取JSON数据,解析JSON数据填充到页面中进行渲染。既然是脚本,当然需要关注script类型的响应了,如下图:

Script
​ 如果不能一眼看出来这些script类型响应了什么内容,可以逐个点击,之后会弹出一个展示框,选中Preview。最终,我发现了新闻列表是通过下图中红框的链接得到的:

新闻列表
​ 至此,网易新闻·国内新闻列表这个“包”,已经被我们“抓”到了。单次抓包结束!

​ 不过,爬虫程序逻辑还没完。

​ 如果往下浏览网页,当翻到距离底部不远的时候,网易新闻(国内)会再次加载新闻列表。这时候Network下对应就出现了新的响应内容。
加载更多
​ 直到出现 :-)已经到最后啦~, 就代表我们只能获取这么多。每次加载70篇新闻,总共可以加载3次。也就是说,我们只能获得网易新闻(国内)最近的3*70=210篇新闻,时间是近7天。对于“新闻”来说,210篇、近7天,差不多就够了,再多就不新了(我曾想挣扎一下拿到更久远的数据,能力有限,没整出来 :)
加载全部
​ 我们可以对每个响应逐个右键,Copy,Copy link address
copy
我已经给整出来了,瞪大眼睛瞅瞅有啥规律?

https://temp.163.com/special/00804KVA/cm_guonei.js?callback=data_callback   (第一次加载)
https://temp.163.com/special/00804KVA/cm_guonei_02.js?callback=data_callback(第二次加载)
https://temp.163.com/special/00804KVA/cm_guonei_03.js?callback=data_callback(第三次加载)

​ 规律就是都包含这个正则表达式

"cm_guonei[_0-9]*\\.js"

​ 但是,等等,我们是不是忽略了一个重要的事情,就是,怎么才能获取到响应的url?

​ 两种方式:一、手动“抓包”,然后写死在程序中。二、手动“抓包”,然后使用cdp4j进行获取Network响应URL。

​ 为了锻炼锻炼我的正则表达式 能力,我选择了后者。

​ 还记得我在一开始用红色框标记的4个官方样例吗?NetworkResponse.java

​ 主要代码如下:
NetworkResponse

​ 通过这个Demo我们就能拿到后台响应的url链接了,再用正则"cm_guonei[_0-9]*\.js"进行匹配就能筛选出我们想要的URL链接。

​ 一旦正则匹配成功,我们就可以自己手动构造3个url链接。下面代码纯属我写着玩,大家完全可以分析出来后手动写死,没必要费这么大劲。

// 获取Network响应的新闻列表url
public static List<String> getNetworkResponseNewsListUrl(String url){
   
   
    Launcher launcher = new Launcher();
    List<String> newsListUrlList = new ArrayList<>();
    try (SessionFactory factory = launcher.launch(asList("--disable-gpu", "--headless"))) {
   
   
        String context = factory.createBrowserContext();
        try (Session session = factory.create(context)) {
   
   
            // 连通网络
            session.getCommand().getNetwork().enable();
            // 事件监听器
            session.addEventListener(new EventListener() {
   
   
                @Override
                public void onEvent(Events event, Object value) {
   
   
                    if (NetworkResponseReceived.equals(event)) {
   
   
                        ResponseReceived rr = (ResponseReceived) value;
                        Response response = rr.getResponse();
                        // 从response对象中获得url
                        String newsListUrl = response.getUrl();
                        // 正则匹配,检测网站 https://regex101.com 匹配3条约用时2ms
                        Pattern pattern = Pattern.compile("cm_guonei[_0-9]*\\.js");
                        Matcher matcher = pattern.matcher(newsListUrl);
                        if (matcher.find()) {
   
   
                            newsListUrlList.add(newsListUrl);
                            newsListUrl = newsListUrl.replaceFirst("cm_guonei[_0-9]*\\.js","cm_guonei_02.js");
                            newsListUrlList.add(newsListUrl);
                            newsListUrl = newsListUrl.replaceFirst("cm_guonei[_0-9]*\\.js","cm_guonei_03.js");
                            newsListUrlList.add(newsListUrl);
                        }
                    }
                }
            });
            // 监听器写在导航之前
            // 一定要有连接超时设置,且不小于2s(多次测试得出结论,具体时间和网速有关系),否则无法获取
            session.navigate(url).wait(5 * 1000).waitDocumentReady(5 * 1000);
        }
        // 处理浏览器上下文,源码:contexts.remove(browserContextId)
        factory.disposeBrowserContext(context);
    }
    // 关闭后台进程,由于历史原因,关闭进程习惯使用kill
    launcher.getProcessManager().kill();
    return newsListUrlList;
}

​ 拿到获取新闻列表的响应链接后,我们就可以使用静态网页工具Jsoup进行获取网页了。这里或许会有疑问,为啥又是cdp4j,又是Jsoup来回混用呢?答案很简单,哪个工具擅长什么就使用哪个呗。

​ Jsoup显然是爬取静态网页中的哥哥!

获取Network响应的新闻列表JSON串
public static String getNewsListJsonStr(String url) throws IOException {
   
   
    // 使用parse,请求连接时指明编码GBK(试出来的),否则获取的内容会乱码
    // 参考:https://www.sojson.com/blog/225.html
    org.jsoup.nodes.Document doc = Jsoup.parse(new URL(url).openStream(), "GBK", url);
    String body = doc.text();

    // 零宽断言,从body上截取路径data_callback( )圆括号内数据
    Pattern pattern = Pattern.compile("(?<=data_callback\\()(.*)(?=\\))");
    Matcher matcher = pattern.matcher(body);
    while(matcher.find()){
   
   
        return matcher.group();
    }
    return "";
}

解析JSON

​ 通过上面代码就可以拿到Network返回的JSON数据了,之后,我们可以先去一个在线网站解析一下,复制一下JSON内容区这个网站:在线解析JSON

​ 可以发现,最外层是1个JSONArray,里面嵌套70个JSONObject

嵌套


JSON总体可以分为对象、集合(数组)两大类,二者可以任意嵌套。

常用的工具就是Google的Gson,两大功能:序列化、反序列化,官方给出教程如下

序列化,即对象转为Json字符串

反序列化,即Json字符串转为对象

Object序列化与反序列化

// 序列化
UserSimple userObject = new UserSimple(  
    "Norman", 
    "norman@futurestud.io", 
    26, 
    true
);

Gson gson = new Gson();  
String userJson = gson.toJson(userObject);  
/*
结果 ==>
"{
  "age": 26,
  "email": "norman@futurestud.io",
  "isDeveloper": true,
  "name": "Norman"
}"
*/

// 反序列化
String userJson = "{'age':26,'email':'norman@futurestud.io','isDeveloper':true,'name':'Norman'}";  

Gson gson = new Gson();  
UserSimple userObject = gson.fromJson(userJson, UserSimple.class);  
// 结果 ==> 就是上面那个userObject

Array序列化与反序列化

int[] ints = {
   
   1, 2, 3, 4, 5};
String[] strings = {
   
   "abc", "def", "ghi"};

Gson gson = new Gson();
// 序列化
gson.toJson(ints);     // ==> [1,2,3,4,5]
gson.toJson(strings);  
Java实现爬虫 关于美国历来每次飞机失事的数据,包含时间地点、驾驶员、死亡人数、总人数、事件描述,一共有12列,第一列是标题,下面一共有5268条数据。多线程中如果想设置等待状态,有一个方法可以实现wait(),如果想从等待状态唤醒,则可以使用notify()。通过Pattern和Matcher的配合,我们可以把一段内容中匹配我们要求的文字提取出来,方便我们来处理。对爬取的HTML页面来说,如果想提取连接地址,就必须找到所有超连接的标签和对应的属性。需要先自定义一个线程的操作类,在这个操作类中判断不同的状态,并且根。... 阅读详情

相关推荐

Java实现网络爬虫-Java入门|Java基础课程

目标 网络爬虫的是做什么的? 手动写一个简单的网络爬虫; 1. 网络爬虫 1.1. 名称 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚 本。 另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 1.2. 简述 网络爬虫是通过网页的链接地址来寻找网页,从网站某一个页面(通常是首页)开始,读取网页的内容,找到 在网页中的其它...

万和IT教育 5031

Java网络爬虫全面教程

Java网络爬虫 这是本文目录 这里写目录标题Java网络爬虫1. HttpClient1.1 Get请求1.2 POST请求1.3 连接池1.4 参数设置2. Jsoup 本文将循序渐进介绍3大爬虫必备技术 HttpClietn(负责请求页面并获得页面) Jsout(负责解析页面,提取元素) WebMagic(Java的一个爬虫框架,利用WebMagic可以整合1、2中的繁琐操作) WebMagic框架我们留到下一期讲解。 1. HttpClient 使用网络爬虫其实就是要用Java程序去访问Ht

weixin_44293582的博客 3118

网络爬虫课程介绍及网络爬虫是什么

1.1.1知识概述 介绍网络爬虫的课时安排,以及简单介绍当前课程在大数据课程中的重要性。 1.1.2视频详情 1.1.3总结与补充 无 1.1.4课堂提问与练习 无 1.1.5习题答案 无 1.1网络爬虫是什么1.2.1知识概述 以上数据来源于百度百科 爬虫又叫网络爬虫,网络蜘蛛,一种运行在互联网上用来获取数据的...

qq_40208605的博客 1778

Java网络爬虫入门

Java网络爬虫是一个强大的工具,可以用于收集、分析各种数据,并用于数据挖掘、搜索引擎等场景。发送HTTP请求:使用Java发送HTTP请求,获取Web页面的内容。本文旨在介绍Java网络爬虫的入门知识,包括如何使用Java编写网络爬虫程序、如何发送HTTP请求、如何解析网页和如何保存爬取结果等。如:要爬取的是新闻网站,要收集的是新闻标题、发布时间、正文等。解析HTML页面:使用Java解析HTML页面,提取有用的信息。解析HTML页面:使用Java解析HTML页面,提取有用的信息。

吃不胖. 387

Java网络爬虫的设计与实现

网络爬虫(Web Crawler),也被称为网络蜘蛛(Web Spider)或网络机器人(Web Robot),是一种自动获取网页内容的程序或脚本。它按照一定的规则,自动地在互联网上浏览、检索并抓取信息。网络爬虫是搜索引擎、数据挖掘和知识管理等领域的关键技术之一。Java语言自1995年问世以来,因其“编写一次,到处运行”的理念而广受欢迎。它的特点包括面向对象、平台无关性、安全性、多线程和网络编程能力等。

weixin_33773084的博客 1254

ComfyUI 的 LoRA 训练:素材打标签与调优全攻略

标签是 LoRA 训练的"地基"——地基打不牢,后续调参再精细也难出好效果。记住:标签要"少而精",聚焦独特点,用触发词控效果。下一篇我们将讲解参数设置,让你的优质标签发挥最大价值~

2301_78150483的博客 3099

labview中DAQ采集多个数据通道(温度传感器)(TTL信号的曲轴位置传感器)总结

文章目录前言一、面对的问题篇二、问题解决篇三、后续工作总结 前言 我研一的项目利用labview软件和NI数据采集卡采集发动机传感器的信号然后进行采集,发动机传感器是有很多种的,所以难以避免的需要采集多个通道的传感器信号。 一、面对的问题篇 前篇已经写道我已经将温度传感器的信号采集出来,也可以将其数据进行信号处理,由电压信号转变为温度值。但是想要采集多个通道的信号,加上TTL信号的曲轴位置传感器,我模仿温度传感器采集的程序另加了一个DAQ助手进行采集。也就是如图所示的程序: 但是这个程序不能正常显

xiaobaiwsc的博客 1万+

EXI编解码避坑指南:ISO15118-2协议中3条异常命令的差异分析

本文深度剖析了ISO15118-2协议测试中EXI编解码的典型问题,聚焦于ChargeParameterDiscoveryRes、CertificateInstallationReq和MeteringReceiptReq三条命令在不同工具间产生109字节差异的现象。通过对比EXICodec.jar、OpenEXI和Efficient XML的输出,揭示了差异根源于EXI报头处理机制与模式文件完整性,并提供了从现象确认、根因分析到解决方案的标准化排查流程,助力协议测试工程师确保编解码一致性与通信可靠性。

algae的博客 411

HackRF实战:用Portapack扩展板玩转GPS信号模拟(附固件刷写教程)

本文详细介绍了如何使用HackRF与Portapack扩展板进行GPS信号模拟,包括固件刷写、信号生成与发射配置等实战操作。通过专业工具和优化技巧,读者可以掌握软件无线电的高级应用,解决手机定位难题,同时强调安全合规使用的重要性。

weixin_28717431的博客 363

Spark Sql 连接mysql

转载请务必注明原创地址为:http://dongkelun.com/2018/03/21/sparkMysql/ 1、基本概念和用法(摘自spark官方文档中文版) Spark SQL 还有一个能够使用 JDBC 从其他数据库读取数据的数据源。当使用 JDBC 访问其它数据库时,应该首选 JdbcRDD。这是因为结果是以数据框(DataFrame)返回的,且这样 Spark SQL操作轻松或便......

主要分享大数据相关的知识,如Spark、Hudi 1万+

CAMERALINK硬件封装说明

闲言少叙,直接上活,Cameralink硬件接口当前主要分为MDR26和SDR26两种,其中MDR对应封装较大价格比较便宜,SDR对应尺寸较小价格比较贵,这点我个人总是记错的图1 MDR26实物图图2 SDR26实物图。

6171

2025机械考研复试面试问题汇总篇(含13门科目),考研机械复试专业面试常见重点问题总结!考研机械复试专业面试准备看这一篇就够了!

(完整版内容:)1.汇集了本科各科的重点知识及多个机械名校800多个常见问题,共8.7万字185页,涵盖机械所以专业课的重点知识和常见问答。 2.涉及机械大类重点科目,包括:材料力学、控制工程、数控技术、机械制造技术基础、理论力学、液压传动、机械设计、机械原理、工程材料、互换性与技术测量、测试技术、汽车理论、程序设计与C语言等13门必修课。

weixin_56510835的博客 1862

Python爬虫实战:利用Playwright与反反爬技术抓取Crunchbase企业数据

在当今数据驱动的商业环境中,获取准确的企业信息对于市场分析、竞争情报和投资决策至关重要。Crunchbase作为全球领先的企业信息平台,包含了数百万家公司、投资者和关键人员的详细数据。本文将深入探讨如何使用Python最新爬虫技术Playwright,结合多种反反爬策略,高效抓取Crunchbase企业数据。我们将从爬虫基础概念讲起,逐步深入到高级技巧,并提供完整的代码实现,帮助读者掌握现代网络数据采集的核心技术。网络爬虫技术自互联网诞生以来经历了显著演变。

2201_76125261的博客 1833

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 【数据库】B+树与索引之间的恩怨情仇
下一篇: 搜集一些骨骼清奇的文章
midnight_time
博客等级 码龄10年 1714粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值