网络爬虫--生成假数据

news2024/12/26 15:47:42

爬取网址中的数据。

下面3个分别是姓、女孩名字、男孩名字的网址。 

        String familyURLStr = "http://www.baijiaxing.net.cn/";
        String girlNameURLStr = "https://wannianli.tianqi.com/qiming/news/16536.html";
        String boyNameURLStr = "https://wannianli.tianqi.com/qiming/news/883.html";

如何爬取呢?

1、首先有一个网址

这是一个百家姓的网址。

String familyURLStr = "http://www.baijiaxing.net.cn/";

 2、爬取网址中的全部数据

注意注释中的细节。

    //爬取全部数据
    private static String webUrl(String URLStr) throws IOException {
        //先转换为url对象
        URL url = new URL(URLStr);
        //打开连接
        URLConnection conn = url.openConnection();
        //利用IO流进行读取
        //1.由于url对象提供字节流进行读取,无法读取中文,所以转换为字符流
        InputStreamReader isr = new InputStreamReader(conn.getInputStream());
        //使用一次read()方法只能读取一个字符
        //使用sb把读取出来的字符存起来
        StringBuilder sb = new StringBuilder();
        int b;
        while ((b = isr.read()) != -1) {
            sb.append((char)b);
        }
        return sb.toString();
    }

输出结果是以下html这种格式的,由服务器传过来的原本就是html,只不过平时被浏览器解析了而已。

 3、提取需要的信息

对我们有用的只有其中的姓氏而已,所以利用正则表达式进行匹配。

①下面是利用正则表达式读取数据的代码:

    private static ArrayList<String> getData(String str, String regex) {
        ArrayList<String> list = new ArrayList<>();
        //转换为正则表达式对象
        Pattern pattern = Pattern.compile(regex);
        //将字符串与正则表达式进行匹配
        Matcher matcher = pattern.matcher(str);
        //是否有与正则表达式匹配的值,有则返回true,无则返回false
        while (matcher.find()){
            //将匹配到的值进行返回
            list.add(matcher.group());
        }
        return list;
    }

②正则表达式如何书写?

观察百家姓可以看到都是4个汉字一组,并且后面跟着中文的","或者中文的"。",所以正则表达式可写为

".{4},|。"

输出结果如下:

输出为什么是这种格式?

因为这种情况下,把".{4},"看作一个逻辑,"。"看作一个逻辑,所以应该把,|。括起来,正确的是

.{4}(,|。)

但是又出现一个问题,返回结果我们只想要前面的4个汉字,不想要后面中文的","或者中文的"。",这种情况下有两种解决办法。

(1)这种需求很常见,所以专门提出了一个符号去解决这个问题,就是?=,将匹配结果进行返回时忽略?=后面的东西,但是匹配的时候还是参与的,因此正则表达式可写为

".{4}(?=,|。)"

(2)将正则表达式使用括号进行分组,然后在使用matcher.group()将匹配结果进行返回时,可以选择返回哪些组。

正则表达式可写为

"(.{4})(,|。)"

这种情况下,提取需要的数据的方法就需要额外加上一个参数,就是要返回的组号。

关于组号有一些说明:组号从1开始编,也存在一个特殊的0,表示全部数据。

    private static ArrayList<String> getData(String str, String regex, int index ) {
        ArrayList<String> list = new ArrayList<>();
        //转换为正则表达式对象
        Pattern pattern = Pattern.compile(regex);
        //将字符串与正则表达式进行匹配
        Matcher matcher = pattern.matcher(str);
        //是否有与正则表达式匹配的值,有则返回true,无则返回false
        while (matcher.find()){
            //将匹配到的值进行返回
            list.add(matcher.group(index));
        }
        return list;
    }

返回结果:

错误1:在与网址建立连接时抛错:Server returned HTTP response code: 403 for URL,如下图:

解决办法:在建立完连接之后加上

conn.setRequestProperty("User-Agent", "Mozilla/4.76");
        //打开连接
        URLConnection conn = url.openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/4.76");

如何写女生名字的正则表达式呢? 

首先看到2个汉字一组,并且后面跟着中文的"、"或者中文的"。",所以正则表达式可写为

".{2}(?=、|。)"

返回结果如下:

可以看到把一些不是名字的汉字也给返回了,原因就是也符合正则表达式。那怎么解决呢?

把"露怡、琦倩、澜蕾、思琳、"看作一组进行匹配,正则表达式可写为

