《Python程序设计基础》 课件第8章 实战项目之爬虫和分词·_第1页
《Python程序设计基础》 课件第8章 实战项目之爬虫和分词·_第2页
《Python程序设计基础》 课件第8章 实战项目之爬虫和分词·_第3页
《Python程序设计基础》 课件第8章 实战项目之爬虫和分词·_第4页
《Python程序设计基础》 课件第8章 实战项目之爬虫和分词·_第5页
已阅读5页,还剩90页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八章实战项目之爬虫和分词项目需求爬虫正则表达式分词思维导图学习目标掌握掌握掌握了解爬虫的概念和基本工作原理12掌握爬虫常用模块和函数的使用了解分词的概念和常用的分词库

4基本掌握正则表达的概念和语法

3技能目标掌握掌握掌握学会爬虫的基本编程应用12学会分词的基本编程应用进一步提升Python综合编程应用能力3思政目标1.学以致用,行以致远。要把研究和解决现实问题作为学习的根本出发点。2.“师夷长技以制夷”,从中国制造到中国创造是中国IT产业的必由之路。3.通过“核高基—从‘中国制造’到‘中国创造’的战略决策”的学习,了解拥有属于我国的真正安全、可靠、可控的基础软件是一代代IT人接续奋斗的目标。目录爬虫8.28.1项目需求8.3正则表达式8.4分词知识架构8.1项目需求1热词分析平台2数据库设计3网页内容分析4手机版网页新闻的获取5学生实践练习8.1项目需求1

热词分析平台

热词分析平台通过分析某段时间内最热门的关键字,并通过曲线图和柱状图的形式进行展示,它包含以下三个部分:(1)新闻的抓取和保存。例如,从163新闻网页中抓取每天最新的新闻,抓取地址为http://3,抓取后将新闻内容保存到MySQL数据库中。(2)分词处理。在控制台中输入要分析的时间段,在数据库中查询出该时间段内的新闻记录,使用结巴分词库对新闻内容进行关键字的分词处理。(3)数据整理、分析和清洗及图表展示。将分析好的关键字使用Pandas库存入DataFrame对象中。对关键字出现的次数进行排序,使用Matplotlib库将关键字和它出现的次数使用曲线图和柱状图表现出来。8.1项目需求1

热词分析平台

首先,在控制台中输入要分析的开始时间和结束时间,程序会根据输入的时间,在数据库中查询出结果,并开始分词处理,如图8.1所示。8.1项目需求1

热词分析平台

然后,将统计出来的前20个关键字用图表展示出来,处理完成后,折线图和柱状图如图8.2所示。8.1项目需求2

数据库设计

热点关注项目使用MySQL数据库保存数据。在该项目中,分析后的关键字在内存中存储即可,因此只需要创建一张新闻news表。新闻表的表结构见表8.1。8.1项目需求3

网页内容分析

