2021年Java爬虫技术教程(一小时实现) 您所在的位置:网站首页 百度识图爬虫软件有哪些 2021年Java爬虫技术教程(一小时实现)

2021年Java爬虫技术教程(一小时实现)

2024-07-11 07:04| 来源: 网络整理| 查看: 265

Java爬虫开发 操作要点

正则表达式 Java网络通信:URL IO流 Map—HashMap 字符串操作 异常处理

项目已上传本人码云(gitee)传送门

如果这篇博客对你有一点点小帮助,希望您能给我来波一键三连;

前言

python优点:

1.各种爬虫框架,方便高效的下载网页; 2.多线程、进程模型成熟稳定,爬虫是一个典型的多任务处理场景,请求页面时会有较长的延迟,总体来说更多的是等待。多线程或进程会更优化程序效率,提升整个系统下载和分析能力。 3.gae 的支持,当初写爬虫的时候刚刚有 gae,而且只支持 python ,利用 gae 创建的爬虫几乎免费,最多的时候我有近千个应用实例在工作。

java 和 c++ : 相对脚本语言比较麻烦,所以放弃。总之,如果开发一个小规模的爬虫脚本语言是个各方面比较有优势的语言。如果要开发一个复杂的爬虫系统可能 java 是个增加选项, c++ 我感觉写个模块之类的更加适合。对于一个爬虫系统来说,下载和内文解析只是基本的两个功能。真正好的系统还包括完善的任务调度、监控、存储、页面数据保存和更新逻辑、排重等等。爬虫是一个耗费带宽的应用,好的设计会节约大量的带宽和服务器资源,并且好坏差距很大。

注意(爬虫爬取数据,必须是合法的数据,) 爬虫的类型 通用型的爬虫: 宽度遍历 针对网页进行无差别抓取,例如Google搜索引擎和百度搜索引擎等等;(他们不生产网页内容,其内容都是类似的爬虫爬取来的) 难点:页面下载和链接管理上,如果你要高效的抓取更多界面,就必须进行更快的下载;同时随着链接数量的增多,需要考虑如果对大规模的链接进行去重和调度,就成了一个很大的问题 通用型爬虫框架: Nutch, Heritrix 垂直型的爬虫 关注内容与准确还有效率,仅仅抓取到有效有用的数据,并且在爬虫抓取之前,就能够对数据进行简单的处理:如:提取标题,内容,时间等; 例如:股票财经,其涨跌幅度; 难点:如何高效的定制一个爬虫,可以精确的抽取网页内容,并保存成结构化的数据。 框架 :webmagic 本次代码实践所用技术 模拟浏览器:HttpClient html解析:jsoup 1.在Module建立一个maven工程

(因为我提前建立了一个大的maven工程项目,本次为了节省时间,就不重新创建一个maven工程,直接利用现有的) 建立一个简单的maven,不选用现成的骨架 点击module在这里插入图片描述 选择好你需要的jdk版本,点击next 在这里插入图片描述 设置好工程名称,和域名倒写。点击finish 在这里插入图片描述 点击file,点击Project structure,再点击module 在这里插入图片描述 将 java设为Source 将resources 设为Resource 在这里插入图片描述 引入你需要的maven依赖

org.jsoup jsoup 1.10.3 org.apache.httpcomponents httpcore 4.4.10 org.apache.httpcomponents httpclient 4.5.6 commons-io commons-io 2.6

