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

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.lryc.cn/news/2385355.html

相关文章:

  • Baklib内容中台的主要构成是什么?
  • 深度解析 Java 中介者模式:重构复杂交互场景的优雅方案
  • 家用和类似用途电器的安全 第1部分:通用要求 与2005版差异(7)
  • HTTP Digest 认证:原理剖析与服务端实现详解
  • untiy实现汽车漫游
  • PID项目---硬件设计
  • Pluto实验报告——基于FM的音频信号传输并解调恢复
  • 【Redis】AOF日志
  • Leetcode 2792. 计算足够大的节点数
  • 《关于浔川社团退出DevPress社区及内容撤回的声明》
  • Windows逆向工程提升之IMAGE_RESOURCE_DIRECTORY
  • 使用ps为图片添加水印
  • x64_ubuntu22.04.5安装:cuda driver + cuda toolkit
  • 开盘啦 APP 抓包 逆向分析
  • vs2022 Qt Visual Studio Tools插件设置
  • Python包__init__.py标识文件解析
  • 【MySQL】第8节|Innodb底层原理与Mysql日志机制深入剖析(一)
  • 电商ERP管理系统,Java+Vue,含源码与文档,统筹订单、库存等,助力电商企业高效运营
  • Spring Boot微服务架构(四):微服务的划分原则
  • 【打卡】树状数组的操作
  • OpenLayers 加载动画控件
  • Oracle 基础知识作业的使用
  • HTTP协议初认识、速了解
  • C#:多线程Task使用
  • 模拟电子技术基础----绪论
  • 从零基础到最佳实践:Vue.js 系列(2/10):《模板语法与数据绑定》
  • iOS 使用 - 设置 来电震动/关闭震动
  • anaconda、miniconda、conda的关系及miniconda安装
  • [C语言初阶]扫雷小游戏
  • 谷歌medgemma-27b-text-it医疗大模型论文速读:多语言大型语言模型医学问答基准测试MedExpQA