吳裕雄--天生自然PYTHON爬蟲:爬取某一大型電商網站的商品數據


首先觀察、分析網站

網址:https://touch.qunar.com

 接下按F12進入瀏覽器開發者模式,並且點擊  自由行  選項進入到自由行頻道,如下圖:

 

 

 

 

 

 

 

 

Request URL:
https://dujia.qunar.com/golfz/destination/tejiaLeft?num=6&tms=pc_jrth&dep=%E6%B7%B1%E5%9C%B3&callback=jQuery17203372573055312833_1579011479291&_=1579011479776
單擊任意一個城市,通過觀察可以發現數據在XHR(用XMLHttpRequest方法來獲取JavaScript)

 

 

其中RequestURL是以%開頭的字符串是中文編譯成的字符串,由於服務器不能識別中文字符,所以這里可以使用第三方工具解碼查看。
這里使用的是零一工具。下載網址: http://www.muyaotech.com/about_muyao.php?cid=40
安裝過程如下:

 

 

 

 

 

 

 

 

 

 

 任意點擊一張圖片,再從開發者模式的header那里查看

Request URL:
https://dujia.qunar.com/golfz/routeList?isTouch=0&t=all&extendFunction=%E8%87%AA%E7%94%B1%E8%A1%8C&q=%E5%8E%A6%E9%97%A8&d=%E6%B7%B1%E5%9C%B3&s=all&qs_ts=1579012214105&tf=pcindex_free&tm=djnull&sourcepage=list&userResident=%E6%B7%B1%E5%9C%B3&random=748656&aroundWeight=1&qssrc=eyJ0cyI6IjE1NzkwMTIyMTQxMDUiLCJzcmMiOiJhbGwuZW52YiIsImFjdCI6InNlYXJjaCIsInJhbmRvbSI6Ijc0ODY1NiJ9&m=p%2Cpr%2Ciso%2CisSd%2Chco%2Chtl%2Cactivities%2Cns%2Cnep%2Cgg%2CrefundAnytime%2CtruthfulDesc&displayStatus=pc&ddf=true

 

 可以看到上面的URL是UTF8編碼的,解碼后就可以看到中文部分了。

Request URL:
https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep=%E5%8C%97%E4%BA%AC&query=%E5%8E%A6%E9%97%A8%E8%87%AA%E7%94%B1%E8%A1%8C&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E5%8E%A6%E9%97%A8%E8%87%AA%E7%94%B1%E8%A1%8C&limit=0,24&includeAD=true&qsact=search

 

由於這里的目標是獲取整個自由行的產品列表,因此還需要獲取出發站點的列表,從不同的城市出發,會有不用的產品。

返回自由行的首頁,單擊搜索框左側的出發站點,如下圖:

 

 切換到Headers界面:

 

 可以看到此時目標的URL是:https://touch.dujia.qunar.com/depCities.qunar

開始分析該網站的爬蟲工作流程分析步驟:

1 獲取出發地站點列表

2 獲取旅游景點列表

3 獲取景點產品列表

4 存儲數據

 

 

#首先獲取出發站點,代碼如下:
import requests

url = 'https://touch.dujia.qunar.com/depCities.qunar'
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        print(dep)

 

 。。。。。。。。。

 

 

 

 在獲取數據的時候需要將最后一個callback參數刪掉。因此目標URL如下:

https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep=%E6%B7%B1%E5%9C%B3&exclude=&extensionImg=255,175

 

 

#然后根據出發地站點獲取目的地,代碼如下:
import time
import urllib
import requests

url = 'https://touch.dujia.qunar.com/depCities.qunar'
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        print(dep)
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(urllib.request.quote(dep))
        time.sleep(3)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    print(query['query'])
        

 

 .................

 

到達的 目的地有很多,上面這段代碼也要運行很長時間,運行截圖也是一部分的,篇幅有限還有很多地點沒有展示,但很容易看到許多的目的地是重復的,

原因也很簡單一個目的地多數都是對應這多個出發點的,按出發點分別來找目的地的話最后打印尋找到的目的地肯定有許多也就是重復的了,所以接下來

就是要對目的地進行去重,代碼修改后,如下:

#然后根據出發地站點獲取目的地,代碼如下:
import time
import urllib
import requests

url = 'https://touch.dujia.qunar.com/depCities.qunar'
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        #這里聲明一個列表a用來保存當前這個出發點對應的所有目的地
        a = []
        print(dep)
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(urllib.request.quote(dep))
        time.sleep(3)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    #如果當前這個目的地不在a中的話,那就添加進去,否則不添加,這樣就可以達到目的地去重的目的了
                    if(query['query'] not in a):
                        a.append(query['query'])
        #打印當前出發點所有對應的不重復的目的地點
        print(a)
        

 

 

 這樣每個出發點對應的目的點打印出來也好看清晰了許多。

完成了出發點和目的地的構建之后,接下來就要獲取產品列表了。代碼如下:

 

 

 

 

#獲取產品列表
import time
import urllib
import pymongo
import requests

#使用MongoDB創建數據庫、表
client = pymongo.MongoClient('localhost',27017)
book_qunar = client['qunar']
sheet_qunar_zyx = book_qunar['qunar_zyx']

#獲取產品
url = 'https://touch.dujia.qunar.com/depCities.qunar'
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        #這里聲明一個列表a用來保存當前這個出發點對應的所有目的地
        a = []
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(urllib.request.quote(dep))
        time.sleep(3)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    #如果當前這個目的地不在a中的話,那就添加進去,否則不添加,這樣就可以達到目的地去重的目的了
                    if(query['query'] not in a):
                        a.append(query['query'])
        #逐個地取出當前出發點對應的目的地item
        for item in a:
            url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery={}&limit=0,24&includeAD=true&qsact=search'.format(urllib.request.quote(dep),urllib.request.quote(item),urllib.request.quote(item))
            time.sleep(3)
            strhtml = requests.get(url)
            #獲取當前目的地的產品數量
            routeCount = int(strhtml.json()['data']['limit']['routeCount'])
            for limit in range(0,routeCount,24):
                url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery={}&limit={},24&includeAD=true&qsact=search'.format(urllib.request.quote(dep),urllib.request.quote(item),urllib.request.quote(item),limit)
                time.sleep(3)
                strhtml = requests.get(url)
                #用一個字典保存當前這個產品的信息
                result = {
                    'date':time.strftime('%Y-%m-%d',time.localtime(time.time())),
                    'dep':dep,
                    'arrive':item,
                    'limit':limit,
                    'result':strhtml.json()
                }
                #向數據庫中插入這條產品信息記錄
                sheet_qunar_zyx.insert_one(result)
                print('成功!')

 

爬取的數據量是非常大的 代碼需要運行非常長的時間,運行代碼打開pycharm就可以觀察到保存的數據了(前提是pycharm已經安裝好了mongo的插件了以及本地安裝配置好mongodb了)

 

 

 

 

 

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM