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

【UCAS自然语言处理作业一】利用BeautifulSoup爬取中英文数据,计算熵,验证齐夫定律

文章目录

    • 前言
    • 中文
      • 数据爬取
        • 爬取界面
        • 爬取代码
      • 数据清洗
      • 数据分析
      • 实验结果
    • 英文
      • 数据爬取
        • 爬取界面
        • 动态爬取
      • 数据清洗
      • 数据分析
      • 实验结果
    • 结论

前言

  • 本文分别针对中文,英文语料进行爬虫,并在两种语言上计算其对应的熵,验证齐夫定律
  • github: ShiyuNee/python-spider (github.com)

中文

数据爬取

本实验对四大名著的内容进行爬取,并针对四大名著的内容展开中文文本分析,统计熵,验证齐夫定律

  • 爬取网站: https://5000yan.com/
  • 以水浒传的爬取为例展示爬取过程
爬取界面

在这里插入图片描述

  • 我们需要通过本页面,找到水浒传所有章节对应的url,从而获取每一个章节的信息

  • 可以注意到,这里每个章节都在class=menu-itemli中,且这些项都包含在class=panbaiul内,因此,我们对这些项进行提取,就能获得所有章节对应的url

  • 以第一章为例,页面为

    在这里插入图片描述

    • 可以看到,所有的正文部分都包含在class=grapdiv内,因此,我们只要提取其内部所有div中的文字,拼接在一起即可获得全部正文
爬取代码
def get_book(url, out_path):root_url = urlheaders={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'} # chrome浏览器page_text=requests.get(root_url, headers=headers).content.decode()soup1=BeautifulSoup(page_text, 'lxml')res_list = []# 获取所有章节的urltag_list = soup1.find(class_='paiban').find_all(class_='menu-item')url_list = [item.find('a')['href'] for item in tag_list]for item in url_list: # 对每一章节的内容进行提取chapter_page = requests.get(item, headers=headers).content.decode()chapter_soup = BeautifulSoup(chapter_page, 'lxml')res = ''try:chapter_content = chapter_soup.find(class_='grap')except:raise ValueError(f'no grap in the page {item}')chapter_text = chapter_content.find_all('div')print(chapter_text)for div_item in chapter_text:res += div_item.text.strip()res_list.append({'text': res})write_jsonl(res_list, out_path)
  • 我们使用beautifulsoup库,模拟Chrome浏览器的header,对每一本书的正文内容进行提取,并将结果保存到本地

数据清洗

  • 因为文本中会有括号,其中的内容是对正文内容的拼音,以及解释。这些解释是不需要的,因此我们首先对去除括号中的内容。注意是中文的括号

    def filter_cn(text):a = re.sub(u"\\(.*?)|\\{.*?}|\\[.*?]|\\【.*?】|\\(.*?\\)", "", text)return a
    
  • 使用结巴分词,对中文语句进行分词

    def tokenize(text):return jieba.cut(text)
    
  • 删除分词后的标点符号项

    def remove_punc(text):puncs = string.punctuation + "“”,。?、‘’:!;"new_text = ''.join([item for item in text if item not in puncs])return new_text
    
  • 对中文中存在的乱码,以及数字进行去除

    def get_cn_and_number(text):return re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039])","",text)
    

整体流程代码如下所示

def collect_data(data_list: list):voc = defaultdict(int)for data in data_list:for idx in range(len(data)):filtered_data = filter_cn(data[idx]['text'])tokenized_data = tokenize(filtered_data)for item in tokenized_data:k = remove_punc(item)k = get_cn_and_number(k)if k != '':voc[k] += 1return voc

数据分析

针对收集好的字典类型数据(key为词,value为词出现的次数),统计中文的熵,并验证齐夫定律

  • 熵的计算

    def compute_entropy(data: dict):cnt = 0total_num = sum(list(data.values()))print(total_num)for k, v in data.items():p = v / total_numcnt += -p * math.log(p)print(cnt)
    
  • 齐夫定律验证(由于词项比较多,为了展示相对细节的齐夫定律图,我们仅绘制前200个词)

    def zip_law(data: dict):cnt_list = data.values()sorted_cnt = sorted(enumerate(cnt_list), reverse=True, key=lambda x: x[1])plot_y = [item[1] for item in sorted_cnt[:200]]print(plot_y)x = range(len(plot_y))plot_x = [item + 1 for item in x]plt.plot(plot_x, plot_y)plt.show()
    