"(.{2}(、|。)){4}"

返回结果如下:

如何写男生名字的正则表达式呢? 

下面是一个男生名字的网址:

100个好听的男孩名字,古风儒雅、洒脱大气的好名字! - 知乎 (zhihu.com)

网址中的数据如下:

如果依旧按照前面的把4个看作一组进行匹配,会把前面的序号也进行匹配,这不是我们想要的,所以要限定为中文。

有一个插件AnyRule,可以搜索常见需求的正则表达式,鼠标右键一下可看到:

打开之后搜索中文的正则表达式:

复制:[\u4E00-\u9FA5]

因此正则表达式写为

"([\\u4E00-\\u9FA5]{2}(、|\\n)){4}"

输出结果一直为空,刚开始以为是正则表达式有问题,后面怀疑知乎是不是有反爬啊。

测试一下,输出爬取的全部数据:

答案确实是这样,知乎将数据处理成密文了,所以无法匹配到与正则表达式相符的数据,导致输出一直为空。

只能换个网址了。

换成这个:【男孩名字】好听的男孩名字大全_男孩独特少见的名字_男孩简单大气的名字_亲子百科_太平洋亲子网 (pcbaby.com.cn)

结果还是有问题,爬取的中文无法解析,是乱码的。 

又接连试了好几个网址,都是同样的问题,都怀疑是不是代码有问题了,于是又回去测试了一下姓的爬取,也没有问题啊。

只能不断寻找不乱码的网址,终于找到一个:

男宝宝起名大全 100个好听的男孩名字 - 万年历 (tianqi.com)

输出结果如下:

下面对爬取的数据再次进行处理:

首先对姓进行处理,对于集合中的一个元素来说是有4个姓的,所以现在要拆开。

代码如下:

可以看到有错误提示: 

使用强制类型转换无法将char转为String, 那怎么办呢?

解决办法就是使用+将字符和空字符串""进行拼接就可以转换了。

正确的代码如下:

    private static ArrayList<String> processData(ArrayList<String> familyNameTempList) {
        ArrayList<String> familyNameList = new ArrayList<>();
        for (String s : familyNameTempList) {
            for (int i = 0; i < s.length(); i++) {
                familyNameList.add("" + s.charAt(i));
            }
        }
        return familyNameList;
    }

对名字进行处理,代码如下:

    //由于男孩和女孩的格式差不多,由一个方法进行处理
    private static ArrayList<String> processName(ArrayList<String> nameTempList) {
        ArrayList<String> nameList = new ArrayList<>();
        for (String s : nameTempList) {
            String[] ss = s.split("、");
            for (String name : ss) {
                nameList.add(name);
            }
        }
        return nameList;
    }

姓和名处理之后的结果如下:

下面将姓和名进行拼接,生成姓名,代码如下:

    private static HashSet<String> getFullName(ArrayList<String> familyNameList, ArrayList<String> nameList, int number) {
        //由于名字不能重复,所以选用HashSet存
        HashSet<String> fullNamehs = new HashSet<>();
        for (int i = 0; i < number; i++) {
            //1.首先随机选取姓和名
            //没有使用随机数的方式,而是集合工具类的shuffle()方法
            Collections.shuffle(familyNameList);
            Collections.shuffle(nameList);
            //选取索引0处的元素
            String familyName = familyNameList.get(0);
            String name = nameList.get(0);
            //将姓和名进行拼接并添加到集合中
            fullNamehs.add(familyName + name);
        }
        return fullNamehs;
    }

生成指定格式的数据,代码如下:

     //生成男生信息
    private static HashSet<String> getBoyInfo(HashSet<String> fullBoyNamehs) {
        HashSet<String> infohs = new HashSet<>();
        //生成年龄
        Random r = new Random();
        for (String fullName : fullBoyNamehs) {
            int age = r.nextInt(10) + 18;
            infohs.add(fullName + "-男-" + age);
        }
        return infohs;
    }

    //生成女生信息
    private static HashSet<String> getGirlInfo(HashSet<String> fullGirlNamehs) {
        HashSet<String> infohs = new HashSet<>();
        //生成年龄
        Random r = new Random();
        for (String fullName : fullGirlNamehs) {
            int age = r.nextInt(8) + 18;
            infohs.add(fullName + "-女-" + age);
        }
        return infohs;
    }

 将其写入到外部设备中,代码如下:

    //写到外部设备中
    private static void writeInfo(HashSet<String> girlInfo, HashSet<String> boyInfo) throws IOException {
        ArrayList<String> infoList = new ArrayList<>();
        infoList.addAll(girlInfo);
        infoList.addAll(boyInfo);
        Collections.shuffle(infoList);
        BufferedWriter bw = new BufferedWriter(new FileWriter("name.txt"));
        for (String info : infoList) {
            bw.write(info);
            bw.newLine();
        }
        bw.close();
    }

