当前位置: 首页 > 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();}
}

http://www.xdnf.cn/news/608347.html

相关文章:

  • Redis 8.0 新增数据结构深度解析:从核心功能到生态重构
  • 【数据架构04】数据湖架构篇
  • Flutter跨平台通信实战|3步打通Android原生能力,实现底层API调用!
  • Flutter - 国际化
  • Flutter 3.32 升级要点全解析
  • ros2 humble安装ros-humble-tf2-tools
  • 布丁扫描高级会员版 v3.5.2.2| 安卓智能扫描 APP OCR文字识别小助手
  • 数字人交互系统哪家强?品牌技术对比!
  • JavaScript进阶(十二)
  • 【AS32X601驱动系列教程】GPIO_点亮LED详解
  • 在bash中,如何打开特定文件,使用特定字符串替换特定字符串?请编写代码
  • 哈希表的实现(上)
  • mac将自己网络暴露到公网
  • ROS云课三分钟-cmake gcc g++ 默认版本和升级-250523
  • 前后端联调实战指南:Axios拦截器、CORS与JWT身份验证全解析
  • 提示词工程框架——CO-STAR 框架实战
  • 江科大DMA直接存储器访问hal库实现
  • 深度剖析 MCP SDK 最新版:Streamable HTTP 模式
  • 学习黑客Nmap 是什么?
  • 数据结构 -- 交换排序(冒泡排序和快速排序)
  • 信息安全管理与评估赛项参考答案-模块1网络平台搭建
  • 【软件测试】第三章·软件测试基本方法(基于需求的测试方法)
  • Trae+12306 MCP,10分钟搭建行程可视化助手
  • Gmsh 代码深度解析与应用实例
  • 【开源项目1】基于机器学习木马查杀引擎项目
  • 1.3 线性系统的时域分析法
  • kafka速度快的原理
  • 【时时三省】(C语言基础)对被调用函数的声明和函数原型
  • [Datagear] [SQL]实现分组统计同时带汇总行的两种方式对比分析
  • AI架构师的新工具箱:ChatGPT、Copilot、AutoML、模型服务平台