此篇文章主要是为了教大家如何使用pyppeteer,切勿用于非法用途,否则后果自负!
回归正题!今天猫哥要讲的内容是,利用pyppeteer购买某麦网演唱会门票。作为技术交流,猫哥只实现了基本的功能!
实现原理:首先,我们无需破解其登录,直接通过手机扫码进入主页面。其次,通过访问我们的目标网址(也就是,我们想要抢的那场票。例如:抢刘德华的票,那么目标网址就直接定位到刘德华的预定页面)。然后,通过不断的监控、刷新页面,来选座、预定。最后,如果预定成功,则添加观影人,提交订单。如果预定失败,就返回预定页面,继续刷新,直到预定成功,提交了订单为止。
入口函数 dmspider.py 文件,此文件功能主要是调用pyppeteer的执行以及调用种子url。因为我们的spider文件中不可能只放一个爬虫,也不是所有的爬虫都会用pyppeteer去执行,所以就将其定义为middlewares中的一个功能,用时直接调用。
# -*- coding: utf-8 -*-
import scrapy
class DmspiderSpider(scrapy.Spider):
name = 'dmspider'
allowed_domains = ['damai.cn']
# start_urls = ['http://damai.cn/']
# 爬虫的设置
custom_settings = {
"DOWNLOADER_MIDDLEWARES": {
'DMTickets.middlewares.FundscrapyDownloaderMiddleware': 260,
}
}
def start_requests(self):
# url = "https://www.damai.cn/"
url = "https://passport.damai.cn/login?ru=https%3A%2F%2Fwww.damai.cn%2F"
yield scrapy.FormRequest(
url=url,
callback=self.parse,
meta={"usePypp": True},
dont_filter=True,
)
def parse(self, response):
print("success!")
利用pyppeteer去访问种子URl,我们的种子URL其实就是某麦网的登录页面。登录过程我们是利用手机扫码登录,也就是说当pyppeteer将登录页面加载出来后,我们要用自己的手机扫码登录。登录后,通过判断我们昵称是否一致,来确定是否登录成功,然后再进行下一步操作。
async def usePyppeteer(self, request):
num = random.randint(3, 6)
await asyncio.sleep(num)
# UA 随机更换UA
await self.page.setUserAgent(random.choice(self.user_agent))
await self.page.setViewport({'width': 1366, 'height': 768})
# 是否启用JS,enabled设为False,则无渲染效果
await self.page.setJavaScriptEnabled(enabled=True)
try:
await self.page.goto(request.url, options={'timeout': 30000, "waitUntil": "networkidle2"})
except Exception as e:
print(e)
print("error" * 100)
# 注入JS, 绕过浏览器检测
await self.page.evaluate("""() =>{Object.defineProperties(navigator, {webdriver:{get: () => false}})}""")
await self.page.evaluate(
'''() =>{Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});}''')
await self.page.evaluate(
'''() =>{Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }''')
# num = random.randint(3, 6)
await asyncio.sleep(10)
content = await self.page.content()
content = etree.HTML(content)
nick_name = content.xpath("//div[@class='span-box-header name-user show']/text()")[0]
print(nick_name)
# 获取昵称,判断账号是否登录成功!注:此昵称要改为自己的昵称
if nick_name == "猫哥":
# 不断循环,检测是否可以购买
while True:
page = await self.choose_tickets()
if page:
while True:
page = await self.submit_order()
if page:
time.sleep(3000)
else:
continue
else:
continue
登录成功后,进行选座、订票。此处猫哥只写了个简单的订票功能,大家可以根据自己学到的知识自行补充,完善功能,猫哥就直接上代码了。
# 选票功能 此处大家可以自由发挥,自行添加更多功能
async def choose_tickets(self):
await self.page.goto(self.target_url, options={'timeout': 30000, "waitUntil": "networkidle2"})
# 添加选座功能
# await self.page.click(".perform__order__select perform__order__select__performs > div.select_right > div.select_right_list > div.select_right_list_item")
# await self.page.click(".perform__order__select > div.select_right > div.select_right_list > div.select_right_list_item sku_item")
# buybtn = await self.page.xpath("//div[@class='buybtn']//text()")
content = await self.page.content()
content = etree.HTML(content)
buybtn = content.xpath("//div[@class='buybtn']//text()")
if buybtn:
if buybtn[0] == "立即预订" or buybtn[0] == "立即购买":
await self.page.click(".buybtn")
await asyncio.sleep(1)
return True
else:
return None
else:
return None
预定成功后,就可以提交订单了。不过此处有一个坑,大家要注意了。因为有些演唱会的门票需要实名认证,这个大家要提前在自己的账号中添加好购票人,需要实名认证的,要提前认证。要不然最后提交的时候,如果没有添加购票人,就会提交失败!
# 提交订单
async def submit_order(self):
content = await self.page.content()
content = etree.HTML(content)
order = content.xpath("//div[@class='submit-wrapper']/button/text()")
if order:
print("exit order!")
# content = await self.page.content()
# print(content)
try:
await self.page.click(".next-checkbox-label")
await self.page.click(".submit-wrapper > button")
return True
except Exception as e:
print(e)
return await self.choose_tickets()
else:
return None
以上就是某麦网抢票的所有过程,看过我以前文章的朋友,估计一眼就能看出来,这个和12306抢票软件源码详解是一个原理。
好了,今天的分享就到这里。下面我放一个GitHub的源码链接,喜欢的朋友帮猫哥start一下哈~
猫哥公众号,欢迎大家关注!主推数据挖掘、数据分析和机器学习~