可以看到已写入到文件中:

总结一下全部过程就是:爬取数据--对数据进行处理--写入文件。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2086434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python脚本自动备份华为交换机配置,Console重置密码,升级系统文件

Python脚本自动备份华为交换机配置,Console重置密码,升级系统文件 1.说明2.Console口重置密码3.版本升级4.SSH配置5.python脚本—————————————————————————————————————————————————— 1.说明 恢复密码交换机型号:Quidwa…

YB2421E是一款专为降低电磁干扰特性而设计的降压型DC/DC转换器

现代生活中&#xff0c;我们离不开各种电子设备的陪伴&#xff0c;而这些设备的正常运行离不开稳定的电源供应。YB2421E同步降压电压转换器可以满足您对电源供应的需求。 YB2421E是一款专为降低电磁干扰特性而设计的降压型DC/DC转换器。它采用了单片集成电路的设计&#xff0c;…

MyBatis错误

说明&#xff1a;记录一次MyBatis错误&#xff0c;错误信息如下&#xff0c;说数字转换异常&#xff0c;显然&#xff0c;把一个字符串类型转为数字类型&#xff0c;肯定是不行的。 2024-08-29 19:44:43.198 ERROR 24216 --- [nio-9090-exec-2] o.a.c.c.C.[.[.[/].[dispatcher…

RocketMQ部署单机版及集群版本(Docker部署)

目录 前言 单机版部署 1. 准备工作 2. 创建Docker网络 3.启动NameServer 4.启动Broker 5.启动RocketMQ控制台 集群版部署 1.启动NameServer 2.启动Broker 配置文件说明 前言 废话不多直接上干货&#xff0c;我负责踩坑&#xff0c;你负责验证。 单机版部署 1. 准备工…

DCMM数据管理能力成熟度评估模型解读

DCMM(GBT36073-2018)数据管理能力成熟度评估模型解读 DCMM标准的核心点在于通过八个核心能力域和五个成熟度等级的划分&#xff0c;全面评估企业的数据管理能力&#xff0c;并为企业提供提升数据管理能力的路径和方法&#xff0c;从而推动企业在信息化、数字化、智能化方面的发…

光伏设计中组串逆变和微型逆变是什么意思?有什么区别?

在光伏系统设计中&#xff0c;逆变器是核心组件之一&#xff0c;负责将太阳能电池板产生的直流电转换为交流电&#xff0c;以供家庭、商业或电网使用。根据设计和应用场景的不同&#xff0c;逆变器主要分为组串逆变器和微型逆变器两大类。 一、组串逆变器的定义 组串逆变器是太…

力扣面试经典算法150题:整数转罗马数字

整数转罗马数字 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a; 整数转罗马数字。 题目链接&#xff1a;https://leetcode.cn/problems/integer-to-roman/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 七个不同的符号代表罗马…

【EI稳定检索】2024年第三届环境工程与可持续能源国际会议

2024年第三届环境工程与可持续能源国际会议&#xff08;EESE 2024&#xff09;将于12月20日至22日在长沙举行&#xff0c;由西安交通大学等支持&#xff0c;EI检索&#xff0c;投稿截止10月18日&#xff0c;AC学术中心提供技术支持和免费投稿系统。 2024年第三届环境工程与可持…

鸿蒙(API 12 Beta3版)【默认界面扫码】

基本概念 默认界面扫码能力提供系统级体验一致的扫码界面&#xff0c;Scan Kit对系统相机权限进行了预授权&#xff0c;调用接口时&#xff0c;无需开发者再次申请相机权限。适用于不同扫码场景的应用开发。 说明 通过默认界面扫码可以实现应用内的扫码功能&#xff0c;为了…

机器学习:TF-IDF算法原理及代码实现