实验结果

  • 西游记

    • 熵:8.2221(共364221种token)

    在这里插入图片描述

  • 西游记+水浒传

    • 熵:8.5814(共836392种token)

      在这里插入图片描述

  • 西游记+水浒传+三国演义

    • 熵:8.8769(共1120315种token)

      在这里插入图片描述

  • 西游记+水浒传+三国演义+红楼梦

    • 熵:8.7349(共1585796种token)

      在这里插入图片描述

英文

数据爬取

本实验对英文读书网站上的图书进行爬取,并针对爬取内容进行统计,统计熵,验证齐夫定律

  • 爬取网站: Bilingual Books in English | AnyLang
  • 以The Little Prince为例介绍爬取过程
爬取界面

在这里插入图片描述

  • 我们需要通过本页面,找到所有书对应的url,然后获得每本书的内容

  • 可以注意到,每本书的url都在class=field-contentspan中,且这些项都包含在class=ajax-linka内,因此,我们对这些项进行提取,就能获得所有书对应的url

  • 以The Little Prince为例,页面为

    在这里插入图片描述

    • 可以看到,所有的正文部分都包含在class=page n*div内,因此,我们只要提取其内部所有div中的<p> </p>内的文字,拼接在一起即可获得全部正文
动态爬取

需要注意的是,英文书的内容较少,因此我们需要爬取多本书。但此页面只有下拉后才会加载出新的书,因此我们需要进行动态爬取

  • 使用selenium加载Chrome浏览器,并模拟浏览器下滑操作,这里模拟5次

    def down_ope(url):driver = webdriver.Chrome()  # 根据需要选择合适的浏览器驱动  driver.get(url)  # 替换为你要爬取的网站URL  for _ in range(5):driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")  time.sleep(5)return driver
    
  • driver中的内容传递给BeautifulSoup

        soup1=BeautifulSoup(driver.page_source, 'lxml')books = soup1.find_all(class_ = 'field-content')
    

整体代码为

def get_en_book(url, out_dir):root_url = url + '/en/books/en'headers={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'} # chrome浏览器driver = down_ope(root_url)soup1=BeautifulSoup(driver.page_source, 'lxml')books = soup1.find_all(class_ = 'field-content')book_url = [item.a['href'] for item in books]for item in book_url:if item[-4:] != 'read':continueout_path = out_dir + item.split('/')[-2] + '.jsonl'time.sleep(2)try:book_text=requests.get(url + item, headers=headers).content.decode()except:continuesoup2=BeautifulSoup(book_text, 'lxml')res_list = []sec_list = soup2.find_all('div', class_=re.compile('page n.*'))for sec in sec_list:res = ""sec_content = sec.find_all('p')for p_content in sec_content:text = p_content.text.strip()if text != '':res += textprint(res)res_list.append({'text': res})write_jsonl(res_list, out_path)

数据清洗

  • 使用nltk库进行分词

    def tokenize_en(text):sen_tok = nltk.sent_tokenize(text)word_tokens = [nltk.word_tokenize(item) for item in sen_tok]tokens = []for temp_tokens in word_tokens:for tok in temp_tokens:tokens.append(tok.lower())return tokens
    
  • 对分词后的token删除标点符号

    def remove_punc(text):puncs = string.punctuation + "“”,。?、‘’:!;"new_text = ''.join([item for item in text if item not in puncs])return new_text
    
  • 利用正则匹配只保留英文

    def get_en(text):return re.sub(r"[^a-zA-Z ]+", '', text)
    

整体流程代码如下

def collect_data_en(data_list: list):voc = defaultdict(int)for data in data_list:for idx in range(len(data)):tokenized_data = tokenize_en(data[idx]['text'])for item in tokenized_data:k = remove_punc(item)k = get_en(k)if k != '':voc[k] += 1return voc

数据分析

数据分析部分与中文部分的分析代码相同,都是利用数据清洗后得到的词典进行熵的计算,并绘制图像验证齐夫定律

实验结果

  • 10本书(1365212种token)

    • 熵:6.8537

    在这里插入图片描述

  • 30本书(3076942种token)

    • 熵:6.9168

      在这里插入图片描述

  • 60本书(4737396种token)

    • 熵:6.9164

      在这里插入图片描述

结论

从中文与英文的分析中不难看出,中文词的熵大于英文词的熵,且二者随语料库的增大都有逐渐增大的趋势。

  • 熵的数值与tokenizer,数据预处理方式有很大关系
  • 不同结论可能源于不同的数据量,tokenizer,数据处理方式

我们分别对中英文在三种不同数据量熵对齐夫定律进行验证

  • 齐夫定律:一个词(字)在语料库中出现的频率,与其按照出现频率的排名成反比

  • 若齐夫定律成立

    • 若我们直接对排序(Order)与出现频率(Count)进行绘制,则会得到一个反比例图像
    • 若我们对排序的对数(Log Order)与出现频率的对数(Log Count)进行绘制,则会得到一条直线
    • 这里由于长尾分布,为了方便分析,只对出现次数最多的top 1000个token进行绘制
  • 从绘制图像中可以看出,齐夫定律显然成立

相关文章:

【UCAS自然语言处理作业一】利用BeautifulSoup爬取中英文数据,计算熵,验证齐夫定律

文章目录 前言中文数据爬取爬取界面爬取代码 数据清洗数据分析实验结果 英文数据爬取爬取界面动态爬取 数据清洗数据分析实验结果 结论 前言 本文分别针对中文&#xff0c;英文语料进行爬虫&#xff0c;并在两种语言上计算其对应的熵&#xff0c;验证齐夫定律github: ShiyuNee…...

微信小程序之个人中心授权登录

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.了解微信授权登录 微信登录官网&#xff1a; 小程序登录https://developers.weixin.qq.com/miniprogram/d…...

Elasticsearch的聚集统计,可以进行各种统计分析

说明&#xff1a; Elasticsearch不仅是一个大数据搜索引擎&#xff0c;也是一个大数据分析引擎。它的聚集(aggregation)统计的REST端点可用于实现与统计分析有关的功能。Elasticsearch提供的聚集分为三大类。 度量聚集(Metric aggregation)&#xff1a;度量聚集可以用于计算搜…...

Webpack 理解 input output 概念

一、介绍 如果还没用过 Webpack 请先阅读 Webpack & 基础入门 再回头看本文。 Webpack 的核心只做两件事&#xff0c;输入管理&#xff08;Input Management&#xff09;和输出管理&#xff08;Output Management&#xff09;&#xff0c;什么花里胡哨的插件和配置都离不…...

【字符函数】

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;进阶C语言 &#x1f388;相关博文&#xff1a;字符串函数&#xff08;一&#xff09;、字符串函数&#xff08;二&#xff09; 字符函数 字符函数1.字符分类函数1.1 iscntrl - 判断是否是控制字符1.2 i…...

git创建与合并分支

文章目录 创建与合并分支分支管理的概念实际操作 解决冲突分支管理策略Bug分支Feature分支多人协作 创建与合并分支 分支管理的概念 分支在实际中有什么用呢&#xff1f;假设你准备开发一个新功能&#xff0c;但是需要两周才能完成&#xff0c;第一周你写了50%的代码&#xf…...

【电子通识】USB TYPE-A 2.0/3.0连接器接口

基础知识 USB TYPE-A连接器又可称为USB-A&#xff0c;现在不少PC、PC周边、手机充电器等等都依然采用了这种扁平的矩形接口&#xff0c;是目前普及度最高的USB接口了。 USB-A亦有分为插头与插座。常见的USB-A数据线的A端就是插头&#xff0c;而充电器上的则是插座。插头和插座…...

org.apache.sshd的SshClient客户端 连接服务器执行命令 示例

引入依赖 <dependency><groupId>org.apache.sshd</groupId><artifactId>sshd-core</artifactId><version>2.9.1</version></dependency>示例代码&#xff0c;可以直接执行&#xff0c;也可以做替换命令、维护session等修改 p…...

STM32 裸机编程 03

MCU 启动和向量表 当 STM32F429 MCU 启动时&#xff0c;它会从 flash 存储区最前面的位置读取一个叫作“向量表”的东西。“向量表”的概念所有 ARM MCU 都通用&#xff0c;它是一个包含 32 位中断处理程序地址的数组。对于所有 ARM MCU&#xff0c;向量表前 16 个地址由 ARM …...

Python ‘list‘ object is not callable错误

我尝试着解决“TypeError: ‘list’ object is not callable”这个错误。在Python编程中&#xff0c;我有时会遇到这个错误。这个错误通常是由于我错误地尝试像函数一样调用一个列表对象。为了解决这个问题&#xff0c;我需要找出错误发生的具体位置&#xff0c;然后进行修正。…...

原生php 实现redis登录五次被禁,隔天再登陆

<?php /*** Created by PhpStorm.* User: finejade* Date: 2023-10-18* Time: 11:08*/ session_start();include_once(header.php); include_once(connect.php); include_once(common.php); include_once(redis.php); try {// 常量 用户错误次数记录define("USER_LOGI…...

24. Kernel 4.19环境下,Cilium网络仍然需要使用iptables

在设计这套容器集群服务时,我从原来的k3s架构中分离出一个问题,那就是容器网络插件应该选择哪个。因为我设计的目标是给服务器领域使用的容器引擎,所以我就不需要考虑太多边缘IOT设备的情况,直接拉满技能找了cilium。cilium借助内核ebpf技术的出现,让我看到了网络性能更好…...

java中的容器(集合),HashMap底层原理,ArrayList、LinkedList、Vector区别,hashMap加载因子0.75原因

一、java中的容器 集合主要分为Collection和Map两大接口&#xff1b;Collection集合的子接口有List、Set&#xff1b;List集合的实现类有ArrayList底层是数组、LinkedList底层是双向非循环列表、Vector&#xff1b;Set集合的实现类有HashSet、TreeSet&#xff1b;Map集合的实现…...

Linux Server 终止后立即重启报错 bind error: Address already in use

先启动Server&#xff0c;再启动Client&#xff0c;然后使用CtrlC关闭Server&#xff0c;马上再运行Server&#xff0c;会得到以下结果&#xff1a; bind error: Address already in use这是因为&#xff0c;虽然Server的应用程序终止了&#xff0c;但TCP协议层的连接并没有完全…...

【Python 千题 —— 基础篇】分解数据

题目描述 题目描述 编写一个程序&#xff0c;输入一个类似 “233,234,235” 格式的字符串&#xff0c;然后提取字符串中的数字&#xff0c;将这些数字存储在列表中&#xff0c;并输出该列表。在这里&#xff0c;我们使用 eval 函数来解析字符串中的数字。 输入描述 输入一个…...

【C++】C++11新特性之右值引用与移动语义

文章目录 一、左值与左值引用二、右值与右值引用三、 左值引用与右值引用比较四、右值引用使用场景和意义1.左值引用的短板2.移动构造和移动赋值3.STL中右值引用的使用 五、万能引用与完美转发1.万能引用2.完美转发 一、左值与左值引用 在C11之前&#xff0c;我们把数据分为常…...

家庭燃气表微信抄表识别系统

1.背景需求 目前家里燃气度数的读数上报&#xff0c;每个月在社区微信群里面将手机拍摄的燃气表读数截图&#xff08;加住址信息水印&#xff09;&#xff0c;发到群里给抄表员。 2.总体设计 设计目标 功能一&#xff1a;手机上随时可以远程采集读数图片&#xff08;自动加住…...

EF执行迁移时提示provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的

ef在执行时提示provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的。 只需要在数据库链接字符串后增加EncryptTrue;TrustServerCertificateTrue;即可 再次执行...

视频标注的两个主要方法

视频标注技术 单一图像法 在自动化工具面世之前&#xff0c;视频标注效率不高。各公司使用单一图像法提取视频中的所有帧&#xff0c;然后使用标准图像标注技术将它们作为图像来标注。在30fps的视频中&#xff0c;每分钟有1800帧。这个过程没有利用视频标注的优势&#xff0c;…...

学成在线第一天-项目介绍、项目的搭建、开发流程以及相关面试题

目录 一、项目介绍 二、项目搭建 三、开发流程 四、相关面试题 五、总结 一、项目介绍 背景 业务 技术 背景&#xff1a;首先是整个这个行业的背景 然后基于这个行业的背景引出当前项目的背景 业务&#xff1a;功能模块 功能业务流程 技术&#xff1a;整体架构&am…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

初探用uniapp写微信小程序遇到的问题及解决(vue3+ts)

零、关于开发思路 (一)拿到工作任务,先理清楚需求 1.逻辑部分 不放过原型里说的每一句话,有疑惑的部分该问产品/测试/之前的开发就问 2.页面部分(含国际化) 整体看过需要开发页面的原型后,分类一下哪些组件/样式可以复用,直接提取出来使用 (时间充分的前提下,不…...

Linux信号保存与处理机制详解

Linux信号的保存与处理涉及多个关键机制&#xff0c;以下是详细的总结&#xff1a; 1. 信号的保存 进程描述符&#xff08;task_struct&#xff09;&#xff1a;每个进程的PCB中包含信号相关信息。 pending信号集&#xff1a;记录已到达但未处理的信号&#xff08;未决信号&a…...