《Python程序設計基礎》 課件第8章 實戰(zhàn)項目之爬蟲和分詞·_第1頁
《Python程序設計基礎》 課件第8章 實戰(zhàn)項目之爬蟲和分詞·_第2頁
《Python程序設計基礎》 課件第8章 實戰(zhàn)項目之爬蟲和分詞·_第3頁
《Python程序設計基礎》 課件第8章 實戰(zhàn)項目之爬蟲和分詞·_第4頁
《Python程序設計基礎》 課件第8章 實戰(zhàn)項目之爬蟲和分詞·_第5頁
已閱讀5頁,還剩90頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第八章實戰(zhàn)項目之爬蟲和分詞項目需求爬蟲正則表達式分詞思維導圖學習目標掌握掌握掌握了解爬蟲的概念和基本工作原理12掌握爬蟲常用模塊和函數的使用了解分詞的概念和常用的分詞庫

4基本掌握正則表達的概念和語法

3技能目標掌握掌握掌握學會爬蟲的基本編程應用12學會分詞的基本編程應用進一步提升Python綜合編程應用能力3思政目標1.學以致用,行以致遠。要把研究和解決現實問題作為學習的根本出發(fā)點。2.“師夷長技以制夷”,從中國制造到中國創(chuàng)造是中國IT產業(yè)的必由之路。3.通過“核高基—從‘中國制造’到‘中國創(chuàng)造’的戰(zhàn)略決策”的學習,了解擁有屬于我國的真正安全、可靠、可控的基礎軟件是一代代IT人接續(xù)奮斗的目標。目錄爬蟲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

熱詞分析平臺

然后,將統(tǒng)計出來的前20個關鍵字用圖表展示出來,處理完成后,折線圖和柱狀圖如圖8.2所示。8.1項目需求2

數據庫設計

熱點關注項目使用MySQL數據庫保存數據。在該項目中,分析后的關鍵字在內存中存儲即可,因此只需要創(chuàng)建一張新聞news表。新聞表的表結構見表8.1。8.1項目需求3

網頁內容分析

想要抓取到數據,就必須知道有哪些途徑獲取數據源。目前數據源獲取有3種途徑:(1)PC端網站。內容比較繁雜,所以分析最復雜,作為最后考慮的途徑。(2)針對移動設備設計的網站。大部分新聞平臺都提供了針對移動設備設計的網站,如網易新聞除了PC端提供的新聞網址(/),還提供了針對移動設備的新聞網址(http://3)。內容相對簡單,分析比較容易。(3)移動App。優(yōu)先考慮的途徑,一般使用Charles工具進行分析,有些App會加密,此時可以進行反編譯分析,逆推出加密方法。8.1項目需求3

網頁內容分析

通過什么辦法可以爬取到網頁中的所有新聞數據呢?一般情況,可以使用以下3種方式來分析:(1)分析網頁源代碼。(2)查看網頁的訪問地址。(3)借助瀏覽器提供的開發(fā)者工具來分析。當需要獲取有用數據的請求地址時,在Chrome瀏覽器中按Ctrl+Shift+I組合鍵,即可彈出瀏覽器的開發(fā)者工具。單擊開發(fā)者工具的“Network”菜單,查看每次訪問的所有網絡請求,如圖所示。8.1項目需求4

手機版網頁新聞的獲取

!

本小節(jié)將以手機版搜狐新聞(/ch/8)的爬取為例進行講解。每次將網頁拖到底部,網站都會自動加載更多的新聞。但訪問的地址沒有改變,因此我們可以肯定搜狐新聞網站是通過異步請求加載新聞數據的。對于實現了自動加載功能的手機端新聞網站,基本使用異步請求。8.1項目需求4手機版網頁新聞的獲取獲取手機版搜狐數據步驟如下:(1)在Chrome瀏覽器中打開/ch/8網址,如圖8.4所示,使用Ctrl+Shift+I組合鍵打開開發(fā)者工具,或者單擊菜單中的“更多工具”→“開發(fā)者工具”,清空當前的請求列表。8.1項目需求4

手機版網頁新聞的獲取

(2)將網頁拖到底部,網頁將自動加載新聞數據。在請求列表中可以發(fā)現,以.webp結尾的請求都是圖片的請求地址。忽略圖片請求后,在請求列表中查找請求新聞數據的鏈接。每個鏈接的右鍵菜單都提供了復制鏈接的地址功能,可以發(fā)現新聞數據的請求地址如下:/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)通過兩次請求的地址對比,可以發(fā)現請求參數中page表示第幾頁,第一頁是page=1,依次類推。根據這個規(guī)律我們就可以獲取到該網站的所有新聞數據。例如,訪問page=2的新聞數據請求地址后顯示的網頁內容如圖8.5所示。8.1項目需求4