想要抓取到数据,就必须知道有哪些途径获取数据源。目前数据源获取有3种途径:(1)PC端网站。内容比较繁杂,所以分析最复杂,作为最后考虑的途径。(2)针对移动设备设计的网站。大部分新闻平台都提供了针对移动设备设计的网站,如网易新闻除了PC端提供的新闻网址(/),还提供了针对移动设备的新闻网址(http://3)。内容相对简单,分析比较容易。(3)移动App。优先考虑的途径,一般使用Charles工具进行分析,有些App会加密,此时可以进行反编译分析,逆推出加密方法。8.1项目需求3

网页内容分析

通过什么办法可以爬取到网页中的所有新闻数据呢?一般情况,可以使用以下3种方式来分析:(1)分析网页源代码。(2)查看网页的访问地址。(3)借助浏览器提供的开发者工具来分析。当需要获取有用数据的请求地址时,在Chrome浏览器中按Ctrl+Shift+I组合键,即可弹出浏览器的开发者工具。单击开发者工具的“Network”菜单,查看每次访问的所有网络请求,如图所示。8.1项目需求4

手机版网页新闻的获取

本小节将以手机版搜狐新闻(/ch/8)的爬取为例进行讲解。每次将网页拖到底部,网站都会自动加载更多的新闻。但访问的地址没有改变,因此我们可以肯定搜狐新闻网站是通过异步请求加载新闻数据的。对于实现了自动加载功能的手机端新闻网站,基本使用异步请求。8.1项目需求4手机版网页新闻的获取获取手机版搜狐数据步骤如下:(1)在Chrome浏览器中打开/ch/8网址,如图8.4所示,使用Ctrl+Shift+I组合键打开开发者工具,或者单击菜单中的“更多工具”→“开发者工具”,清空当前的请求列表。8.1项目需求4

手机版网页新闻的获取

(2)将网页拖到底部,网页将自动加载新闻数据。在请求列表中可以发现,以.webp结尾的请求都是图片的请求地址。忽略图片请求后,在请求列表中查找请求新闻数据的链接。每个链接的右键菜单都提供了复制链接的地址功能,可以发现新闻数据的请求地址如下:/integrationapi/mix/region/90?secureScore=50&page=2&size=24&pvId=1567408590219xE6igXs&mpId=0&adapter=default&refer=&spm=&channel=8&requestId=1909021515402V4N_1567408882124清空当前的请求列表,再次拖到底部,查找新的请求地址如下:/integrationapi/mix/region/90?secureScore=50&page=3&size=24&pvId=1567408590219xE6igXs&mpId=0&adapter=default&refer=&spm=&channel=8&requestId=1909021515402V4N_15674089120798.1项目需求4

手机版网页新闻的获取

(3)通过两次请求的地址对比,可以发现请求参数中page表示第几页,第一页是page=1,依次类推。根据这个规律我们就可以获取到该网站的所有新闻数据。例如,访问page=2的新闻数据请求地址后显示的网页内容如图8.5所示。8.1项目需求4

手机版网页新闻的获取

(4)从请求的新闻列表数据格式可以看出,页面数据是一个标准的JSON字符串。通过对JSON字符串的解析,可以获取一条一条的新闻数据。(5)将新闻数据中的内容和新闻实际的访问地址进行对比,例如,其中一条新闻的数据如下:{"brief":"但中美两国正式建立外交关系不久…,"images":["//5b0988e595225….jpeg"],"cmsId":0,"mobileTitle":"要中国还1万亿美元清朝债…","mobilePersonalPage":"/media/114988","type":2,"authorId":114988,"authorPic":"//5b0988e595225….jpeg","title":"偿还1万亿美元清朝债券?这事儿特朗普都觉得不靠谱","url":"/a/338061381_114988","publicTime":1567390000000,"authorName":"新京报","id":338061381,"scm":"1002.10001.0.0-0","personalPage":"/profile?xpt=c29odXptdDNqdHpnY0Bzb2h1LmNvbQ==","resourceType":1}8.1项目需求4

手机版网页新闻的获取

而该新闻的访问地址为/a/338061381_114988,如图8.6所示。由图8.6可以看出,通过新闻数据中的url字段可获取实际的新闻地址,通过title字段可以获取新闻内容等。8.1项目需求1.需求说明

在MySQL数据库中创建数据库NewsDB和新闻表news表,news表结构见表8.1。2.实现思路(1)可以在Windows系统中搜索MySQL。找到“MySQLCommandLineClient”命令行客户端工具。输入密码后通过命令创建MySQL数据库,也可以使用NavicatMySQL工具创建。(2)创建数据库NewsDB和新闻表news表。5

学生实践练习

知识架构8.2爬虫1爬虫介绍2爬虫框架3通过URL浏览网页4urllib模块5POST方式和GET方式6学生实践练习8.2爬虫1

爬虫介绍

网络爬虫(又被称为网页蜘蛛、网络机器人)是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,抓取想要的内容或程序。网络爬虫是一个自动提取网页的程序,它从万维网上下载网页,是搜索引擎的重要组成部分。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的停止条件。聚焦爬虫的工作流程较为复杂,需要对网页进行分析,通过算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,当满足系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存储,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫而言,这一过程所得到的分析结果可能对以后的抓取过程给出反馈和指导。在该项目中,爬虫用来获取163新闻网站(网址为http://3)上的所有新闻记录。首先要获取该网站上所有的新闻链接地址,然后通过访问新闻的链接地址获取新闻的内容。8.2爬虫2

爬虫框架

目前比较优秀并且比较齐全的爬虫框架有Scrapy、PySpider、Grab和Cola。下面我们将分别介绍这几种框架。1.ScrapyScrapy是一个为了爬取网站数据、提取结构性数据而编写的应用框架,可以应用在包括数据挖掘、信息处理或存储历史数据等一系列的程序中,也可以应用在获取API所返回的数据(如AmazonAssociatesWebServices)或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy使用了Twisted异步网络数据库来处理网络通信。8.2爬虫2

爬虫框架Scrapy的主要组件如下:(1)引擎(Scrapy):用来处理整个系统的数据流,触发事务(框架核心)。(2)调度器(Scheduler):用来接收引擎发过来的请求,压入队列中,并在引擎再次请求时返回,可以将它想象成一个URL(抓取网页的网址或者说是链接)的优先队列,由它来决定下一个要抓取的网址是什么,同时去除重复的网址。(3)下载器(Downloader):用于下载网页内容,并将网页内容返回给蜘蛛(Scrapy下载器是建立在Twisted这个高效的异步模型上的)。(4)爬虫(Spiders):用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。8.2爬虫2

爬虫框架(5)项目管道(Pipeline):负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。(6)下载器中间件(DownloaderMiddlewares):位于Scrapy引擎和下载器之间的框架,主要处理Scrapy引擎与下载器之间的请求及响应。(7)爬虫中间件(SpiderMiddlewares):介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。(8)调度中间件(SchedulerMiddewares):介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。8.2爬虫2

爬虫框架

Scrapy运行流程如下:首先,引擎从调度器中取出一个链接(URL)用于接下来的抓取,引擎把URL封装成一个请求(Request)传给下载器,下载器把资源下载下来,并封装成应答包(Response)。然后,爬虫解析Response,若是解析出实体(Item),则交给实体管道进行进一步的处理。若解析出的是链接(URL),则把URL交给Scheduler等待抓取。Scrapy整体架构如图8.8所示。8.2爬虫2

爬虫框架

2.PySpider

PySpider是Binux做的一个爬虫架构的开源化实现,主要的功能需求如下:(1)抓取、更新调度多站点的特定的页面。(2)需要对页面进行结构化信息提取。(3)灵活可扩展,稳定可监控。还有一些不常使用的爬虫框架,如Portia(基于Scrapy的可视化爬虫)、Restkit(Python的HTTP资源工具包,可以让用户轻松地访问HTTP资源,并围绕它建立的对象)、Demiurge(基于PyQuery的爬虫微框架)。8.2爬虫3

通过URL浏览网页

URL,即统一资源定位符,也就是所谓的网址。URL的格式由以下3部分组成:(1)第一部分是协议或称为服务方式。(2)第二部分是存有该资源的主机IP地址或域名(有时也包括端口号)。(3)第三部分是主机资源的具体地址,如目录和文件名等。8.2爬虫3

通过URL浏览网页

例如,该项目中爬取163新闻内容,则需要http://3/touch/all?dataversion=A&uversion=A&version=v_standard这个目标URL,其中“http”表示协议;“3”为存有该资源的域名,该域名对应一个主机的IP地址;“touch/all?dataversion=A&uversion=A&version=v_standard”则对应主机资源的具体地址。用户看到的网页实质是由HTML代码构成的,使用爬虫工具就可以爬取这些内容,通过分析和过滤这些HTML代码,实现对图片、文字等资源的获取。8.2爬虫4

urllib模块

在Python3.x中,有urllib和urllib3两个库,最常用的是urllib模块,而urllib3则作为一个拓展模块使用。使用urllib库获取某一个地址对应的网页内容,通过调用urllib.request中的urlopen方法向服务器发起请求,最终获取服务器返回的网页内容。其语法如下:importurllib.request#导入urllib模块response=urllib.request.urlopen(url,data,timeout)#返回一个Response对象第一个参数url为访问的URL;第二个参数data为可选的参数,默认为空,是访问URL时要传送的数据;第三个参数timeout是设置的超时时间,为可选参数,默认为socket._GLOBAL_DEFAULT_TIMEOUT。8.2爬虫4

urllib模块

【示例8.1】获取网址http://3/touch/all?dataversion=A&uversion=A&version=v_standard上的内容。importurllib.request#导入urllib2模块url="http://3/touch/all?dataversion=A&uversion=A&version=v_standard"response=urllib.request.urlopen(url)#获取URL地址对应的网页内容print(response.read())#输出返回的网页内容8.2爬虫4

urllib模块

获取网址内容的运行结果如图8.9所示。8.2爬虫4

urllib模块

在示例8.1的urlopen方法中,参数可以传入一个Request请求对象,它是一个Request类的实例,构造时需要传入URL、data等内容。改写示例8.1,详细代码见示例8.2。【示例8.2】#coding:UTF-8importurllib2#导入urllib2模块url="http://3/touch/all?dataversion=A&uversion=A&version=v_standard"request=urllib2.Request(url)response=urllib2.urlopen(request)#获取URL地址对应的网页内容printresponse.read()#输出返回的网页内容8.2爬虫5

POST方式和GET方式

数据传送分为POST和GET两种方式

两者最重要的区别是GET方式是直接以链接形式访问的,链接中包含了所有的参数,如果在参数中包含了密码,密码将在地址栏中显示,有可能导致密码的泄露,不过可以直观地看到提交到网站服务器的参数。POST则不会在地址栏上显示所有的参数。8.2爬虫5

POST方式和GET方式

使用POST方式登录CSDN网站。importurllib.requestimporturllib.parsevalues={"username":"9*******0@","password":"jq*******21"}#请使用已注册成功的账号和密码data=urllib.parse.urlencode(values).encode(encoding='UTF8')#将键值对以连接符&划分url="/login"request=urllib.request.Request(url,data)#创建Request请求对象response=urllib.request.urlopen(request)print(response.read())1.POST方式8.2爬虫5

POST方式和GET方式

使用POST方式登录CSDN网站,运行结果如图所示。8.2爬虫5

POST方式和GET方式

【示例8.4】使用GET方式请求网页数据。importurllib.requestimporturllib.parsevalues={"username":"9*******0@","password":"jq*******21"}data=str(urllib.parse.urlencode(values).encode(encoding='UTF8'))url="/login"geturl=url+"?"+dataprint("Get访问时网址为:"+geturl)request=urllib.request.Request(geturl)#只需要传入URL,创建Request请求对象response=urllib.request.urlopen(request)print(response.read())2.GET方式8.2爬虫5

POST方式和GET方式

使用GET方式请求网页数据,运行结果如图所示。8.2爬虫5

POST方式和GET方式

有些网站不会同意程序直接使用上述的方式进行访问的,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,需要设置一些Headers属性。Headers的相关属性介绍如下:(1)User-Agent:有些服务器或Proxy会通过该值来判断是否是浏览器发出的请求。(2)Content-Type:在使用rest接口时,服务器会检查该值,用来确定HTTPBody中的内容该怎样解析。(3)application/xml:返回XML格式的数据时设置,如RESTful/SOAP调用时使用。(4)application/json:返回JSON格式的数据时设置。(5)application/x-www-form-urlencoded:浏览器提交Web表单时使用3.Headers属性8.2爬虫5

POST方式和GET方式

【示例8.5】设置Headers中的agent和referer属性。importurllib.requestimporturllib.parseurl='/login'values={'username':'cqc','password':'XXXX'}#服务器会识别headers中的referer是不是它自己headers={'User-Agent':'Mozilla/4.0(compatible;MSIE5.5;WindowsNT)',

'Referer':'/account/login'}data=urllib.parse.urlencode(values).encode(encoding='UTF8')request=urllib.request.Request(url,data,headers)response=urllib.request.urlopen(request)page=response.read()print(page)运行结果与示例8.4的结果相同。8.2爬虫5

POST方式和GET方式

【示例8.6】通过代码设置访问的代理服务器。importurllib.request#:8080为代理服务器的地址proxy_handler=urllib.request.ProxyHandler({"http":':8080'})opener=urllib.request.build_opener(proxy_handler)urllib.request.install_opener(opener)该示例仅设置代理服务器,因此没有输出结果。4.访问代理服务器8.2爬虫需求说明:5

学生实践练习

使用POST方式获取QQ邮箱登录后的信息,网址为/cgi_x0002_bin/loginpage。需要添加请求的身份agent属性。

使用GET方式获取QQ邮箱登录后的信息,网址为/cgi_x0002_bin/loginpage。需要添加请求的身份agent属性。实现思路:(1)定义一个函数getPageContent(),函数根据请求对象获取网页内容。(2)定义一个函数getPostRequest(),获取POST方式的请求对象。(3)定义一个函数getGetRequest(),获取GET方式的请求对象。(4)提示选择请求方式,根据选择类型获取网页的内容。知识架构8.3正则表达式1正则表达式介绍2语法规则3Re模块4学生实践练习8.3正则表达式1

正则表达式介绍

Python中的正则表达式和Java语言基本一致,在支持语法的数量上稍有不同。它是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式的处理流程如图8.14所示。

正则表达式的大致匹配过程是依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符,则匹配失败。8.3正则表达式2

语法规则

正则表达式通常用于在文本中查找匹配的字符串。贪婪模式总是尝试匹配尽可能多的字符;非贪婪模式则相反,总是尝试匹配尽可能少的字符。Python中数量词默认是贪婪的。例如,正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。8.3正则表达式2

语法规则

正则表达式的字符和语法见表8.2。8.3正则表达式2

语法规则

正则表达式特殊序列见表8.3。与大多数编程语言相同,正则表达式中使用“\”作为转义字符8.3正则表达式3

Re模块

Python通过Re模块提供对正则表达式的支持。使用Re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果,最后使用Match实例获得信息,进行其他的操作。

Re模块提供了compile(strPattern[,flag])函数,用于将字符串形式的正则表达式编译Pattern对象,该函数有两个参数,第一个为正则表达式,第二个参数flag用于设置匹配模式,取值可以使用按位或运算符'|'表示同时生效,如“re.I|re.M”8.3正则表达式3

Re模块

可以在regex字符串中指定模式,如pile('pattern',re.I|re.M)与pile('(?im)pattern')是等价的。其可选值如下:(1)re.I(re.IGNORECASE):忽略大小写(括号内是完整写法,下同)。(2)M(MULTILINE):多行模式,改变'^'和'$'的行为。(3)S(DOTALL):任意匹配模式,改变'.'的行为。(4)L(LOCALE):预定字符类\w\W\b\B\s\S,取决于当前区域设定。(5)U(UNICODE):预定字符类\w\W\b\B\s\S\d\D,取决于unicode定义的字符属性。(6)X(VERBOSE):详细模式。在这个模式下,正则表达式可以是多行的,忽略空白字符,并可以加入注释。8.3正则表达式3

Re模块

【示例8.7】使用正则表达式的两种方式示例。importre#第一种方式#将正则表达式编译成Pattern对象,Re.I表示忽略大小写pattern=pile(r'hello',re.I)#使用Pattern匹配文本,获得匹配结果,无法匹配时将返回Nonematch=pattern.match('helloworld!')ifmatch:#使用Match获得分组信息print(match.group())#第二种简写的方式m=re.match(r'hello','helloworld!',re.I)print(m.group())#使用Match获得分组信息8.3正则表达式3

Re模块

使用正则表达式两种方式的运行结果如图8.15所示。

由示例8.7分析可知,两种方式的结果一致,其中match()函数返回的Match对象是一次匹配的结果,包含了许多关于此次匹配的信息,可以使用Match提供的可读属性或方法来获取这些信息。8.3正则表达式3

Re模块

1.Match对象Match对象的属性介绍如下:(1)string:匹配时使用的文本。(2)re:匹配时使用的Pattern对象。(3)pos:文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。(4)endpos:文本中正则表达式结束搜索的索引。值与Pattern.match()方法和Pattern.seach()方法的同名参数相同。(5)lastindex:最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,其值将为None。(6)lastgroup:最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,其值将为None。8.3正则表达式3

Re模块

Match对象的方法介绍如下:(1)group([group1,…]):获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号,也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组则返回None;截获了多次的组则返回最后一次截获的子串。(2)groups([default]):以元组形式返回全部分组截获的字符串。(3)groupdict([default]):返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。(4)start([group]):返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。(5)end([group]):返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。(6)span([group]):返回(start(group),end(group))。(7)expand(template):将匹配到的分组代入template中然后返回。8.3正则表达式3

Re模块

【示例8.8】使用Match对象中的属性和方法。importre#(?P<sign>.*)表示分组,除了原有的编号外再指定sign为别名m=re.match(r'(\w+)(\w+)(?P<sign>.*)','helloworld!')print("匹配时使用的文本:",m.string)print("匹配时使用的Pattern对象:",m.re)print("文本中正则表达式开始搜索的索引:",m.pos)print("文本中正则表达式结束搜索的索引:",m.endpos)print("最后一个被捕获的分组在文本中的索引:",m.lastindex)print("最后一个被捕获的分组的别名:",m.lastgroup)print("截获1到2位的分组的字符串:",m.group(1,2))print("以元组形式返回全部分组截获的字符串:",m.groups())print("别名的组的别名为键、以该组截获的子串为值的字典:",m.groupdict())print("第2组截获的子串在string中的起始索引:",m.start(2))print("第2组截获的子串在string中的结束索引:",m.end(2))print("第2组截获的子串在string中的起始和结束索引:",m.span(2))print(r"匹配到的分组代入r'\2\1\3'中然后返回的值为:",m.expand(r'\2\1\3'))8.3正则表达式3

Re模块

Match对象中的属性和方法的使用的运行结果如图8.16所示。8.3正则表达式3

Re模块

2.Pattern对象

Pattern对象是一个编译好的正则表达式,通过Pattern提供的一系列方法可以对文本进行匹配查找。Pattern不能直接实例化,必须使用pile()进行构造。Pattern提供了几个可读属性用于获取表达式的相关信息。(1)pattern:编译时用的表达式字符串。(2)flags:编译时用的匹配模式,数字形式。(3)groups:表达式中分组的数量。(4)groupindex:如果表达式中有拥有别名的组,该属性为一个以别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内。8.3正则表达式3

Re模块

Pattern对象中提供的方法介绍如下:(1)match(string[,pos[,endpos]])|re.match(pattern,string[,flags]):该方法将从string

的pos下标处起,尝试匹配pattern。(2)search(string[,pos[,endpos]])|re.search(pattern,string[,flags]):该方法用于查找字符串中可以匹配成功的子串。(3)split(string[,maxsplit])|re.split(pattern,string[,maxsplit]):按照能够匹配的子串将string分割后返回列表。(4)findall(string[,pos[,endpos]])|re.findall(pattern,string[,flags]):搜索string,以列表形式返回全部能匹配的子串。(5)finditer(string[,pos[,endpos]])|re.finditer(pattern,string[,flags]):搜索string,返回一个按顺序访问每一个匹配结果(Match对象)的迭代器。8.3正则表达式3

Re模块

(6)sub(repl,string[,count])|re.sub(pattern,repl,string[,count]):使用repl替换string中每一个匹配的子串后,返回替换后的字符串。使用repl时,需要注意以下两点:①当repl是一个字符串时,可以使用\id或\g<id>、\g<name>引用分组,但不能使用编号0。②当repl是一个方法时,这个方法应当只接收一个参数(Match对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。(7)count用于指定最多替换次数,不指定时则全部替换。subn(repl,string[,count])|re.sub(pattern,repl,string[,count]):返回(sub(repl,string[,count]),替换次数)。8.3正则表达式3

Re模块

【示例8.9】使用Pattern对象中的属性和方法。importre#(?P<sign>.*)表示分组,除了原有的编号,再指定sign为别名p=pile(r'(\w+)(\w+)(?P<sign>.*)',re.DOTALL)print("编译时用的表达式字符串为:",p.pattern)print("编译时用的匹配模式为:",p.flags)print("表达式中分组的数量为:",p.groups)#如果表达式中有别名,该属性为一个以别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内print("字典值为:",p.groupindex)pattern=pile(r'world')#将正则表达式编译成Pattern对象#使用search()查找匹配的子串,不存在能匹配的子串时将返回Nonematch=pattern.search('helloworld!')ifmatch:print("使用search()查找匹配的子串为:",match.group())pattern=pile(r'\d+')#按照能够匹配的子串将string分割后返回列表print("使用split()分割的列表为:",pattern.split('one1two2three3four4'))8.3正则表达式3

Re模块

pattern=pile(r'\d+')print("findall()搜索所有匹配的子串列表为:",pattern.findall('one1two2three3four4'))pattern=pile(r'\d+')forminpattern.finditer('one1two2three3four4'):print(m.group(),end='')#输出后不换行print("")pattern=pile(r'(\w+)(\w+)')s='isay,helloworld!'print(pattern.sub(r'\2\1',s))deffunc(m):returnm.group(1).title()+''+m.group(2).title()print(p.sub(func,s))print(pattern.subn(r'\2\1',s))deffunc(m):returnm.group(1).title()+''+m.group(2).title()print(p.subn(func,s))#在sub()方法的基础上增加次数8.3正则表达式3

Re模块

Pattern对象中的属性和方法的使用,运行结果如图8.17所示。8.3正则表达式4

学生实践练习

需求说明:

分析手机版网易新闻(网址为http://3)的新闻数据获取方式,使用urllib模块、正则表达式等知识获取新闻的标题和访问地址。实现思路:(1)分析手机版网易新闻的获取方式。从手机版网易新闻的“体育”栏目中的请求列表可以看出,第一个请求“https://3/touch/reconstruct/article/list/BA8E6OEOwangning/0-10.html”是用来获取新闻列表数据的。可以在该请求上右键单击,选择“Openinnewtab”选项,打开新的Tab页。请求的新闻数据如图8.18所示。8.3正则表达式4

学生实践练习

因为手机新闻网站基本都有自动加载功能,当我们将网页拖到底部时,网站会再次请求新闻列表数据,显示更多的新闻。清空原来的请求列表显示,将网页拖到底部后会显示新的请求列表。再次查找新闻列表数据的请求地址,会发现地址已经改为https://3/touch/reconstruct/article/list/BA8E6OEOwangning/10-10.html。

通过上述操作,分析可得到规律:“...0-10.html...”表示前面10条记录,“...10-10.html...”表示第二个10条记录。依次类推,并验证可以得出,“...n*10-10.html...”表示第n+1个10条记录。根据这种规律即可查询到网站的所有新闻数据。

在新闻数据中包含url字段表示新闻的地址,title字段表示新闻标题,通过爬取URL地址的内容,并通过Scrapy选择器解析,就可以获取具体的新闻内容。(2)定义getPageContent()函数,根据URL获取网页的内容。获取到网页内容后,使用正则表达式获取新闻列表对应的JSON字符串。(3)将JSON字符串转换成列表,循环遍历列表中的记录,输出新闻标题和地址。知识架构8.4分词1分词概述2常用分词库3结巴分词4学生实践练习8.4分词1

分词概述

分词的基本概述详见以下4点。1.引言自然语言处理一直都是比较热门的领域,在搜索和新闻推荐等应用上都需要和自然语言打交道,而中文的自然语言处理的第一步就是分词,所以中文分词一直扮演着举足轻重的角色。2.中文分词技术现有的分词算法可分为3大类:基于字符串匹配的分词方法:这种分词方法又称为机械分词方法,它按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功(识别出一个词);基于理解的分词方法:这种分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果;基于统计的分词方法:从形式上看,词是稳定的字的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。8.4分词1

分词概述

3.分词难题中文是一种十分复杂的语言,让计算机理解中文含义更是困难。在中文分词过程中,有两大难题一直没有完全突破。(1)歧义识别:歧义是指同样的一句话,可能有两种或者更多的切分方法。例如,“表面的”,因为“表面”和“面的”都是词,那么这个短语就可以分成“表面,的”和“表,面的”,这种称为交叉歧义。(2)新词识别:新词,专业术语称为未登录词,即那些在字典中都没有收录过,但又确实能称为词的那些词。4.分词在系统中的使用在热词分析平台中,想要从新闻数据中获取最热门的词汇,需要对每条新闻记录的内容进行分词处理,先获取新闻内容中出现的关键字,然后使用分词统计这些关键字出现的次数。所以分词是热词分析平台中很关键的一个环节。8.4分词2

常用分词库

1.结巴(jieba)分词

在Python编程领域,jieba分词解决了一直缺少高准确率、高效率的分词组件的问题,现阶段关注度高,实际生产实践中遇到的问题能够在社区反馈并得到解决,适合长期使用。jieba分词功能丰富,不仅仅只有分词这一个功能,它还是一个开源框架,提供了很多在分词之上的算法,如关键词提取、词性标注等,并提供多种编程语言实现,官方提供了Python、C++、Go、R、iOS等多平台多语言支持,同时支持多个热门项目的扩展插件,如ElasticSearch、solr、lucene等。因此,在实际项目中,进行扩展十分容易,使用简单。jieba分词官网地址是/fxsjy/jieba,它的安装与中科院分词类似,可以使用“pipinstalljieba”命令安装,也可以使用PyCharm安装。8.4分词2

常用分词库

jieba提供了以下3种分词模式:(1)精确模式:试图将句子最精确地切开,适合文本分析。(2)全模式:把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解决歧义。(3)搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。8.4分词2

常用分词库

jieba组件cut()方法作为分词接口,语法如下:jieba.cut(str,cut_all)str:表示需要分词的字符串,可以是gbk、utf-8或者unicode格式。cut_all:用来控制分词模式,有True和False两种取值:True表示全模式,False表示精确模式。不写该参数时,表示的是默认模式,该模式的效果同精确模式。

jieba.cut返回的结构是一个可迭代的generator,可以使用for循环来获得分词后得到的每一个词语(unicode),也可以用list(jieba.cut(...))转化为list。8.4分词2

常用分词库

例如,使用全模式搜索分词,代码如下:importjiebasent="中文分词是文本处理不可或缺的一步!"seg_list=jieba.cut(sent)print"默认模式:","/".join(seg_list)seg_list=jieba.cut(sent,cut_all=False)print"精确模式:","/".join(seg_list)seg_list=jieba.cut(sent,cut_all=True)print"全模式:","/".join(seg_list)seg_list=jieba.cut_for_search(sent)print"搜索引擎模式","/".join(seg_list)8.4分词2

常用分词库

使用cut()方法进行结巴分词的运行结果如图8.20所示。8.4分词2

常用分词库

2.中国科学院分词库

中国科学院针对分词公开了源代码软件ICTCLAS(InstituteofComputingTechnology,ChineseLexicalAnalysisSystem)。该系统分词正确率高达97.58%(973专家组评测结果),未登录词识别召回率均高于90%,其中中国人名的识别召回率接近98%,处理速度为31.5Kbps。

ICTCLAS的特色在于可以根据需要输出多个高概率结果,有多种输出格式,支持北大词性标注集,973专家组给出的词性标注集合。该系统得到了专家的好评,并在国内外发表了多篇论文。

ICTCLAS的功能有中文分词、词性标注及未登录词识别。中文分词,即输入“我是中国人。”,得到的处理结果为“我/是/中国/人/。/”。词性标注,即对每个切分开的词进行词性说明,支持北大词性标注集,如上例可得到结果为“我/r是/v中国/n人/n。/w”。未登录词识别即解决新词识别问题。分词模块还可以根据需要,输出多个高概率结果。8.4分词2

常用分词库

3.smallseg

该分词库为一个开源的分词项目,是基于DFA的轻量级的中文分词工具包。(1)特点:可自定义词典、切割后返回登录词列表和未登录词列表,有一定的新词识别能力。(2)使用:需要安装和配置smallseg库。8.4分词2

常用分词库

4.snailseg

snailseg是一个使用Python编写的简单的中文分词库,也是基于单字位置最大概率的Python分词工具。其算法是统计单字在词语中出现位置的概率大小,选择最大可能的分词方案。其算法很简单,只有100行纯Python代码。测试环境为“Intel(R)Core(TM)i7-2600CPU@3.4GHz;”的机器配置下测试“围城.txt”可以达到700Kbps。8.4分词2

常用分词库

四款Python中文分词系统简单测试后的测试结果,详情见表8.4。8.4分词3

结巴分词

1.结巴分词的安装

使用结巴(jieba)分词需要安装第三方库jieba。jieba的安装与其他第三方库的安装类似,可以通过PyCharm工具和使用“pipinstalljieba”命令两种方式安装。1)使用PyCharm工具安装(1)在PyCharm开发工具中依次单击“File”→“Settings”菜单,打开设置界面,如图8.21所示8.4分词3

结巴分词

(2)单击“+”按钮后,在搜索框中搜索“jieba”,出现搜索结果后选择“jieba”,再单击“InstallPackage”按钮安装jieba库,安装完将出现如图8.22所示的提示信息。8.4分词3

结巴分词

2)使用“pipinstalljieba”命令安装在Windows中搜索“cmd”,打开命令行工具,执行“pipinstalljieba”命令,如图8.23所示。8.4分词3

结巴分词

2.结巴分词的使用1)关键词提取

关键词提取是结巴分词分析文本的重要功能,关键词一般是指文档中出现频率较高且非无用的词语,其一定程度上代表了文档的焦点所在。针对单篇文档,可以作为高频词来看;对于如新闻这样的多篇文档,可以将其作为热词,发现舆论焦点。关键词提取是自然语言处理中的TF(TermFrequency)策略,其主要有以下干扰项:(1)标点符号:一般标点符号无任何价值,需要去除。(2)停用词:诸如“的”“是”“了”等常用词无任何意义,也需要剔除。8.4分词3

结巴分词

【示例8.10】统计绕口令“扁担长,板凳宽……”(句子太长,省略,具体见代码)的关键字。importjiebacontent="扁担长,板凳宽,板凳没有扁担长,扁担没有板凳宽。扁担要绑在板凳上,板凳不让扁担绑在板凳上,扁担偏要扁担绑在板凳上。"con_list=list(jieba.cut(content))print('文本内容:',content)print('样本分词效果:','/'.join(con_list))#统计文中每个分词出现的次数tf_dic={}forwincon_list:tf_dic[w]=tf_dic.get(w,0)+1#统计出现次数最多的五个关键字keywords=sorted(tf_dic.items(),key=lambdax:x[1],reverse=True)[:5]print('样本的topK(5)词:',str(keywords))8.4分词3

结巴分词

统计文本的关键字的运行结果如图8.24所示。8.4分词3

结巴分词

2)添加自定义词典

