1. 程式人生 > 其它 >20191212斯廷響 2020-2021-2 《Python程式設計》實驗四報告

20191212斯廷響 2020-2021-2 《Python程式設計》實驗四報告

課程:《Python程式設計》
班級: 1912
姓名:斯廷響
學號:20191212
實驗教師:王志強
實驗日期:2021年6月20日
必修/選修: 公選課

1.實驗內容

Python綜合應用:爬蟲、資料處理、視覺化、機器學習、神經網路、遊戲、網路安全等。
課代表和各小組負責人收集作業(原始碼、視訊、綜合實踐報告)
批閱:注意本次實驗不算做實驗總分,前三個實驗每個實驗10分,累計30分。本次實踐算入綜合實踐,打分為25分。
評分標準:
(1)程式能執行,功能豐富。(需求提交原始碼,並建議錄製程式執行的視訊)10分
(2)綜合實踐報告,要體現實驗分析、設計、實現過程、結果等資訊,格式規範,邏輯清晰,結構合理。10分。
(3)在實踐報告中,需要對全課進行總結,並寫課程感想體會、意見和建議等。5分

2. 實驗過程

綜合應用一:網路爬蟲

瞭解什麼是爬蟲

  最後一節課上高年級學長向我們介紹了爬蟲有關原理,網路爬蟲,即Web Spider,是一個很形象的名字。把網際網路比喻成一個蜘蛛網,那麼Spider就是在網上爬來爬去的蜘蛛。網路蜘蛛是通過網頁的連結地址來尋找網頁的。從網站某一個頁面(通常是首頁)開始,讀取網頁的內容,找到在網頁中的其它連結地址,然後通過這些連結地址尋找下一個網頁,這樣一直迴圈下去,直到把這個網站所有的網頁都抓取完為止。如果把整個網際網路當成一個網站,那麼網路爬蟲就可以用這個原理把網際網路上所有的網頁都抓取下來。這樣看來,網路爬蟲就是一個爬行程式,一個抓取網頁的程式。網路爬蟲的基本操作是抓取網頁。

瞭解URI

Web上每種可用的資源,如 HTML文件、影象、視訊片段、程式等都由一個通用資源標誌符(Universal Resource Identifier, URI)進行定位。

URI通常由三部分組成:

  • 訪問資源的命名機制;
  • 存放資源的主機名;
  • 資源自身 的名稱,由路徑表示。

瞭解URL

  URL是URI的一個子集。它是Uniform Resource Locator的縮寫,譯為“統一資源定位 符”。通俗地說,URL是Internet上描述資訊資源的字串,主要用在各種WWW客戶程式和伺服器程式上。採用URL可以用一種統一的格式來描述各種資訊資源,包括檔案、伺服器的地址和目錄等。URL的一般格式為(帶方括號[]的埠號可有可無):

  protocol :// hostname[:port] / path / [;parameters][?query]#fragment

URL的格式由三部分組成:

  • 第一部分是協議(或稱為服務方式)。
  • 第二部分是存有該資源的主機IP地址(有時也包括埠號)。
  • 第三部分是主機資源的具體地址,如目錄和檔名等。

第一部分和第二部分用“://”符號隔開,第二部分和第三部分用“/”符號隔開。第一部分和第二部分是不可缺少的,第三部分有時可以省略。