手機版網頁新聞的獲取

(4)從請求的新聞列表數據格式可以看出,頁面數據是一個標準的JSON字符串。通過對JSON字符串的解析,可以獲取一條一條的新聞數據。(5)將新聞數據中的內容和新聞實際的訪問地址進行對比,例如,其中一條新聞的數據如下:{"brief":"但中美兩國正式建立外交關系不久…,"images":["http://5b0988e595225….jpeg"],"cmsId":0,"mobileTitle":"要中國還1萬億美元清朝債…","mobilePersonalPage":"/media/114988","type":2,"authorId":114988,"authorPic":"http://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數據庫中創(chuàng)建數據庫NewsDB和新聞表news表,news表結構見表8.1。2.實現思路(1)可以在Windows系統(tǒng)中搜索MySQL。找到“MySQLCommandLineClient”命令行客戶端工具。輸入密碼后通過命令創(chuàng)建MySQL數據庫,也可以使用NavicatMySQL工具創(chuàng)建。(2)創(chuàng)建數據庫NewsDB和新聞表news表。5

學生實踐練習

知識架構8.2爬蟲1爬蟲介紹2爬蟲框架3通過URL瀏覽網頁4urllib模塊5POST方式和GET方式6學生實踐練習8.2爬蟲1

爬蟲介紹

網絡爬蟲(又被稱為網頁蜘蛛、網絡機器人)是一種按照一定的規(guī)則,自動地抓取萬維網信息的程序或者腳本,抓取想要的內容或程序。網絡爬蟲是一個自動提取網頁的程序,它從萬維網上下載網頁,是搜索引擎的重要組成部分。傳統(tǒng)爬蟲從一個或若干初始網頁的URL開始,獲得初始網頁上的URL,在抓取網頁的過程中,不斷從當前頁面上抽取新的URL放入隊列,直到滿足系統(tǒng)的停止條件。聚焦爬蟲的工作流程較為復雜,需要對網頁進行分析,通過算法過濾與主題無關的鏈接,保留有用的鏈接并將其放入等待抓取的URL隊列。然后,它將根據一定的搜索策略從隊列中選擇下一步要抓取的網頁URL,并重復上述過程,當滿足系統(tǒng)的某一條件時停止。另外,所有被爬蟲抓取的網頁將會被系統(tǒng)存儲,進行一定的分析、過濾,并建立索引,以便之后的查詢和檢索;對于聚焦爬蟲而言,這一過程所得到的分析結果可能對以后的抓取過程給出反饋和指導。在該項目中,爬蟲用來獲取163新聞網站(網址為http://3)上的所有新聞記錄。首先要獲取該網站上所有的新聞鏈接地址,然后通過訪問新聞的鏈接地址獲取新聞的內容。8.2爬蟲2

爬蟲框架

目前比較優(yōu)秀并且比較齊全的爬蟲框架有Scrapy、PySpider、Grab和Cola。下面我們將分別介紹這幾種框架。1.ScrapyScrapy是一個為了爬取網站數據、提取結構性數據而編寫的應用框架,可以應用在包括數據挖掘、信息處理或存儲歷史數據等一系列的程序中,也可以應用在獲取API所返回的數據(如AmazonAssociatesWebServices)或者通用的網絡爬蟲。Scrapy用途廣泛,可以用于數據挖掘、監(jiān)測和自動化測試。Scrapy使用了Twisted異步網絡數據庫來處理網絡通信。8.2爬蟲2

爬蟲框架Scrapy的主要組件如下:(1)引擎(Scrapy):用來處理整個系統(tǒng)的數據流,觸發(fā)事務(框架核心)。(2)調度器(Scheduler):用來接收引擎發(fā)過來的請求,壓入隊列中,并在引擎再次請求時返回,可以將它想象成一個URL(抓取網頁的網址或者說是鏈接)的優(yōu)先隊列,由它來決定下一個要抓取的網址是什么,同時去除重復的網址。(3)下載器(Downloader):用于下載網頁內容,并將網頁內容返回給蜘蛛(Scrapy下載器是建立在Twisted這個高效的異步模型上的)。(4)爬蟲(Spiders):用于從特定的網頁中提取自己需要的信息,即所謂的實體(Item)。用戶也可以從中提取出鏈接,讓Scrapy繼續(xù)抓取下一個頁面。8.2爬蟲2

爬蟲框架(5)項目管道(Pipeline):負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證實體的有效性、清除不需要的信息。當頁面被爬蟲解析后,將被發(fā)送到項目管道,并經過幾個特定的次序處理數據。(6)下載器中間件(DownloaderMiddlewares):位于Scrapy引擎和下載器之間的框架,主要處理Scrapy引擎與下載器之間的請求及響應。(7)爬蟲中間件(SpiderMiddlewares):介于Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應輸入和請求輸出。(8)調度中間件(SchedulerMiddewares):介于Scrapy引擎和調度之間的中間件,從Scrapy引擎發(fā)送到調度的請求和響應。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)靈活可擴展,穩(wěn)定可監(jiān)控。還有一些不常使用的爬蟲框架,如Portia(基于Scrapy的可視化爬蟲)、Restkit(Python的HTTP資源工具包,可以讓用戶輕松地訪問HTTP資源,并圍繞它建立的對象)、Demiurge(基于PyQuery的爬蟲微框架)。8.2爬蟲3

通過URL瀏覽網頁

URL,即統(tǒng)一資源定位符,也就是所謂的網址。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方法向服務器發(fā)起請求,最終獲取服務器返回的網頁內容。其語法如下: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兩種方式

兩者最重要的區(qū)別是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)#創(chuàng)建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,創(chuàng)建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會通過該值來判斷是否是瀏覽器發(fā)出的請求。(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語法規(guī)則3Re模塊4學生實踐練習8.3正則表達式1

正則表達式介紹

Python中的正則表達式和Java語言基本一致,在支持語法的數量上稍有不同。它是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符及這些特定字符的組合,組成一個“規(guī)則字符串”,這個“規(guī)則字符串”用來表達對字符串的一種過濾邏輯。正則表達式的處理流程如圖8.14所示。

正則表達式的大致匹配過程是依次拿出表達式和文本中的字符比較,如果每一個字符都能匹配,則匹配成功;一旦有匹配不成功的字符,則匹配失敗。8.3正則表達式2

語法規(guī)則

正則表達式通常用于在文本中查找匹配的字符串。貪婪模式總是嘗試匹配盡可能多的字符;非貪婪模式則相反,總是嘗試匹配盡可能少的字符。Python中數量詞默認是貪婪的。例如,正則表達式"ab*"如果用于查找"abbbc",將找到"abbb"。而如果使用非貪婪的數量詞"ab*?",將找到"a"。8.3正則表達式2

語法規(guī)則

正則表達式的字符和語法見表8.2。8.3正則表達式2

語法規(guī)則

正則表達式特殊序列見表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,取決于當前區(qū)域設定。(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”是用來獲取新聞列表數據的??梢栽谠撜埱笊嫌益I單擊,選擇“Openinnewtab”選項,打開新的Tab頁。請求的新聞數據如圖8.18所示。8.3正則表達式4

學生實踐練習

因為手機新聞網站基本都有自動加載功能,當我們將網頁拖到底部時,網站會再次請求新聞列表數據,顯示更多的新聞。清空原來的請求列表顯示,將網頁拖到底部后會顯示新的請求列表。再次查找新聞列表數據的請求地址,會發(fā)現地址已經改為https://3/touch/reconstruct/article/list/BA8E6OEOwangning/10-10.html。

通過上述操作,分析可得到規(guī)律:“...0-10.html...”表示前面10條記錄,“...10-10.html...”表示第二個10條記錄。依次類推,并驗證可以得出,“...n*10-10.html...”表示第n+1個10條記錄。根據這種規(guī)律即可查詢到網站的所有新聞數據。

在新聞數據中包含url字段表示新聞的地址,title字段表示新聞標題,通過爬取URL地址的內容,并通過Scrapy選擇器解析,就可以獲取具體的新聞內容。(2)定義getPageContent()函數,根據URL獲取網頁的內容。獲取到網頁內容后,使用正則表達式獲取新聞列表對應的JSON字符串。(3)將JSON字符串轉換成列表,循環(huán)遍歷列表中的記錄,輸出新聞標題和地址。知識架構8.4分詞1分詞概述2常用分詞庫3結巴分詞4學生實踐練習8.4分詞1

分詞概述

分詞的基本概述詳見以下4點。1.引言自然語言處理一直都是比較熱門的領域,在搜索和新聞推薦等應用上都需要和自然語言打交道,而中文的自然語言處理的第一步就是分詞,所以中文分詞一直扮演著舉足輕重的角色。2.中文分詞技術現有的分詞算法可分為3大類:基于字符串匹配的分詞方法:這種分詞方法又稱為機械分詞方法,它按照一定的策略將待分析的漢字串與一個“充分大的”機器詞典中的詞條進行匹配,若在詞典中找到某個字符串,則匹配成功(識別出一個詞);基于理解的分詞方法:這種分詞方法是通過讓計算機模擬人對句子的理解,達到識別詞的效果;基于統(tǒng)計的分詞方法:從形式上看,詞是穩(wěn)定的字的組合,因此在上下文中,相鄰的字同時出現的次數越多,就越有可能構成一個詞。8.4分詞1

分詞概述

3.分詞難題中文是一種十分復雜的語言,讓計算機理解中文含義更是困難。在中文分詞過程中,有兩大難題一直沒有完全突破。(1)歧義識別:歧義是指同樣的一句話,可能有兩種或者更多的切分方法。例如,“表面的”,因為“表面”和“面的”都是詞,那么這個短語就可以分成“表面,的”和“表,面的”,這種稱為交叉歧義。(2)新詞識別:新詞,專業(yè)術語稱為未登錄詞,即那些在字典中都沒有收錄過,但又確實能稱為詞的那些詞。4.分詞在系統(tǒng)中的使用在熱詞分析平臺中,想要從新聞數據中獲取最熱門的詞匯,需要對每條新聞記錄的內容進行分詞處理,先獲取新聞內容中出現的關鍵字,然后使用分詞統(tǒng)計這些關鍵字出現的次數。所以分詞是熱詞分析平臺中很關鍵的一個環(huán)節(jié)。8.4分詞2

常用分詞庫

1.結巴(jieba)分詞

在Python編程領域,jieba分詞解決了一直缺少高準確率、高效率的分詞組件的問題,現階段關注度高,實際生產實踐中遇到的問題能夠在社區(qū)反饋并得到解決,適合長期使用。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循環(huán)來獲得分詞后得到的每一個詞語(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)。該系統(tǒng)分詞正確率高達97.58%(973專家組評測結果),未登錄詞識別召回率均高于90%,其中中國人名的識別召回率接近98%,處理速度為31.5Kbps。

ICTCLAS的特色在于可以根據需要輸出多個高概率結果,有多種輸出格式,支持北大詞性標注集,973專家組給出的詞性標注集合。該系統(tǒng)得到了專家的好評,并在國內外發(fā)表了多篇論文。

ICTCLAS的功能有中文分詞、詞性標注及未登錄詞識別。中文分詞,即輸入“我是中國人。”,得到的處理結果為“我/是/中國/人/。/”。詞性標注,即對每個切分開的詞進行詞性說明,支持北大詞性標注集,如上例可得到結果為“我/r是/v中國/n人/n。/w”。未登錄詞識別即解決新詞識別問題。分詞模塊還可以根據需要,輸出多個高概率結果。8.4分詞2

常用分詞庫

3.smallseg

該分詞庫為一個開源的分詞項目,是基于DFA的輕量級的中文分詞工具包。(1)特點:可自定義詞典、切割后返回登錄詞列表和未登錄詞列表,有一定的新詞識別能力。(2)使用:需要安裝和配置smallseg庫。8.4分詞2

常用分詞庫

4.snailseg

snailseg是一個使用Python編寫的簡單的中文分詞庫,也是基于單字位置最大概率的Python分詞工具。其算法是統(tǒng)計單字在詞語中出現位置的概率大小,選擇最大可能的分詞方案。其算法很簡單,只有100行純Python代碼。測試環(huán)境為“Intel(R)Core(TM)i7-2600CPU@3.4GHz;”的機器配置下測試“圍城.txt”可以達到700Kbps。8.4分詞2

常用分詞庫

四款Python中文分詞系統(tǒng)簡單測試后的測試結果,詳情見表8.4。8.4分詞3

結巴分詞

1.結巴分詞的安裝

使用結巴(jieba)分詞需要安裝第三方庫jieba。jieba的安裝與其他第三方庫的安裝類似,可以通過PyCharm工具和使用“pipinstalljieba”命令兩種方式安裝。1)使用PyCharm工具安裝(1)在PyCharm開發(fā)工具中依次單擊“File”→“Settings”菜單,打開設置界面,如圖8.21所示8.4分詞3

