使用python抓取App數據


使用python抓取App數據

App中的數據可以用網絡爬蟲抓取么

答案是完全肯定的:凡是可以看到的APP數據都可以抓取。
下面我就介紹下自己的學習經驗和一些方法吧 本篇適合有過web爬蟲基礎的程序猿看
沒有的的話學的可能會吃力一些

App接口爬取數據過程

  • 使用抓包工具
  • 手機使用代理,app所有請求通過抓包工具
  • 獲得接口,分析接口
  • 反編譯apk獲取key
  • 突破反爬限制

需要的工具:

實現過程

首先下載夜神模擬器模擬手機也可以用真機,然后下載Fiddler抓取手機APP數據包,分析接口完成以后使用Python實現爬蟲程序

Fiddler安裝配置過程

第一步:下載神器Fiddler

Fiddler下載完成之后,傻瓜式的安裝一下!

第二步:設置Fiddler

打開Fiddler, Tools-> Fiddler Options (配置完后記得要重啟Fiddler)
選中"Decrpt HTTPS traffic", Fiddler就可以截獲HTTPS請求
選中"Allow remote computers to connect". 是允許別的機器把HTTP/HTTPS請求發送到Fiddler上來
這里寫圖片描述
這里寫圖片描述
記住這個端口號是:8888

夜神模擬器安裝配置過程

######第一步:下載安裝
夜神模擬器下載完成之后,傻瓜式的安裝一下!
######第二步:配置橋接 實現互通
首先將當前手機網絡橋接到本電腦網絡 實現互通
這里寫圖片描述這里寫圖片描述
安裝完成橋接驅動后配置IP地址,要配成和本機互通的網段,配置完成后打開主機cmd終端ping通ok

第三步:配置代理
  1. 打開主機cmd
    這里寫圖片描述
  2. 輸入ipconfig查看本機IP
    這里寫圖片描述
  3. 配置代理
    進入夜神模擬器–打開設置–打開WLAN
    這里寫圖片描述
    點擊修改網絡–配置代理 如下圖:
    這里寫圖片描述
    配置完后保存
    到這里我們就設置好所有的值,下面就來測試一下,打開手機的超級課程表APP
    這里寫圖片描述
  4. 在夜神模擬器上下載你想爬取得App使用Fiddler抓包分析api后使用python進行爬取就可以了

####爬取充電網APP實例
爬取部分內容截圖:
這里寫圖片描述
部分python代碼分享:

import requests
import city
import json
import jsonpath
import re

city_list = city.jsons
tags_list = city.Tag

def city_func(city_id):
    try:
        city = jsonpath.jsonpath(city_list, '$..sub[?(@.code=={})]'.format(int(city_id)))[0]["name"]
    except:
        city = jsonpath.jsonpath(city_list, '$[?(@.code=={})]'.format(int(city_id)))[0]["name"]
    return city

def tags_func(tags_id):
    tags_join = []
    if tags_id:
        for tags in tags_id:
            t = jsonpath.jsonpath(tags_list,'$..spotFilterTags[?(@.id=={})]'.format(int(tags)))
            tags_join.append(t[0]["title"])

    return ('-'.join(tags_join))

def split_n(ags):
    return re.sub('\n',' ',ags)


