爬取日本常用汉字秘籍

news2024/10/7 16:19:39

前言

昨天投简历时遇到了这样的一个笔试。本以为会是数据结构算法之类的没想到直接发了一个word直接提需求,感觉挺有意思就写了这篇文章,感兴趣的朋友可以看看。
image.png

image.png

1. 网页内容解析

首先,我们通过请求网页获取到日本常用汉字的链接列表。然后,针对每个汉字链接,我们提取网页中相应部分的 HTML 内容。

首先分析页面结构

image.png
发现这些汉字有着相同的规律,先将.parts_box类标签拿到之后再用css选择器拿到对应的汉字标签.

url = 'https://kanji.jitenon.jp/cat/joyo.html'
response = requests.get(url)
response.encoding = 'utf-8'
html_content = response.text

css_selector = '#content > div.bushu_wrap > div > .parts_box '
parsed_elements = parse_css(html_content, css_selector)
urllist = []
for element in parsed_elements:
    chineslinks = element.select(".search_parts > li > a")
    for chineslink in chineslinks:
        chines = {}
        chines['link'] = chineslink['href']
        chines['name'] = chineslink.text
        urllist.append(chines)

首先,我用了Python的requests库发送了一个HTTP请求,抓取了目标网站的内容。然后,用了BeautifulSoup库进行HTML解析,找到了我需要的信息。通过一个简单的CSS选择器,我成功地定位到了汉字链接的位置。

接着,我遍历了这些链接,将它们逐个存储在了一个名为urllist的列表中。每个链接都包含着汉字的名称和对应的链接地址。

2.详情页解析

image.png

image.png
通过对比前两字可以发现每个字的介绍里的属性都有可能不一样,因此这里的思路是先拿到这部分标签的整体text,然后通过正则去进行筛选匹配。在进行字符拼接时加上分隔符,为之后的对转成列表形式时的字符分割做准备。

def get_detailed(chines):
    url = chines['link']
    response = requests.get(url)
    response.encoding = 'utf-8'
    html_content = response.text
    css_selector = '#content > article > div.search_data > div > div.kanji_wrap > div.kanji_right > div > section > table >tbody > tr '
    parsed_elements = parse_css(html_content, css_selector)
    text = ''
    separator = '%'  # 定义分隔符
    for element in parsed_elements:
        # print(element.text)
        text =text+ ' '.join(element.stripped_strings)+ separator

        font = {}
        font['name'] = chines['name']
        #
        # fontkey = element.select(".ruby_switch")[0].text
        # fontvaule = element.select(".ruby_switch > span")
        # print(fontkey)
    # print(text)

    def extract_text_between_patterns(text, start_patterns, end_patterns):
        """
        从文本中提取两个模式之间的文本。

        参数:
            text (str): 待提取文本。
            start_patterns (list): 匹配文本起始的模式列表。
            end_patterns (list): 匹配文本结束的模式列表。

        返回:
            list: 匹配的文本列表,如果没有匹配项则返回None。
        """
        matches = []  # 存储匹配结果的列表
        for start_pattern in start_patterns:
            for end_pattern in end_patterns:
                # 查找所有起始模式的位置
                start_matches = [match.end() for match in re.finditer(start_pattern, text)]
                # 查找所有结束模式的位置
                end_matches = [match.start() for match in re.finditer(end_pattern, text)]
                # 遍历每个起始位置和结束位置的组合
                for start_match in start_matches:
                    for end_match in end_matches:
                        if start_match < end_match:  # 确保结束位置在起始位置之后
                            subtext = text[start_match:end_match]  # 提取子文本
                            # 检查子文本中是否包含其他模式
                            if not any(pattern in subtext for pattern in start_patterns[1:] + end_patterns):
                                # 添加匹配的子文本到结果列表中,并保留第一个关键词
                                matches.append(text[text.find(start_pattern):end_match].strip())
                                break  # 找到一个匹配后退出当前循环
        return matches if matches else None  # 返回匹配结果列表,如果列表为空则返回None

    # 定义关键字列表
    start_patterns = ['部首', '画数', '音 読 み', '訓 読 み', '意味', '成 り 立 ち', '種別', '分類', '学年', '漢字 検定', 'JIS 水準']
    end_patterns = ['画数', '音 読 み', '訓 読 み', '意味', '成 り 立 ち', '種別', '分類', '学年', '漢字 検定', 'JIS 水準']

    # 调用函数进行提取
    results = extract_text_between_patterns(text, start_patterns, end_patterns)
    # print(results)
    # for i in range(len(results)):
    #     print(results[i])

    def create_dict(data, patterns):
        hanzi_dict = {}
        for item in data:
            for pattern in patterns:
                if pattern in item:
                    key, value = item.split(pattern, 1)
                    hanzi_dict[pattern.strip()] = value.strip()
                    break
        return hanzi_dict

    # 测试
    patterns = ['部首', '画数', '音 読 み', '訓 読 み', '意味', '成 り 立 ち', '種別', '分類', '学年', '漢字 検定', 'JIS 水準']
    # 解析数据
    hanzi_dict = create_dict(results, patterns)
    # 遍历hanzi_dict
    for key, value in hanzi_dict.items():
        parts = hanzi_dict[key].split('%')
        parts.pop()  # 移除最后一个空字符串
        if  len(parts) == 1:
            hanzi_dict[key] = str(parts[0])
            continue
        hanzi_dict[key] = parts

    return hanzi_dict