建立好包 在这里插入图片描述 本次爬取网站:昵图网传送门 以一个图片网站作为本次爬取对象 在这里插入图片描述 在网站中审查元素:确定图片的html代码结构 crtl+(a标签里面的http://www.nipic.com/topic/show_27400_1.html) 分析html代码,观察里面的结点结构特点。建立一个URL的值,把里面所有的html的保存起来。 然后来处理里面的每一个html,再来根据里面的每一个html,来取这个界面中间的图片。 需要分开处理,img图片和上面的a标签,来爬取上面的图片,将图片保存起来。 在这里插入图片描述 创建一个UrlPool类,用来存放html。 代码全在我的gitee:传送门 对你有用的话,可以点个收藏关注;给我的gitee点一个star;谢谢;

package com; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * * @Auther: 孙伟俊 * @Date: 2021/03/14/22:37 * @Description: */ //用来存放html public class UrlPool { public static void main(String[] args) { getURL("http://www.nipic.com/"); } private static void getURL(String baseUrl) { // 创建一个map集合,传入要爬取的页面的url,并定义一个Boole型值,用于判断当前传入的url是否被遍历过; Map oldMap=new LinkedHashMap(); // 如果采集下来的路径是相对路径的话,要将相对路径进行 String oldLinkHost=""; // 使用正则表达式,对路径进行占位符替换 Pattern p=Pattern.compile("(http?://)?[^/\\s]*"); Matcher m=p.matcher(baseUrl); if(m.find()){ oldLinkHost=m.group(); // 取到正则之后的值 //因为baseUrl,也是需要去爬取的,所以要将baseUrl的值,放入到这个集合中,因为未采集,所以定值为false oldMap.put(baseUrl,false); oldMap=crawlLinks(oldLinkHost,oldMap);//遍历这个url,告诉他传入的值经过正则处理过,如果取到一个相对路径则进行拼接 //返回的也是一个oldMap;(是个引用类型) for (Map.Entry mapping:oldMap.entrySet()){ System.out.println("链接"+ mapping.getKey()); } } } /** * @Description: 实现递归 对传入的url进行处理 * @Param: [oldLinkList, oldMap] * @return: void * @Author: 孙伟俊 * @Date: 2021/3/14 */ private static Map crawlLinks(String oldLinkHost, Map oldMap) { Map newMap=new LinkedHashMap();//创建一个新的容器 // 如果url被遍历过,就不做遍历, String oldLink=""; for (Map.Entry mapping: oldMap.entrySet()){ System.out.println("链接"+ mapping.getKey()+"----check"+mapping.getValue()); if(!mapping.getValue()){} oldLink=mapping.getKey(); try{ URL url=new URL(oldLink); HttpURLConnection connection=(HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); //如果拿到的响应值为responseCode=200 if(connection.getResponseCode()==200){ //读取所有的a标签 使用BufferedReader 缓冲区来接收,这样读取速度快一点, BufferedReader reader=new BufferedReader( new InputStreamReader(connection.getInputStream())); //定义 a标签的正则表达式 Pattern p = Pattern.compile("a.*?href=[\\\"']?((https?://)?/?[^\"']+)[\\\"']?.*?>(.+)"); Matcher matcher=null; String line=""; //开始流操作 while ((line=reader.readLine())!=null){ matcher=p.matcher(line); if(matcher.find()){ String newLink=matcher.group(1).trim(); //判断newLink是否为合法的,如果newLink不以http开头,此时的newLink就是一个相对路径 if(!newLink.startsWith("http")){ if (newLink.startsWith("/")){ newLink=oldLinkHost+newLink; }else { newLink=oldLinkHost+"/"+newLink; } } if(newLink.endsWith("/")){ newLink=newLink.substring(0,newLink.length()-1); } //判断url有没有重复 if(!oldMap.containsKey(newLink) &&!newMap.containsKey(newLink) &&!newLink.startsWith(oldLinkHost)){ newMap.put(newLink,false); } } } } }catch (Exception e){ }finally { } oldMap.replace(oldLink,false,true); } if(!newMap.isEmpty()){ //将新的url集合和oldMap进行合并 oldMap.putAll(newMap); oldMap.putAll(crawlLinks( oldLinkHost, oldMap)); } return oldMap; } }

运行上面的UrlPool类,得到下面的控制台输出: 为了拿到被爬取的内容图片,对内容解析并持久化,创建ImageCrawl类 这一部分:因为考虑到待会教程太长了,放到下一篇博客中说明;

对内容解析并持久化:放在下一篇博客教程中; 后续我会对本次爬虫中涉及的技术的内容,整理出相关博客:

正则表达式 Java网络通信:URL IO流 Map—HashMap 字符串操作 异常处理

本人技术有限,如中间出现什么错误,欢迎大家在评论区指出,希望大家多多支持;

点赞+加一键三连



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有