猶記得本科的某段時(shí)期,點(diǎn)評上的霸王餐是讓我走出校門,游蕩京城的很大一個原因。而在其他時(shí)候,囊中羞澀的我只能感嘆一句京城居不宜而更多地選擇宅在宿舍。之后一方面是生活費(fèi)變得充足,一方面是因?yàn)榘酝醪偷纳暾堄行┞闊┚椭饾u忘記了繼續(xù)在點(diǎn)評上繼續(xù)報(bào)名。
真正產(chǎn)生寫一個報(bào)名腳本的想法誕生在找工作時(shí)期,不過那時(shí)候一方面爬蟲知識忘記了許多,另一方面也因?yàn)閷?shí)在沒有這個精力和心情來寫,然后就拖到了現(xiàn)在......
話不多說,上來就是一段源碼:
def find_activity():
headers = {
"Host": "m.dianping.com",
"Referer": "https://m.dianping.com/freemeal/index",
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Mobile Safari/537.36"
}
url = "https://m.dianping.com/astro-plat/freemeal/loadLotteryList?cityid=2&latitude=&longitude=&env=dp®ionParentId=0®ionId=0&category=0&sort=0&type=1&page={}"
index = 1
id_list = []
while True:
cur_url = url.format(str(index))
index += 1
res = requests.get(cur_url, headers=headers)
data = json.loads(res.text)["data"]
if data["pageEnd"]:
break
else:
print(data)
lotteryActivityList = data["lotteryActivityList"]
for item in lotteryActivityList:
id = item['offlineActivityId']
title = item['title']
type = item['type']
if type == 1:
id_list.append((id,title))
time.sleep(random.uniform(0.5, 1))
return id_list
if __name__ == '__main__':
find_activity()
此函數(shù)用來尋找所有可用的霸王餐活動,最后返回一個列表,包含活動名稱和對應(yīng)的編號。url中包含page,所以寫了一個while循環(huán)找到所有頁面的內(nèi)容,直到pageEnd標(biāo)識為True,然后結(jié)束循環(huán),其他好像也沒什么好說的。
有了編號就可以直接通過post提交表單來自動報(bào)名:
import requests
import time
import random
def sign_up(id_list):
sign_url = "http://s.dianping.com/ajax/json/activity/offline/saveApplyInfo"
for index in range(len(id_list)):
id = id_list[index][0]
title = id_list[index][1]
sign_headers = {
"Host": "s.dianping.com",
"Origin": "http://s.dianping.com",
"Referer": "http://s.dianping.com/event/{}".format(id),
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"
}
cookies = {
'fspop': '#',
'cy': '#',
'cye': '#',
'_lxsdk_cuid': '#',
'_lxsdk': '#',
'_hc.v': '#',
'dplet': '#',
'dper': '#',
'll': '#',
'ua': '#',
'ctu': '#',
'Hm_lvt_602b80cf8079ae6591966cc70a3940e7': '#',
's_ViewType': '#',
'_lx_utm': '#',
'Hm_lpvt_602b80cf8079ae6591966cc70a3940e7': '#',
'_lxsdk_s': '#'
}
data = {
'offlineActivityId': id,
'phoneNo': '#',
'shippingAddress': '',
'extraCount': '',
'birthdayStr': '',
'email': '',
'marryDayStr': '',
'babyBirths': '',
'pregnant': '',
'marryStatus': '0',
'comboId': '',
'branchId': '',
'usePassCard': '0',
'passCardNo': '',
'isShareSina': 'false',
'isShareQQ': 'false'
}
res = requests.post(sign_url, headers=sign_headers, cookies=cookies, data=data)
print(title, res.text)
time.sleep(random.uniform(0.5, 1))
cookies需要填自己賬號正常訪問產(chǎn)生的cookies,跑完一遍就將霸王餐報(bào)名成功啦。
除了一種情況:該活動有多家門店參加活動,但不通用,需要選擇一家門店來報(bào)名。這個時(shí)候表單中branchId會有該門店的shopid值,為一串?dāng)?shù)字,不適用該數(shù)字形式的branchId會報(bào)名失?。▋H針對多門店不通用情況):

但在頁面中找不到這串?dāng)?shù)字,只能找到shopid的字符串:

而shop/k3VuR1XItjK7I1wW
和shop/1856704708
這倆url指向的是同一個地址,因此我認(rèn)為點(diǎn)評隱藏了真正的shopid而將其編碼后的結(jié)果作為shopid放了出來,后臺可以將其對應(yīng)起來而用戶無法找到真實(shí)的shopid也就無法在提交表單時(shí)輸入正確的branchId。
不過結(jié)果我一下午的嘗試,真實(shí)branchId還是存在的,而且好像在店鋪主界面shop/k3VuR1XItjK7I1wW就存在,奇怪,之前沒有的,現(xiàn)在能夠找到了:

但是我也懶得寫了,就這樣吧,再爬號都要封了。

之前爬的時(shí)候沒過濾type,導(dǎo)致報(bào)名了一堆麗人項(xiàng)目,這這這這這。。。我看60個名額的項(xiàng)目只有29個報(bào)名,誰知道有多坑,而且之后報(bào)上了還得手動退。趕緊再改改,加上對type的過濾后就只剩美食項(xiàng)目了。

好啦,我們下期再見!