def request(page):
    print('開始下載第%d頁'%page)
    url = 'https://app-api.chargerlink.com/spot/searchSpot'
    two_url = "https://app-api.chargerlink.com/spot/getSpotDetail?spotId={d}"
    head = {
        "device": "client=android&cityName=%E5%8C%97%E4%BA%AC%E5%B8%82&cityCode=110106&lng=116.32154281224254&device_id=8A261C9D60ACEBDED7CD3706C92DD68E&ver=3.7.7&lat=39.895024107858724&network=WIFI&os_version=19",
        "appId": "20171010",
        "timestamp": "1532342711477",
        "signature": "36daaa33e7b0d5d29ac9c64a2ce6c4cf",
        "forcecheck": "1",
        "Content-Type": "application/x-www-form-urlencoded",
        "Content-Length": "68",
        "Host": "app-api.chargerlink.com",
        "Connection": "Keep-Alive",
        "User-Agent": "okhttp/3.2.0"
    }


    data = {
        "userFilter[operateType]": 2,
        "cityCode": 110000,
        "sort": 1,
        "page": page,
        "limit": 10,
    }

    response = requests.post(url,data=data,headers=head)
    #獲取數據
    data = response.json()
    for i in data['data']:
        c = []
        id = i['id']
        name = i["name"] #充電樁名
        phone = i["phone"] #手機號
        num = i['quantity'] #有幾個充電樁
        city = city_func(i["provinceCode"]) #城市
        tags =tags_func(i["tags"].split(','))#標簽
        message = c + [id,name,phone,num,city,tags]
        parse_info(two_url.format(d=id),message)

def parse_info(url,message):

    #打開文件
    with open('car.csv','a',encoding='utf-8')as c:
        head = {
            "device": "client=android&cityName=&cityCode=&lng=116.32154281224254&device_id=8A261C9D60ACEBDED7CD3706C92DD68E&ver=3.7.7&lat=39.895024107858724&network=WIFI&os_version=19",
            "TOKEN": "036c8e24266c9089db50899287a99e65dc3bf95f",
            "appId": "20171010",
            "timestamp": "1532357165598",
            "signature": "734ecec249f86193d6e54449ec5e8ff6",
            "forcecheck": "1",
            "Host": "app-api.chargerlink.com",
            "Connection": "Keep-Alive",
            "User-Agent": "okhttp/3.2.0",
        }
        #發起詳情請求
        res = requests.get(url,headers=head)
        price = split_n(jsonpath.jsonpath(json.loads(res.text),'$..chargingFeeDesc')[0]) #價錢
        payType = jsonpath.jsonpath(json.loads(res.text),'$..payTypeDesc')[0] #支付方式
        businessTime =split_n(jsonpath.jsonpath(json.loads(res.text),'$..businessTime')[0]) #營業時間
        result = (message + [price,payType,businessTime])
        r = ','.join([str(i) for i in result])+',\n'
        c.write(r)

def get_page():
    url = 'https://app-api.chargerlink.com/spot/searchSpot'
    head = {
        "device": "client=android&cityName=%E5%8C%97%E4%BA%AC%E5%B8%82&cityCode=110106&lng=116.32154281224254&device_id=8A261C9D60ACEBDED7CD3706C92DD68E&ver=3.7.7&lat=39.895024107858724&network=WIFI&os_version=19",
        "appId": "20171010",
        "timestamp": "1532342711477",
        "signature": "36daaa33e7b0d5d29ac9c64a2ce6c4cf",
        "forcecheck": "1",
        "Content-Type": "application/x-www-form-urlencoded",
        "Content-Length": "68",
        "Host": "app-api.chargerlink.com",
        "Connection": "Keep-Alive",
        "User-Agent": "okhttp/3.2.0"
    }

    data = {
        "userFilter[operateType]": 2,
        "cityCode": 110000,
        "sort": 1,
        "page": 1,
        "limit": 10,
    }
    response = requests.post(url, data=data, headers=head)
    # 獲取數據
    data = response.json()
    total = (data["pager"]["total"])
    page_Size = (data["pager"]["pageSize"])
    totalPage = (data['pager']["totalPage"])
    print('當前共有{total}個充電樁,每頁展示{page_Size}個,共{totalPage}頁'.format(total=total,page_Size=page_Size,totalPage=totalPage))
if __name__ == '__main__':
    get_page()
    start = int(input("親,請輸入您要獲取的開始頁:"))
    end = int(input("親,請輸入您要獲取的結束頁:"))
    for  i in range(start,end+1):
        request(i)
 

 

總結:

app里的數據比web端更容易抓取,反爬蟲也沒拿么強,大部分也都是http/https協議,返回的數據類型大多數為json

 


免責聲明!

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



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