汉字详情页解析函数 get_detailed

该函数的主要目的是解析汉字的详情页,从中提取出部首、画数、音读み等关键信息,并以字典的形式返回。

  • 输入参数

    • chines:一个包含汉字链接和名称的字典,包括键 'link''name'
  • 功能

    1. 通过给定的链接获取汉字的详情页HTML内容。
    2. 使用CSS选择器定位到包含关键信息的元素。
    3. 提取目标信息并整理成字典格式。
  • 详细步骤

    1. 发送HTTP请求以获取详情页HTML内容,并将其编码为UTF-8格式。
    2. 使用预定义的CSS选择器来定位页面上包含关键信息的元素。
    3. 将解析得到的HTML元素提取出文本信息,并按照指定的分隔符连接成一个长字符串。
    4. 使用自定义的函数extract_text_between_patterns从长字符串中提取出具体信息,并整理成字典格式。
    5. 最后,返回包含关键信息的字典。
  • 关键函数

    • extract_text_between_patterns:从长字符串中提取出具体信息的函数,它根据指定的起始和结束模式来匹配文本,并返回匹配的结果列表。
  • 返回值

    • 一个字典,包含部首、画数、音读み等关键信息。

3.保存JSON

通过循环遍历urllist中的每个汉字链接,然后调用get_detailed函数来获取每个汉字的详细信息。获取到的信息被打印输出,并且添加到了名为ans的列表中。

接着,将整个ans列表保存为一个JSON文件,以便将获取到的汉字详细信息持久化存储下来。JSON文件的保存路径为当前目录下的ans.json文件,并且使用UTF-8编码格式,以确保能够正确地保存包含非ASCII字符的内容。

ans = []
for chines in urllist:
    chines = get_detailed(chines)
    print(chines)
    ans.append(chines)

# 将ans保存为json文件
with open('ans.json', 'w', encoding='utf-8') as f:
    json.dump(ans, f, ensure_ascii=False, indent=4)

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

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

相关文章

多线程java

多线程的创建 前两种方法无法返回直接结果,而有的线程执行完毕后需要返回结果 方式一:java是通过java.lang.Thread类的对象来代表线程的 启动线程必须调用strat方法,不是调用run方法不要把主线程任务放在启动子线程之前 //1.让子类继承Thread线程类 public class MyThread …

逻辑卷和磁盘配额

