使用python抓取App資料
阿新 • • 發佈:2018-12-30
App中的資料可以用網路爬蟲抓取麼
答案是完全肯定的:凡是可以看到的APP資料都可以抓取。
下面我就介紹下自己的學習經驗和一些方法吧 本篇適合有過web爬蟲基礎的程式猿看
沒有的的話學的可能會吃力一些
App介面爬取資料過程
- 使用抓包工具
- 手機使用代理,app所有請求通過抓包工具
- 獲得介面,分析介面
- 反編譯apk獲取key
- 突破反爬限制
需要的工具:
- 夜神模擬器
- Pycharm
實現過程
首先下載夜神模擬器模擬手機也可以用真機,然後下載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
第三步:配置代理
- 開啟主機cmd
- 輸入ipconfig檢視本機IP
- 配置代理
進入夜神模擬器–開啟設定–開啟WLAN
點選修改網路–配置代理 如下圖:
配置完後儲存
到這裡我們就設定好所有的值,下面就來測試一下,開啟手機的超級課程表APP
- 在夜神模擬器上下載你想爬取得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