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