Python爬蟲實戰一:爬取csdn學院所有課程名、價格和課時

yihan.z發表於2018-06-23
      作為第一個學習的爬蟲小程式,選取csdn學院,主要是該網站無反爬或較簡單,不需要模擬瀏覽器和代理IP,也不需要驗證和登入資訊,對於新手而言,是非常親民的;其次,需要爬取的內容都能在網頁原始碼中顯示。本篇文章使用urllib和正規表示式進行爬取。
步驟一:
     分析網站,建議使用能檢視網頁原始碼的瀏覽器分析網站,找到所有課程,價格和課時;
    價格所在位置:
 <p class="clearfix">
                        <i>
                            ¥269.10                        </i>

    課時所在位置:
<p><em>82</em>課時(<em>已更新至82</em><em>13</em>小時<em>07</em></p>

步驟二:

       編寫正規表示式,將網頁中課程名、價格和課時提取出來。   
pat1 = '<img src="(.*?)" width="179" height="120" alt="(.*?)">'
name = re.compile(pat1).findall(str(data))
name = dict(name).values() #將資料轉為字典,並將value提取出來
pat2 = '<p><em>(.*?)</em>'
class_num = re.compile(pat2).findall(str(data))
# data = data.replace('\n','').replace('\t','') #將網頁的換行符替換掉
pat3 = '<p class="clearfix">\s{1,}<i>\s{1,}(.*?)\s{1,}'
price = re.compile(pat3).findall(str(data))
for i in price:
    price[price.index(i)] = re.findall(r'-?\d+\.?\d*e?-?\d*?', i)

步驟三:
       編寫程式碼實現網頁翻頁。主要通過點選頁面的頁數,進行url的構造,本文url構造如下:
https://edu.csdn.net/courses/p+?
       觀察得到,總課程為299頁,編寫一個迴圈語句,迴圈一次,遍歷網頁一次,程式碼如下:
html = "https://edu.csdn.net/courses"
for n in range(1,299):
    url = html+'/p'+str(n)
    print(url)
    data = urllib.request.urlopen(url).read().decode('utf-8') #請求網頁,設定編碼方式為utf-8
步驟四:
       對於爬取下來的資料一般存取到資料庫和本地文件中,本文章把爬取的資料存成CSV文件儲存到本地。
       程式碼如下:
#將爬取資料存取為csv檔案,儲存在本地

def sava_data(name,class_num,price):
    #建立workbook和sheet物件
    workbook = xlwt.Workbook()
    sheet1 = workbook.add_sheet('sheet1',cell_overwrite_ok=True)

    #初始化excel樣式
    style = xlwt.XFStyle()

    #為樣式建立字型
    font = xlwt.Font()
    font.name = 'Times New Roman'
    font.bold = True

    #設定樣式的字型
    style.font = font

    #在sheet1表的第1行設定欄位名稱並寫入資料
    sheet1.write(0,0,"序號",style)
    sheet1.write(0,1,"課程名",style)
    sheet1.write(0,2,"課時",style)
    sheet1.write(0,3,"價格",style)

    a=0                                                                #定義行號初始值
    for i in xx:
        #print(str(a+1),i[0])
        sheet1.write(a+1,0,a+1,style)                                   #在第a+1行第1列寫入序號
        sheet1.write(a+1,1,name,style)                                  #在第a+1行第2列寫入課程名
        sheet1.write(a+1,2,class_num,style)                                  #在第a+1行第3列寫入課時
        sheet1.write(a+1,3,price,style)                             #在第a+1行第4列寫入課程價格
        a+=1

        if a==a:                                                        #判斷XX列表是否遍歷結束
            t=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            t1=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
            sheet1.write(a+2,1,"採集時間",style)                        #在sheet1表尾行寫入資料採集時間
            sheet1.write(a+2,2,t,style)

    workbook.save("E:/csdn學院課程彙總表"+str(t1)+".xls")                 #儲存該excel檔案,有同名檔案時無法直接覆蓋

    print("資料寫入excel檔案完畢!")
完整程式碼:
import urllib.request 
import re,xlwt,datetime

class csdn_spider():
    def __init__(self):
        self.c = 0
    def sava_data(self,name,class_num,price):
        #建立workbook和sheet物件
        workbook = xlwt.Workbook()
        sheet1 = workbook.add_sheet('sheet1',cell_overwrite_ok=True)

        #初始化excel樣式
        style = xlwt.XFStyle()

        #為樣式建立字型
        font = xlwt.Font()
        font.name = 'Times New Roman'
        font.bold = True

        #設定樣式的字型
        style.font = font

        #在sheet1表的第1行設定欄位名稱並寫入資料
        sheet1.write(0,0,"序號",style)
        sheet1.write(0,1,"課程名",style)
        sheet1.write(0,2,"課時",style)
        sheet1.write(0,3,"價格",style)

        a=0                                                                #定義行號初始值
        for i in range(0,self.c-1):
            #print(str(a+1),i[0])
            sheet1.write(a+1,0,a+1,style)                                   #在第a+1行第1列寫入序號
            sheet1.write(a+1,1,name[i],style)                                  #在第a+1行第2列寫入課程名
            sheet1.write(a+1,2,class_num[i],style)                                  #在第a+1行第3列寫入課時
            sheet1.write(a+1,3,price[i],style)                             #在第a+1行第4列寫入課程價格
            a+=1

            if a==a:                                                        #判斷XX列表是否遍歷結束
                t=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                t1=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
                sheet1.write(a+2,1,"採集時間",style)                        #在sheet1表尾行寫入資料採集時間
                sheet1.write(a+2,2,t,style)

        workbook.save("E:/csdn學院課程彙總表"+str(t1)+".xls")                 #儲存該excel檔案,有同名檔案時無法直接覆蓋

        print("資料寫入excel檔案完畢!")
    def data(self):
        html = "https://edu.csdn.net/courses"
        name = []
        class_num = []
        price = []
        for n in range(1,299):
            url = html+'/p'+str(n)
            print(url)
            data = urllib.request.urlopen(url).read().decode('utf-8') #請求網頁,設定編碼方式為utf-8
            #print(data)
            pat1 = '<img src="(.*?)" width="179" height="120" alt="(.*?)">'
            n = re.compile(pat1).findall(str(data))
            n = list(dict(n).values()) #將資料轉為字典,並將value提取出來
            name = name+n
            pat2 = '<p><em>(.*?)</em>'
            class_num += re.compile(pat2).findall(str(data))
            # data = data.replace('\n','').replace('\t','') #將網頁的換行符替換掉
            pat3 = '<p class="clearfix">\s{1,}<i>\s{1,}(.*?)\s{1,}'
            p = re.compile(pat3).findall(str(data))
            for i in p:
                p[p.index(i)] = re.findall(r'-?\d+\.?\d*e?-?\d*?', i)
            price = price+p
            print(name,class_num,price)
        self.c = len(class_num)
        print(self.c,list(name),class_num,price)    
        self.sava_data(list(name),class_num,price)
if __name__ == '__main__':
    saveinfo = csdn_spider() #呼叫類
    save_res = saveinfo.data()

     老實講,用urllib+正則執行爬蟲確實比scrapy繁瑣,且執行速度也較慢,該程式碼可以改進或多執行緒來提高執行速度,但具體怎樣小編就不一一介紹了。
       這是小編的第一篇文章,語文表達能力有限,希望能幫到你們!



相關文章