当前位置: 首页 > news >正文

Java—— 网络爬虫

案例要求 

https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0
http://www.haoming8.cn/baobao/10881.html
http://www.haoming8.cn/baobao/7641.html

 上面三个网址分别表示百家姓,男生名字,女生名字,如图:

           

要求:

获取上述网址中的内容,利用正则表达式爬取姓氏和名字信息,并生成不重复的10个男生的姓名和10个女生的姓名 ,将生成的姓名保存到本模块下的a.txt文件中。

关于网络的方法

URL网址对象

构造方法说明
public URL(String spec)利用记录网址的字符串创建一个网址的对象
成员方法说明
public URLConnection openConnection()网址对象调用该方法让程序连接网址,返回程序和URL之间的通信链接对象

URLConnection通信链接对象

成员方法说明
public InputStream getInputStream()得到连接网址的字节输入流

关于爬虫的方法

Pattern正则表达式对象

构造方法说明
public static Pattern compile(String regex)获取正则表达式的对象,传递的是表示正则表达式的字符串
成员方法说明
public Matcher matcher(String str)正则表达式对象调用该方法获取文本匹配器的对象,传递的是需要进行查找的大串

Matcher文本匹配器对象

成员方法说明
public boolean find()让文本匹配器从头开始读取大串,寻找是否有满足正则表达式的子串。如果没有,方法返回false,如果有,返回true。在底层记录子串的起始索引和结束索引+1
public String group()方法底层会根据find()方法记录的索引进行字符串的截取,返回截取的小串,该小串就是符合正则表达式要求的子串

代码实现

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test1 {public static void main(String[] args) throws IOException {//记录网址String familyNameWeb = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";String boyNameweb = "http://www.haoming8.cn/baobao/10881.html";String girlNameweb = "http://www.haoming8.cn/baobao/7641.html";//调用方法网络爬取网址内容并以字符串形式返回String familyNameStr = webCrawler(familyNameWeb);String boyNameStr = webCrawler(boyNameweb);String girlNamewebStr = webCrawler(girlNameweb);//利用正则表达式获取网址中的姓氏和名字//按照所需数据在网址内容中的布局不同设置不同的正则表达式//百家姓网址中所需的百家姓数据都是4个中文一组后面跟逗号或句号,且只获取符合前的内容//中文的正则表达式为[\u4E00-\u9FA5]ArrayList<String> familyNameTempList = getData(familyNameStr, "([\\u4E00-\\u9FA5]){4}(?=,|。)");//男生名字网址中所需的名字数据都是2个中文一组后面跟顿号或句号,且只获取符合前的内容ArrayList<String> boyNameTempList = getData(boyNameStr, "([\\u4E00-\\u9FA5]){2}(?=、|。)");//女生名字网址中所需的名字数据都是2个中文加1个空格4组后面跟2个中文,都获取ArrayList<String> girlNameTempList = getData(girlNamewebStr,"(([\\u4E00-\\u9FA5]){2} ){4}[\\u4E00-\\u9FA5]{2}");//得到了初始数据集合,将其优化方便使用//System.out.println(familyNameTempList);//[赵钱孙李, 周吴郑王, 冯陈褚卫, 蒋沈韩杨,......//修改百家姓集合为:只保留前410个单姓,并且每一个姓氏占一个索引ArrayList<String> familyNameTemp2List = new ArrayList<>();ArrayList<String> familyNameList = new ArrayList<>();for (String s : familyNameTempList) {for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);familyNameTemp2List.add(c + "");}}//只保留前410个单姓for (int i = 0; i < 410; i++) {familyNameList.add(familyNameTemp2List.get(i));}//System.out.println(familyNameList);//[赵, 钱, 孙, 李, 周, 吴, 郑, 王,......//System.out.println(boyNameTempList);//[大气, 美好, 特色, 大气, 美好, 特色, 月星, 弘城, 雨国, 思明,.....//修改男生名字集合为:去除重复,每一个名字占一个索引ArrayList<String> boyNameList = new ArrayList<>();for (String s : boyNameTempList) {if (!boyNameList.contains(s)) {boyNameList.add(s);}}//System.out.println(boyNameList);//[大气, 美好, 特色, 月星, 弘城, 雨国, 思明, ......//System.out.println(girlNameTempList);//[彤舞 芊静 艾丝 惠蕙 语月, 依莹 瑶馨 曼珍 逸云 微婉,.....//修改女生名字集合为:去除重复,每一个名字占一个索引ArrayList<String> girlNameList = new ArrayList<>();for (String s : girlNameTempList) {String[] arr = s.split(" ");for (int i = 0; i < arr.length; i++) {girlNameList.add(arr[i]);}}//System.out.println(girlNameList);//[彤舞, 芊静, 艾丝, 惠蕙, 语月, 依莹, ......//调用方法根据准备好的数据分别获取不重复的10个男生名字和女生名字//参数为坐标的数据和男女要生成名字的数量ArrayList<String> nameList = getName(familyNameList, boyNameList, girlNameList, 10, 10);//利用缓冲字符输出流写到本模块下的a.txt文件中BufferedWriter bw = new BufferedWriter(new FileWriter("day05\\a.txt"));for (String s : nameList) {bw.write(s);bw.newLine();}bw.close();}private static ArrayList<String> getName(ArrayList<String> familyNameList, ArrayList<String> boyNameList,ArrayList<String> girlNameList, int bCount, int gCount) {//定义集合存储生成的不重复的男生名字HashSet<String> boyList = new HashSet<>();//生成男生名字while (true) {//存够数量跳出if (boyList.size() == bCount) {break;}//打乱集合中的内容Collections.shuffle(familyNameList);Collections.shuffle(boyNameList);//将打乱后的集合的0索引位置的姓和名拼接并标注男生,添加到男生名字集合中boyList.add(familyNameList.get(0) + boyNameList.get(0) + "-男");}//定义集合存储生成的不重复的女生名字HashSet<String> girlList = new HashSet<>();while (true) {//存够数量跳出if (girlList.size() == gCount) {break;}//打乱集合中的内容Collections.shuffle(familyNameList);Collections.shuffle(girlNameList);//将打乱后的集合的0索引位置的姓和名拼接并标注女生,添加到女生名字集合中girlList.add(familyNameList.get(0) + girlNameList.get(0) + "-女");}//定义集合存储生成的名字ArrayList<String> nameList = new ArrayList<>();//将男女名字集合中的数据放到一个集合中,方便返回for (String s : boyList) {nameList.add(s);}for (String s : girlList) {nameList.add(s);}return nameList;}//正则表达式private static ArrayList<String> getData(String str, String regex) {//定义集合存储符合正则表达式的数据ArrayList<String> list = new ArrayList<>();Pattern p = Pattern.compile(regex);Matcher m = p.matcher(str);while (m.find()) {String s = m.group();list.add(s);}return list;}//网络爬取private static String webCrawler(String web) throws IOException {//获取网址对象URL url = new URL(web);//让程序连接网址URLConnection uc = url.openConnection();//读取网址内的数据://得到得到连接网址的字节输入流InputStream is = uc.getInputStream();//利用转换流将字节流转换为字符流方便读中文InputStreamReader isr = new InputStreamReader(is);//定义StringBuilder用于拼接读到的数据StringBuilder sb = new StringBuilder();//开始读int b;while ((b = isr.read()) != -1) {sb.append((char) b);}//读完关流isr.close();//返回读到的数据return sb.toString();}
}

相关文章:

  • 设计模式——简单工厂模式
  • CST软件基础六:视图
  • 热点│衰老过程中的表观遗传调控
  • QT-VStudio2107加载项目,报出“元素 <LanguageStandard>只有无效值“Default“”
  • Cat.4+WiFi6工业路由器介绍小体积大作用ER4200
  • 【Hadoop】大数据技术之 HDFS
  • vite学习笔记
  • 阿里云API RAG全流程实战:从模型调用到多模态应用的完整技术链路
  • 阿里云ecs如何禁用ip的访问
  • 【CSS学习笔记1】css基础知识介绍
  • 【软考向】Chapter 11 标准化和软件知识产权基础知识
  • 什么是nginx的异步非阻塞
  • 每日c/c++题 备战蓝桥杯(修理牛棚 Barn Repair)
  • voc怎么转yolo,如何分割数据集为验证集,怎样检测CUDA可用性 并使用yolov8训练安全帽数据集且构建基于yolov8深度学习的安全帽检测系统
  • upload-labs通关笔记-第19关文件上传之条件竞争
  • Fastjson利用链JdbcRowSetImpl分析
  • 多维数据助力企业网络安全
  • 2025年最新基于Vue基础项目Todolist任务编辑器【适合新手入手】【有这一片足够了】【附源码】
  • 基于 SpringBoot + Vue 的海滨体育馆管理系统设计与实现
  • Gmsh 代码深度解析与应用实例
  • 东莞做网站seo/微信引流主动被加软件
  • 古董交易网站怎么做/百度人工服务
  • 原创 网站 源码/优化网站怎么做
  • 全美网站建设/seo做的比较好的公司
  • 网站客户案例的/竞价推广代运营企业
  • 网站建设968/宁德市医院