文章目录 一、逻辑卷二、磁盘配额 一、逻辑卷 为什么会出现技术&#xff1f; 分区的缺点&#xff1a; 没有备份功能无法扩容性能取决于硬盘本身 相关概念 LVM 是 Logical Volume Manager 的简称&#xff0c;译为中文就是逻辑卷管理。它是 Linux 下对硬盘分区的一种管理机制。…

HarmonyOS开发学习:【DevEco Device Tool 安装配置(问题全解)】

本文介绍如何在Windows主机上安装DevEco Device Tool工具。 坑点总结&#xff1a; 国内部分网络环境下&#xff0c;安装npm包可能会很慢或者超时&#xff0c;推荐使用国内npm源&#xff08;如淘宝源、华为源等&#xff09;&#xff1b;serialport这个npm包安装的过程中需要编…

STC8H8K64U 库函数学习笔记 —— GPIO 点灯

STC8H8K64U 库函数学习笔记 —— GPIO 点灯 环境说明&#xff1a; 芯片&#xff1a;STC8H8K64U 软件&#xff1a; KeilC51 μVersion V5.38.00STCAI-ISP (V6.94) 不得不说&#xff0c;Keil 是我用过的 IDE 中&#xff0c;最让人头疼的事情&#xff0c;写代码就像是在记事本里编…

【进阶篇】三、Java Agent实现自定义Arthas工具

文章目录 0、客户端代码1、JMX2、实现&#xff1a;查看内存使用情况3、实现&#xff1a;查看直接内存4、实现&#xff1a;生成堆内存快照5、实现&#xff1a;打印栈信息6、实现&#xff1a;打印类加载器的信息7、实现&#xff1a;打印类的源码8、需求&#xff1a;打印方法的耗时…

OpenHarmony开发学习:【源码下载和编译】

本文介绍了如何下载鸿蒙系统源码&#xff0c;如何一次性配置可以编译三个目标平台&#xff08;Hi3516&#xff0c;Hi3518和Hi3861&#xff09;的编译环境&#xff0c;以及如何将源码编译为三个目标平台的二进制文件。 坑点总结&#xff1a; 下载源码基本上没有太多坑&#xff…

HarmonyOS开发实例:【菜单app】

简介 分布式菜单demo 模拟的是多人聚餐点菜的场景&#xff0c;不需要扫码关注公众号等一系列操作&#xff0c;通过分布式数据库可以方便每个人可及时查看到订单详情&#xff0c;数量&#xff0c;总额等&#xff1b;效果如下 demo效果 工程目录 完整的项目结构目录如下 ├…

2024年DeFi的四大主导趋势:Restaking、Layer3、AI和DePin

DeFi&#xff08;去中心化金融&#xff09;行业在2024年将继续呈现快速增长的势头&#xff0c;驱动这一增长的主要因素将是四大主导趋势&#xff1a;Restaking、Layer3、AI和DePin。这些趋势将推动DeFi生态系统的发展&#xff0c;为用户提供更多的机会和创新。 趋势1&#xff…

雨云:不只是一阵清风,更是一场暴雨的力量

引言 在网络时代&#xff0c;服务器是任何在线业务的核心。无论你是运营一家小型博客还是承载着数百万用户的大型电商平台&#xff0c;都需要一个稳定、高效的服务器来支持你的业务。然而&#xff0c;在众多服务器提供商中&#xff0c;有一家备受推崇&#xff0c;那就是雨云。 …

【C语言】双向链表详解

文章目录 关于双向链表双向链表的初始化双向链表的打印双向链表方法调用 - 尾删为例双向链表的查找 - 指定位置之后插入为例双向链表结束 - 链表的销毁小结及整体代码实现 关于双向链表 首先链表有8种基本分法 其中在笔者之前文章种详细介绍的 单链表 是不带头单项不循环链表…

快速解锁3D Web渲染引擎HOOPS Communicator轻量化技术

在当今数字化时代&#xff0c;三维模型的使用已经成为许多行业中不可或缺的一部分。然而&#xff0c;随着模型复杂性的增加和数据量的膨胀&#xff0c;如何在Web浏览器中高效加载和渲染这些模型成为了一个挑战。慧都3D Web渲染引擎HOOPS Communicator通过其先进的轻量化技术&am…

测试过程和测试生命周期

软件测试过程是一系列有计划、有组织的活动&#xff0c;旨在识别和解决软件产品中的问题。这个过程通常包括多个阶段&#xff0c;每个阶段都有其特定的目标和方法。 需求分析&#xff1a; 分析软件需求和测试需求&#xff0c;确定测试的目标和范围。理解用户需求和业务目标&…

MM-Grounding-DINO的训练推理(待更新)

1、简单介绍 继前面发布的 GroundingDino 和 Open-GroundingDino的推理 和 Open-GroundingDino的训练实现&#xff0c;作为 GroundingDino延续性的文本检测网络 MM-Grounding-DINO 也发布了较详细的 训练和推理实现教程&#xff0c;而且操作性很强。作为学习内容&#xff0c;也…

我对硬技能与软技能的认知

今天看到一个很有意思的一段话&#xff0c;假设一个人的技能有两种&#xff0c;分别是&#xff1a;硬技能和软技能。 硬技能通常指的是与工作直接相关的、可以通过教育和培训获得的技能&#xff0c;如编程语言、会计知识等,这些技能往往有明确的衡量标准&#xff0c;容易通过考…

java 将 json 数据转为 java 中的对象

一、准备 json 数据 {"name": "mike","age": 17,"gender": 1,"subject": ["math","english"] }二、对应的java对象 package com.demo.controller;import lombok.Data; import java.util.List;Data pu…

鸿蒙TypeScript学习第13天:【元组】

1、TypeScript 元组 我们知道数组中元素的数据类型都一般是相同的&#xff08;any[] 类型的数组可以不同&#xff09;&#xff0c;如果存储的元素数据类型不同&#xff0c;则需要使用元组。参考文档&#xff1a;qr23.cn/AKFP8k 元组中允许存储不同类型的元素&#xff0c;元组…

【MATLAB第104期】基于MATLAB的xgboost的敏感性分析/特征值排序计算(针对多输入单输出回归预测模型)

【MATLAB第104期】基于MATLAB的xgboost的敏感性分析/特征值排序计算&#xff08;针对多输入单输出回归预测模型&#xff09; 因matlab的xgboost训练模型不含敏感性分析算法&#xff0c;本文通过使用single算法&#xff0c;即单特征因素对输出影响进行分析&#xff0c;得出不同…

Python 进度显示工具(tqdm)

tqdm 是一个进度显示工具&#xff0c;当任务执行的等待时间较长时&#xff0c;通过tqdm模块可以模拟出一个进度条&#xff0c;由此可以看到任务执行进度&#xff0c;获得更好的体验。 文章目录 一、tqdm的安装二、tqdm的使用2.1 基于可迭代对象2.2 手动进度更新2.3 命令行模式 …

【SpringBoot】mybatis-plus实现增删改查

mapper继承BaseMapper service 继承ServiceImpl 使用方法新增 save,updateById新增和修改方法返回boolean值,或者使用saveOrUpdate方法有id执行修改操作,没有id 执行新增操作 案例 Service public class UserService extends ServiceImpl<UserMapper,User> {// Au…

mac配置Jmeter环境

mac配置Jmeter环境 一、安装jmeter二、Jmeter目录结构三、汉化Jmeter四、jmeter安装第三方插件 一、安装jmeter 第一步先自行配置好电脑的jdk环境 1、官网下载jar包 https://jmeter.apache.org/download_jmeter.cgi 2、解压到软件安装目录 3、启动Jmeter 启动方式1️⃣&#x…