结巴分词还有一个方便的地方是开发者可以自定义词典,以便包含词库中没有的词,虽然结巴jieba分词有新词识别能力,但是自行添加新词可以保证更高的正确率。在命令“jieba.load_userdict(filename)”中,“filename”为自定义词典的路径。在使用的时候,词典的格式和jieba分词本身的分词器中的词典格式必须保持一致,一个词占一行,每一行分成三部分,一部分为词语,一部分为词频,最后为词性(可以省略),用空格隔开。8.4分词3

结巴分词

例如,在项目中新建“userdict.txt”,编写添加的词典内容,内容如下:黑化肥1n灰化肥1n发黑4v发灰4v不5adv8.4分词3

结巴分词

现对比使用自定义字典和不使用自定义字典的结果区别,输出“黑化肥发灰,灰化肥发黑。黑化肥发黑不发灰,灰化肥发灰不发黑。”这句话的分词结果,见示例8.11。importjiebacontent="黑化肥发灰,灰化肥发黑。黑化肥发黑不发灰,灰化肥发灰不发黑。"con_list=list(jieba.cut(content))print('文本内容:',content)print('默认的分词效果:','/'.join(con_list))#使用自定义字典jieba.load_userdict("userdict.txt")con_list=list(jieba.cut(content))print('自定义字典效果:','/'.join(con_list))8.4分词3

结巴分词

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论