URI屬於URL更低層次的抽象,一種字串文字標準。換句話說,URI屬於父類,而URL屬於URI的子類。URL是URI的一個子集。URI的定義是:統一資源識別符號;URL的定義是:統一資源定位符。二者的區別在於,URI表示請求伺服器的路徑,定義這麼一個資源。而URL同時說明要如何訪問這個資源(http://)。

爬蟲流程:

  有了一些理論基礎以後可以開始分析網路爬蟲流程,在最後一節課堂上學長向我們演示了python爬蟲的過程,主要可以概括為:發起請求、獲取響應內容、解析內容

下面就學長的講解分別作出分析:

1.發起請求:
通過HTTP庫向目標站點發起請求,即傳送一個Request,請求可以包含額外的headers、data等資訊,然後等待伺服器響應。這個請求的過程就像我們開啟瀏覽器,在瀏覽器位址列輸入網址:www.baidu.com,然後點選回車。這個過程其實就相當於瀏覽器作為一個瀏覽的客戶端,向伺服器端傳送了 一次請求。


2.獲取響應內容:
如果伺服器能正常響應,我們會得到一個Response,Response的內容便是所要獲取的內容,型別可能有HTML、Json字串,二進位制資料(圖片,視訊等)等型別。這個過程就是伺服器接收客戶端的請求,進過解析傳送給瀏覽器的網頁HTML檔案。


3.解析內容:
得到的內容可能是HTML,可以使用正則表示式,網頁解析庫進行解析。也可能是Json,可以直接轉為Json物件解析。可能是二進位制資料,可以做儲存或者進一步處理。這一步相當於瀏覽器把伺服器端的檔案獲取到本地,再進行解釋並且展現出來。

4.有些爬蟲還會將資料儲存

爬取網站實踐:

  • 初步選取[東方資訊:全球電影票房排行榜](https://mini.eastday.com/a/190505123024855.html)作為要獲取的資訊,和爬取物件。進去之後發現需要翻頁,也就是說資訊分佈在好幾個網頁上。

  • 發現,所搜結果的第n個的url 的特徵引數 就是最後一位的數字,我們嘗試令其依次等於1到n,發現東方諮詢的所搜結果,除了首頁都可以通過此url訪問,至此所有所搜結果的url可以統一成一個形式,第n頁的url = https://mini.eastday.com/a/190505123024855-n.html 至於第一頁只好作為例外採用原本的網址

  • 實現翻頁操作:改變上面url的n值即可。

  • 看一下robots協議 ,驚喜的發現沒有限制

  • 然後開始程式碼部分

    import requests
    import re
    
  • 首先定義一個函式,實現對目標網頁資訊的獲取,由於要不斷的進行翻頁,所以此函式會被不斷呼叫,進而要引入異常處理保證程式不會中途停止或退出。我們用raise_for_status 方法來主動判斷網頁資訊是否獲取成功並如果不成功則產生異常

    def getHTMLText(url):
        try:
            r = requests.get(url, timeout=30)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return ""
    
  • 再定義一個函式,對得到的網頁資訊進行解析,獲取擷取對我們來說有用的資訊。我們通過檢視網頁的原始碼,通過搜尋找到有用的資訊的欄位,然後使用正則表示式對其進行擷取

    def parsePage(ilt, html):
    
            plt = re.findall(r'全球票房:[\d\.]{2,7}',html)
            tlt = re.findall(r'第[\d]*名:《.{1,15}》',html)
      
            '''print(plt)
            print(len(plt))
            print(tlt)
            print(len(tlt))
            '''
            for i in range(len(tlt)):
                price = eval(plt[i].split(':')[1])
                title = tlt[i].split(':')[1]
                ilt.append([price , title])
    
  • 再定義一個把商品資訊輸出到螢幕上的函式

    def printGoodsList(ilt):
        tplt = "{:4}\t{:8}\t{:16}"
        print(tplt.format("序號", "票房", "電影名稱"))
        count = 0
        for g in ilt:
            count = count + 1
            print(tplt.format(count, g[0], g[1]))
    
  • 最後定義一個主函式並執行主函式。使用迴圈實現翻頁操作,屬於例外的首頁資訊先手動將其儲存進變數html中即可

    def main():  
        start_url = '''https://mini.eastday.com/a/190505123024855-''' 
        infoList = []
        url = '''https://mini.eastday.com/a/190505123024855.html?qid=02263'''
        html = getHTMLText(url)
        for i in range(2,7):
            url = start_url+str(i)+'.html'
            html += getHTMLText(url)
        parsePage(infoList, html)
        printGoodsList(infoList)
    
    main()
    

實驗結果

可見成功爬取了該網站的有用資訊。

綜合應用二:遊戲開發

  俄羅斯方塊是一款由俄羅斯人阿列克謝·帕基特諾夫於1984年6月發明的休閒遊戲。該遊戲曾經被多家公司代理過。經過多輪訴訟後,該遊戲的代理權最終被任天堂獲得。 [任天堂對於俄羅斯方塊來說意義重大,因為將它與GB搭配在一起後,獲得了巨大的成功。《俄羅斯方塊》的基本規則是移動、旋轉和擺放遊戲自動輸出的各種方塊,使之排列成完整的一行或多行並且消除得分。

設計思路:

  由小方塊組成的不同形狀的板塊陸續從螢幕上方落下來,玩家通過使用鍵盤上的↑↓←→調整板塊的位置和方向,使它們在螢幕底部拼出完整的一條或幾條。這些完整的橫條會隨即消失,給新落下來的板塊騰出空間,與此同時,玩家得到分數獎勵。沒有被消除掉的方塊不斷堆積起來,一旦堆到螢幕頂端,玩家便告輸,遊戲結束。

  所以須要設計一個用於擺放小型正方形的平面虛擬場地,其標準大小:行寬為10,列高為20,以每個小正方形為單位。一組由4個小型正方形組成的規則圖形,英文稱為Tetromino,中文通稱為方塊共有7種,分別以S、Z、L、J、I、O、T這7個字母形狀,所以要import pygame實現上述功能。

程式開發:

  程式碼比較長,已經上傳至碼雲。

演示例項:

  點選執行,出現介面:

遊戲執行過程:

  1.開始遊戲

  2.進行操作

3.消除一行

4.遊戲結束

完整視訊已額外發送。

3. 實驗過程中遇到的問題和解決過程

  • 問題1:不會翻頁操作,如果資訊只是分佈在一個網頁上,還會處理,如果分佈在多個網頁上就不會了
  • 問題1解決方案:百度了下,通過學習別人的經驗並仔細觀察各個頁面之間的url的區別與聯絡,發現同一個系列的網頁的url通常不會是完全不一樣的,大多情況下存在著或多或少的聯絡,即url之間是相似的,這一系列url中很可能存在一個或幾個特徵值來進行彼此間的區分,我們只要抓住特徵值的變化規律,就能通過規律建構函式,進而通過迴圈實現這一系列網站間的自動跳轉訪問、資訊爬取。
  • 問題2:網頁上的資訊拿到後不會擷取有用的資訊
  • 問題2解決方案:由於之前的雲班課裡看過有關正則表示式的課程,有點印象,所以就想著能不能應用正則表示式來解決,因為我從網頁上爬取下來的資訊也是字串的形式,如果能用正則表示式對其進行匹配,就有可能做到資訊的擷取。所以我上網搜了搜正則表示式和爬蟲,並通過仔細觀察要爬取的一系列網頁,發現有用的資訊的格式都是規範的,也就是說,可以通多多個正則表示式,實現對多種有用資訊的擷取。接下來就是重新學習和運用正則表示式了。

全課總結(感悟、思考等)

  • 現在回想,本學期的收穫還是很大的。通過一學期的學習。我依次掌握了變數賦值及其命名規則、運算子及其優先順序、基本資料型別迴圈語句、列表、元組、字典、集合及其常用功能、字串與正則表示式函式、面向物件程式設計、檔案操作及異常處理、Python操作資料庫、Python網路程式設計及爬蟲開發(Socket)等內容,有了許多的收穫。
  • 本學期我們首先初識了python,瞭解了python的發展歷程、未來前景和優勢 。超級語言是指粘性整合已有程式,具有龐大的計算生態,可以很容易利用已有程式碼的功能,程式設計思維不再是刀耕火種而是整合開發,不重複製造輪子,python是目前唯一的超級語言,其前進的步伐不可阻擋。
  • 接著在學習了輸入輸出後,我們學習了基本資料型別:整數型別,四種進製表示形式、浮點型別,浮點數間運算存在不確定的尾數,不是bug,例如:0.1+0.2=0.3000000004,原因:二進位制與十進位制不是嚴格的對等關係,python用53位二進位制表示小數,是無限接近而不是完全對等。0.1+0.2==0.3,輸出false,科學計數法表示,使用e或E作為冪的符號,底為10 複數型別,只有python語言提供了複數型別,Z == 1.23e-4+5.6e+89j 字母j表示虛數單位,Z.real 獲取實部 z代表某一資料,Z.imag 獲取虛部
  • 字串型別,單引號,雙引號,都只能表示一行字串,三單引號,形成的是多行字串,但也可以當多行註釋來使用。正向遞增序號、反向遞減序號,索引和切片[ : ],字串的操作符,字串處理函式,字串處理”方法”字串型別格式化等等。
  • 接著我們學習了python的分支語句(分支結構)if elif else 和迴圈語句(迴圈結構)while for continue break,
  • 接著我們學習了組合資料型別 首先是列表組合資料型別—序列。序列基本處理方法,六個操作符:(1)X in s(2)X not in s(3)S + t(4)S * n(5)S[ ](6)S [ : : ] 5個函式或方法(1)Len( )返回長度(2)Min(s)返回最小元素,前提是:這組資料中的所有元素可以比較大小
    (3)Max(s)返回最大元素(4)S.index( x, (i,j) ) 找到x(從i,到,j)第一次出現的位置(5)S.count(x) 元組型別 特點:元組一旦被建立,就不能被修改應用場景:保護資料 列表型別 特殊操作:(1)Ls [ i ] = x :賦值(2)Ls [i :j :k]= lt :對切片賦值(3)Del ls[i] :刪除(4)Del ls[i: j: k] :刪除切片(5)Ls.insert(i,x):在i處插入x(6)Ls.pop(i):取出i位置的元素(7)Ls .remove(x):只刪除第一個x(8)Ls.revers() :反轉列表(9)Ls.sort():從小到大排序(10)Ls.sort(reverse = True):從大到小排序。
  • 之後我們又學習了集合與字典 集合間的運算 S|T 並集 S-T 減去T中元素 S&T 交集S^T 返回不同時在S、T中的元素 關係操作符 s<T 即s包含於T 集合的應用場景 包含關係的比較。即,判斷一組資料與另一組資料的關係。例如,資料a中,與資料b,有多少元素相同,不同... 最重要的應用是資料去重。只要set(A),把其他的資料型別變成集合,就實現了資料去重。字典是資料組織 與表達的一種新形態。新:使用者可以自定義 鍵值對。字典型別 真的就像建立一本字典一樣,用的時候,也真的像查字典一樣字典的建立:{ } or dict( )鍵值對 用冒號表示。鍵值對之間用逗號隔開 字典的索引 [ 鍵 ] ,操作中,鍵值對通常作為一個操作整體物件 操作中,引數一般是“鍵”,因為鍵是使用者已知的,而值一般是未知的。增加或修改 元素 dictionary[ key ] = value Del dictionary[ k ] 刪除k鍵對應的鍵值對 K in dictionary k鍵是否在字典裡 value in dictionary 是不可行的Dictionart.keys( ) 返回字典中的所有“鍵” Dictionary.values( ) 返回字典中所有“值” Dictionary.items( ) 返回字典中所有“鍵值對” 注意:返回的 dict_keys ( [ ] ) 可以做遍歷,但不能做列表型別的操作 D.get( k (,default)) 如果k鍵存在,返回對應值,如果不存在,返回引數default D.pop(k, (default)) 同上,取出k對應的值 D.popitem( ) 隨機從字典中取出一個鍵值對,並以元組形式返回 D.clear Len(d) 返回鍵值對的個數。
  • 之後我們學習了函式,def return 初步體會了程式碼複用和封裝的感覺。體驗了遞迴演算法,漢諾塔問題令人印象深刻。接著我們學習了檔案操作,一、檔案的開啟和關閉A = open(檔案路徑和名稱,開啟模式)檔案路徑。由於\是轉義符,所以路徑中的\用/替換。絕對路徑。從硬碟開始 ,例如”D:/pythonfile/三國演義.txt” 相對路徑。我理解為,當程式與檔案在同一目錄,或檔案在程式子目錄下時使用。例如 程式在D盤根目錄 “./pythonfile/三國演義.txt” 開啟模式 ‘r’ :只讀模式 ‘w’ :覆蓋寫模式。相當於先清空檔案,再向檔案中寫入。如果檔案不存在,將建立一個檔案。 ‘a’ :追加寫模式。在原檔案的後面,繼續寫入內容。如果檔案不存在將建立一個檔案。 ‘b’ :二進位制形式開啟檔案 與r,w,a, 組合 例如,wb 預設引數 ‘t’ : 以文字形式開啟檔案。 與r,w,a 組合 + :組合功能,使具備同時讀寫的能力。W+ r+ a+ ...讀檔案:a.read() a .readline() a .readlines() 寫檔案 a .write(str) a .writelines(list)a .seek(offset)a .close()
  • 之後我們介紹了面向物件程式設計 三要素:封裝、繼承、多型 介紹了物件、類,class 如果類是蓋樓的圖紙,那麼物件就是蓋好的大樓__init__()方法,建立資料成員和方法並訪問,訪問限制。接下來我們學習python的模組,Modules 模組,提高程式碼重用性和可維護性,if name == 'main':的作用,Python包以及python的異常處理,try except else finally 。接著我們學習了socket套接字,自己感受了對伺服器和客戶端的模擬,其中還有一些密碼學的知識,像國密演算法什麼的,令人心潮澎湃、印象深刻。最後就是網路爬蟲,當初真的沒想到python選修會講到網路爬蟲,雖然現在還不是很會,但我決定真的是太酷了。十分感謝老師領我並提供契機讓我初識了網路爬蟲,乃至計算機網路,web程式設計。
  • 首先我感覺王老師對我們的課程的進度安排的非常好,不僅講解了python的基本語法,還學習了python的實踐應用,讓我深刻感受到python的重大優勢就在於龐大的第三方庫。雲班課的資料也非常豐富,但也同時考慮到了同學的水平差距和時間精力問題,沒有做硬性要求,我覺得這也是很明智的。王老師上課也比較風趣幽默,課堂的內容也比較比較吸引人,我覺的這是區別的其他程式設計課程的優勢,王老師正是我們的良師益友。讓我提建議的話,很真沒什麼改革性的建議,因為已經很完備了,有一點小建議的話就是最好多給同學們回答問題的機會,讓大家積極投入討論中來。
  • 總之,經過一學期的學習,在王志強老師地帶領下,我深入學習了python課程,並且多次自己開發了實用程式。相信在未來的學習以及工作中,我會使用python語言讓自己的水平達到一個更高的高度。

碼雲連結

網路爬蟲:https://gitee.com/besti2021python/stx20191212homework/blob/master/experiment4_1

俄羅斯方塊遊戲:https://gitee.com/besti2021python/stx20191212homework/blob/master/experiment4_2

參考資料

什麼是網路爬蟲:https://www.zhihu.com/question/24098641

網路爬蟲的基本流程:https://zhuanlan.zhihu.com/p/99795269