結巴分詞

(2)單擊“+”按鈕后,在搜索框中搜索“jieba”,出現搜索結果后選擇“jieba”,再單擊“InstallPackage”按鈕安裝jieba庫,安裝完將出現如圖8.22所示的提示信息。8.4分詞3

結巴分詞

2)使用“pipinstalljieba”命令安裝在Windows中搜索“cmd”,打開命令行工具,執(zhí)行“pipinstalljieba”命令,如圖8.23所示。8.4分詞3

結巴分詞

2.結巴分詞的使用1)關鍵詞提取

關鍵詞提取是結巴分詞分析文本的重要功能,關鍵詞一般是指文檔中出現頻率較高且非無用的詞語,其一定程度上代表了文檔的焦點所在。針對單篇文檔,可以作為高頻詞來看;對于如新聞這樣的多篇文檔,可以將其作為熱詞,發(fā)現輿論焦點。關鍵詞提取是自然語言處理中的TF(TermFrequency)策略,其主要有以下干擾項:(1)標點符號:一般標點符號無任何價值,需要去除。(2)停用詞:諸如“的”“是”“了”等常用詞無任何意義,也需要剔除。8.4分詞3

結巴分詞

【示例8.10】統(tǒng)計繞口令“扁擔長,板凳寬……”(句子太長,省略,具體見代碼)的關鍵字。importjiebacontent="扁擔長,板凳寬,板凳沒有扁擔長,扁擔沒有板凳寬。扁擔要綁在板凳上,板凳不讓扁擔綁在板凳上,扁擔偏要扁擔綁在板凳上。"con_list=list(jieba.cut(content))print('文本內容:',content)print('樣本分詞效果:','/'.join(con_list))#統(tǒng)計文中每個分詞出現的次數tf_dic={}forwincon_list:tf_dic[w]=tf_dic.get(w,0)+1#統(tǒng)計出現次數最多的五個關鍵字keywords=sorted(tf_dic.items(),key=lambdax:x[1],reverse=True)[:5]print('樣本的topK(5)詞:',str(keywords))8.4分詞3