TF-IDF是一种用于信息检索与文本挖掘的常用加权技术。它是一种统计方法&#xff0c;用以评估一个词语对于一个文件集或一个语料库中的其中一份文件的重要程度。它的主要思想是&#xff1a;如果某个词语在一篇文章中出现的频率高&#xff08;Term Frequency&#xff0c;TF&#…

路别走窄了,华为认证的这些方向,比数通值钱

华为认证作为全球领先的ICT技术认证之一&#xff0c;以其高标准和权威性在全球范围内受到认可。它不仅代表了专业技能的国际水平&#xff0c;更是IT专业人士职业生涯中的重要里程碑。但谈论起华为认证&#xff0c;似乎大家都默认首选数通。 不止在华为认证&#xff0c;而是在整…

10个伪原创软件,改写文章效率高

在内容为王的时代&#xff0c;高效地改写文章已成为许多创作者和营销人员必备的技能。伪原创软件作为提升工作效率的利器&#xff0c;可以帮助用户在短时间内生成质量上乘的全新内容。以下是10个备受推崇的伪原创软件&#xff0c;它们各具特色&#xff0c;能够助力创作者大幅提…

猫头虎 分享已解决Bug || ReferenceError: Can‘t find variable: React 解决方案

猫头虎 分享已解决Bug || ReferenceError: Cant find variable: React 解决方案 今天猫头虎要跟大家分享一个前端开发中常见的问题&#xff1a; ReferenceError: Cant find variable: React。这个错误常常出现在我们开发React项目时&#xff0c;特别是在新手刚接触React或者是团…

如何快速创建个性化视频二维码用于产品宣传

产品视频二维码营销推广在实际应用中具有广泛的用途&#xff0c;可以有效地帮助企业推广品牌、产品和服务。常见的应用场景有&#xff1a;产品广告和宣传材料、产品包装展示、展会和活动、店内展示、旅游和景点介绍等。 那么如何快速制作和创建带企业图标的产品视频二维码呢&am…

【香橙派系列教程】(十九) 使用文件编程实现开关盖的历史记录

【十九】使用文件编程实现开关盖的历史记录 我现在多了一个需求&#xff0c;我需要在每次识别垃圾时&#xff0c;将垃圾的种类记录下来&#xff0c;同时记录下时间。 Linux显示当前的时间&#xff1a;date指令 //打印当前的 “年-月-日-时-分-秒” date "%Y-%m-%d %H:%M:…

开环响应(频率响应+相移响应)+闭环响应(负反馈对带宽的影响+增益-带宽积)+正反馈与稳定性/补偿(选学)

2024-8-29&#xff0c;星期四&#xff0c;20:01&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴。今天没什么事情发生&#xff0c;继续学习。 今天完成了第七章的学习&#xff0c;主要学习内容为&#xff1a;开环响应(频率响应相移响应)闭环响应(负反馈对带宽的…

鸿蒙开发入门day15-焦点事件

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;还请三连支持一波哇ヾ(&#xff20;^∇^&#xff20;)ノ&#xff09; 目录 焦点事件 基础概念与规范 基础概念 走焦规范 走焦算法 获焦/失…

Layer Normalization(层归一化)里的可学习的参数

参考pyttorch官方文档&#xff1a; LayerNorm — PyTorch 2.4 documentation 在深度学习模型中&#xff0c;层归一化&#xff08;Layer Normalization, 简称LN&#xff09;是一种常用的技术&#xff0c;用于稳定和加速神经网络的训练。层归一化通过对单个样本内的所有激活进行…

各种数据降维方法ICA、 ISOMAP、 LDA、LE、 LLE、MDS、 PCA、 KPCA、SPCA、SVD、 JADE

独立分量分析 ICA 等度量映射 ISOMAP 线性判别分析 LDA (拉普拉斯)数据降维方法 LE 局部线性嵌入 LLE 多维尺度变换MDS 主成分分析 PCA 核主成分分析 KPCA 稀疏主成分分析SPCA 奇异值分解SVD 特征矩阵的联合近似对角化 JADE 各种数据降维方法(matlab代码)代码获取戳此处代码获取…

一篇文章讲清楚Java中的反射

介绍 每个类都有一个 Class 对象&#xff0c;包含了与类有关的信息。当编译一个新类时&#xff0c;会产生一个同名的 .class 文件&#xff0c;该文件内容保存着 Class 对象。 类加载相当于 Class 对象的加载。类在第一次使用时才动态加载到 JVM 中&#xff0c;可以使用 Class…