1. 程式人生 > >Ajax數據的爬取(淘女郎為例)

Ajax數據的爬取(淘女郎為例)

gen exce on() version ref write charset 匹配 char

mmtao

Ajax數據的爬取(淘女郎為例)
如有疑問,轉到 Wiki

淘女郎模特抓取教程

網址:https://0x9.me/xrh6z

判斷一個頁面是不是 Ajax 加載的方法:

查看網頁源代碼,查找網頁中加載的數據信息,如果源代碼中不顯示,證明是 Ajax 加載。
如果是網站源代碼中就包含要爬取的信息,那麽就直接只用正則拿數據出來就行了
但是如果網頁源碼中沒有,那麽就是 Ajax 了,可以進行抓包找到獲取數據的相關接口,操作如下(以爬取淘女郎美女信息為例):

一、初級

  1. 尋找 API 接口:獲取模特列表。

如果使用的是 Chrome 的話,可以首先選中 XHR 來更快速的找出獲取數據的 API,如果在 XHR 裏面沒有再去 JS 裏面一個個的尋找。

技術分享圖片

  1. 找到 API 的 URL 為:https://mm.taobao.com/alive/list.do

經過嘗試,後面的參數都是可以去掉的,訪問的時候默認 page 為 1 ,所以如果要獲取到所有頁,需要使用 for 循環分別獲取每一頁的模特列表。

技術分享圖片

  1. 然後打開一個模特的詳情頁面,使用紅框圈住的地方都是我們要獲取到的數據

技術分享圖片

  1. 打開開發者工具,然後進行和剛剛相似的抓包操作。首先選中 XHR 進行快速的找出獲取數的 API 接口,可以很容易的找到這個地址:

技術分享圖片

二、中級

下面我們抓取所有的妹子數據到文件中:

  1. 不難找到獲取後臺數據的地址為:https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8

技術分享圖片

  1. 但是我們發現在地址的 GET 參數中只有一個_input_charset=utf-8,而且默認獲取的是第一頁的妹子列表,正常情況下我們在 GET 參數中可以看到page=1類似的項,但這裏沒有,那麽很顯然它沒有用GET就肯定用了 POST ,結果一看發現確實是這樣子的。

技術分享圖片

  1. 那麽,這就簡單了,使用 requests 庫 post 請求數據,將請求來的 json 數據保存成表格,這項工作就結束了。

下面貼出代碼:

a. myheaders.py ----這個文件裏保存了一些常用的 headers 頭信息

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date: 2018-02-02 19:40:50
# @Author  : cnsimo ([email protected])
# @Link: http://www.scriptboy.com
# @Version : 1.0
import random

uaStr = '''Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)
Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1
Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11
Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)
MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'''

def getUA():
    uaList = uaStr.split('\n')
    length = len(uaList)
    return uaList[random.randint(0,length-1)]

if __name__ == '__main__':
    print(getUA())

b. mmtao.py -----主程序

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date: 2018-02-02 23:11:08
# @Author  : cnsimo ([email protected])
# @Link: http://www.scriptboy.com
# @Version : 1.0

from myheaders import getUA
import requests
import re
import time
import csv

mmListUrl = 'https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8'
mmUrl = ''

# 獲得總共的頁數
def getTotalPage():
    headers = {'User-Agent': getUA()}
    req = requests.get(mmListUrl, headers=headers)
    res = req.json()
    return res['data']['totalPage']

# 獲取列表的函數
def getMMList(cpage = 1):
    headers = {'User-Agent': getUA()}
    payload = {'currentPage': cpage, 'pageSize': 100, 'sortType': 'default', 'viewFlag': 'A'}
    req = requests.post(mmListUrl, headers=headers, data=payload)
    res = req.json()
    if 'data' in res.keys():
        return res['data']['searchDOList']
    else:
        return

if __name__ == '__main__':
    totalPage = getTotalPage()
    with open(r'mmlist.csv', 'w+', newline='') as fs:
        count = 1
        cpage = 1
        csvwriter = csv.writer(fs, dialect='excel')
        page1 = getMMList(cpage)
        csvwriter.writerow(page1[0].keys())
        print('正在處理第%s頁。。。' % cpage)
        for mm in page1:
            csvwriter.writerow(mm.values())
            print(str(count)+' ', end='')
            count += 1
        print()
        while cpage < totalPage:
            cpage += 1
            print('正在處理第%s頁。。。' % cpage)
            time.sleep(2)
            mmList = getMMList(cpage)
            if not mmList:
                break
            for mm in mmList:
                csvwriter.writerow(mm.values())
                print(str(count)+' ', end='')
                count += 1
            print('')

    print('所有數據處理完畢!')

導出的數據如下:

技術分享圖片技術分享圖片

三、高級

雖然說數據已經出來了,但是對模特的描述還是不夠具體,想要更具體的數據得通過他們的模特卡獲得,例如:https://mm.taobao.com/self/model_info.htm?spm=719.7800510.a312r.22.bKq7m9&user_id=277949921
技術分享圖片
這裏的信息要更加全面一些,所以我們從列表也只獲取模特 ID ,然後通過模特卡來拿到更加詳細的信息。

  1. 首先分析模特卡頁面,還是通過開發者工具,我們很容易找到了獲取數據的 URL :https://mm.taobao.com/self/info/model_info_show.htm?user_id=277949921
    技術分享圖片
  2. 這次響應的數據並不是格式的,不過沒有關系,我們還可以使用正則表達式將信息匹配出來。
  3. 這樣我們僅僅比剛才編寫的程序多了一個分析模特卡的步驟,很快就能寫出來這個代碼了。

部分數據截圖:

技術分享圖片

代碼詳見: mmtao_plus.py ,如有疑問,轉到 Wiki

Ajax數據的爬取(淘女郎為例)