結巴分詞

統(tǒng)計文本的關鍵字的運行結果如圖8.24所示。8.4分詞3

結巴分詞

2)添加自定義詞典

結巴分詞還有一個方便的地方是開發(fā)者可以自定義詞典,以便包含詞庫中沒有的詞,雖然結巴jieba分詞有新詞識別能力,但是自行添加新詞可以保證更高的正確率。在命令“jieba.load_userdict(filename)”中,“filename”為自定義詞典的路徑。在使用的時候,詞典的格式和jieba分詞本身的分詞器中的詞典格式必須保持一致,一個詞占一行,每一行分成三部分,一部分為詞語,一部分為詞頻,最后為詞性(可以省略),用空格隔開。8.4分詞3

結巴分詞

例如,在項目中新建“userdict.txt”,編寫添加的詞典內容,內容如下:黑化肥1n灰化肥1n發(fā)黑4v發(fā)灰4v不5adv8.4分詞3

結巴分詞

現對比使用自定義字典和不使用自定義字典的結果區(qū)別,輸出“黑化肥發(fā)灰,灰化肥發(fā)黑。黑化肥發(fā)黑不發(fā)灰,灰化肥發(fā)灰不發(fā)黑。”這句話的分詞結果,見示例8.11。importjiebacontent="黑化肥發(fā)灰,灰化肥發(fā)黑。黑化肥發(fā)黑不發(fā)灰,灰化肥發(fā)灰不發(fā)黑。"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. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論