1. 程式人生 > >Python3爬蟲實戰:爬取大眾點評網某地區所有酒店相關資訊

Python3爬蟲實戰:爬取大眾點評網某地區所有酒店相關資訊

歷時一下午加一晚上,終於把這個爬蟲程式碼寫好,後面還有很多想完善的地方(譬如資料儲存用redis、使用多執行緒加快速度、爬取圖片、細分資料等等),待有空再做更改,下面是具體的步驟與思路:

工具:PyCharm、Google Chrome開發者工具、fiddle2

平臺:Python3.4

一、進入大眾點評首頁預設的地區是上海地區,所以乾脆直接進入上海地區酒店首頁從這裡開始爬資料

我完成的任務很簡單,分為兩步:

1、爬取點評網上海地區所有酒店的主頁地址,儲存下來

2、對於每一個酒店,爬取所有對其評價的顧客的資訊(id、name),評價情況(房間、環境、服務、評價時間等),綜合評價情況等等,並儲存

二、程式碼編寫

1、我們可以看到,酒店主頁的每一頁都有很多酒店,每一頁的url都是如下形式:

http://www.dianping.com/shanghai/hotel/pn

其中n是指頁數(1-50),這樣我們就可以遍歷所有頁面,找到所有酒店,如下:

for k1 in range(0,50):
    tempurlpag = "http://www.dianping.com/shanghai/hotel/p"+str(pagelist[k1])
    #queuepag.append(tempurlpag)
    #下面對於當前頁拿到每個酒店網址並加入佇列
    op = opener.open(tempurlpag)
    if 'html' not in op.getheader('Content-Type'):
        continue
    data1 = op.read().decode(encoding='UTF-8')
    #  onclick="window.open('/shop/2503441')
  
    linkre = re.compile(r'onclick="window.open\(\'(.*?)\'\)', re.DOTALL).findall(data1)
    for k2 in range(0, len(linkre)):
        tempurlhotel = "http://www.dianping.com" + linkre[k2]
        queue.append(tempurlhotel)
        fileOp.write(tempurlhotel+'\n')
        #print('目前是第:  %d  頁的第: %d  個酒店,其地址是 :%s'%(k1+1,k2+1,tempurlhotel))
    print('第:  %d  頁抓取完成!'%k1)

執行過程如下

輸出檔案如下:

可以看到點評網以遊客身份登入給的750條酒店資訊全部抓取到(遊客登入只顯示50頁資料,不知道使用者登入是不是醬紫,爬蟲的login請參考上上篇部落格)

2、我把所有酒店主頁放到了佇列裡,這裡用了常用的deque模組,為了防止網站禁止爬蟲,所以在post的時候要把爬蟲偽裝成瀏覽器(詳見前幾篇部落格)

對於每個酒店read到的資料,下面是獲取評價使用者name的示例:

  #   <a target="_blank" rel="nofollow" href="/member/8450012" user-id="8450012" class="J_card">
  #   <img title="靈燕兒" alt="靈燕兒" src="http://i2.dpfile.com/pc/0ffc32ea67e4e872fc50ec7c04effcec(48#c48)/thumb.jpg">

# 使用者的名字
username = re.compile(r'<img title="(.*?)" alt=', re.DOTALL).findall(data)
# print('username', username)

前面註釋裡內容是利用Google或者fiddle或者檢視儲存下來的html資料裡包含使用者名稱的一段字串,利用正則:
re.compile(r'<img title="(.*?)" alt=', re.DOTALL).findall(data)

就可以得到username

同理,獲取所有你想要的資訊,處理之後就可以格式化輸出到檔案:

mink = min(int(len(userid)), int(len(rate_total)), int(len(rate_room)))
                # print('mink:  ', mink)

                # 開啟輸出檔案,追加資訊進去
                fileOp = open(fileOut, 'a', encoding="utf-8")
                for k in range(0, mink):
                    fileOp.write('%12s\t%12s\t%20s\t%15s\t%15s\t%15s\t%15s\t\n' % (hotelid, userid[k], username[k], rate_room[k], rate_service[k], rate_total[k], rate_time[k]))
                fileOp.close()

在編寫程式碼的過程中不要忘記使用try...except丟擲異常,例如下面:
except:
        file_except = open('D:/exception.txt','a')
        file_except.write(tempurl+'\n')
        breaknumber = breaknumber+1
我們也可以順便把異常處的資訊儲存下來,方便進行除錯

這是執行過程:



(感覺自己在寫課程報告。。。習慣性貼過程。。。)

這是最後抓取到的資料樣子:


(有幾位歪了不知道啥情況,請忽略)

這樣,我們就很easy的完成了想要達成的目標(歡迎留言討論)

------------------------

要程式碼的人太多了,上傳網上了一份v2版本供大家參考,現在csdn下載無法設定為免費,所以需要1積分,

地址:http://download.csdn.net/download/drdairen/9938689