V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yinuxy
V2EX  ›  Python

小米商城优惠券抢购

  •  
  •   yinuxy · 2020-04-27 10:45:53 +08:00 · 5407 次点击
    这是一个创建于 1432 天前的主题,其中的信息可能已经有所发展或是发生改变。

    登录网址: https://account.xiaomi.com/ 活动页面: https://s1.mi.com/m/app/hd/index.html?id=15042 如题,我想买个小米手环但是小米商城里面的 5 折优惠券太难抢了,于是手写了一段代码(selenium)如下:

    from selenium import webdriver
    import time
    import datetime
    chrome_driver = 'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe'  #chromedriver 的文件位置
    browser = webdriver.Chrome(executable_path = chrome_driver)
     
    def login(name ,pwd):
        browser.get( 'https://account.xiaomi.com/')#登录网址
        time.sleep(2)
        browser.find_element_by_id("username").send_keys(name) #利用账号标签的 ID,确定位置并 send 信息
        browser.find_element_by_id("pwd").send_keys(pwd) #利用密码标签的 ID,确定位置并 send 信息
        browser.find_element_by_id("login-button").click()#利用登录按钮的 ID,确定位置并点击
        #如果找不到标签 ID,可以使用其他方法来确定元素位置
        time.sleep(3)
        browser.get("https://s1.mi.com/m/app/hd/index.html?id=15042")#切换到秒杀页面
        print('登录成功,正在等待秒杀···')
     
    def buy_on_time():
        while True: #不断刷新时钟
            now = datetime.datetime.now()
            if now.strftime('%H:%M:%S') == '09:00:00' or now.strftime('%H:%M:%S') == '11:00:00' or now.strftime('%H:%M:%S') == '15:00:00' or now.strftime('%H:%M:%S') == '17:00:00':
    #        if now.strftime('%H:%M:%S') == buytime:
                browser.find_element_by_xpath("//div[@class='content-box flex-box']/a[@data-log_code='logcode#activity_code=wjsncc49&page=activity&page_id=15042&bid=3645414.0']/div/img").click()
    #            browser.find_element_by_xpath("//a[@data-log_code='logcode#activity_code=1i19jyzh&page=activity&page_id=15042&bid=3645414.0']").click()
    #            browser.find_element_by_xpath("//a[@data-log_code='logcode#activity_code=tudhbjjy&page=activity&page_id=15042&bid=3646017.0']").click() #购买按钮的 Xpath
    #            browser.find_element_by_xpath("//a[@data-log_code='logcode#activity_code=qpohzak0&page=activity&page_id=15042&bid=3646017.0']").click()
                print('当前时段已抢购完毕')
            time.sleep(0.01)#注意刷新间隔时间要尽量短
     
    login('username' , 'password')
    time.sleep(10)
    buy_on_time()#指定秒杀时间,并且开始等待秒杀
    

    运行的时候发现了一个问题,直接运行的话会报错找不到元素

    selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <img src="//cdn.cnbj1.fds.api.mi-img.com/mi-mall/233e61ba38ffb86943fea320adb1607a.jpg"> is not clickable at point (394, 648). Other element would receive the click: <img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6e607d2e29651daa308b6310998f2991.png?w=216&amp;h=160&amp;bg=7FFFFF">
      (Session info: chrome=83.0.4103.7)
    

    然后我每次都要在它运行之后在 Chromedriver 开的浏览器里面F12打开一下源码之后运行才不会报错,求问大佬这种优惠券的话该怎么抓取,能给个源码就更好啦!

    31 条回复    2020-04-28 17:01:06 +08:00
    youngs
        1
    youngs  
       2020-04-27 11:03:01 +08:00
    传说中的薅羊毛?
    hunter2015
        2
    hunter2015  
       2020-04-27 11:04:53 +08:00
    鉴定完毕,羊毛党
    yinuxy
        3
    yinuxy  
    OP
       2020-04-27 11:05:43 +08:00
    @youngs 这羊毛可不好薅,手工根本抢不到
    evilic
        4
    evilic  
       2020-04-27 11:15:01 +08:00
    偷懒的代码

    ```python
    #!/usr/bin/python3
    # -*- coding: UTF-8 -*-

    import pyautogui

    pyautogui.moveTo(968, 485) # 链接坐标
    pyautogui.click(clicks=20000)
    ```
    evilic
        5
    evilic  
       2020-04-27 11:16:39 +08:00
    事实上,我也不知道代码能不能运行,因为我不抢券。
    yinuxy
        6
    yinuxy  
    OP
       2020-04-27 11:19:15 +08:00
    @evilic 额,这个好像不行
    evilic
        7
    evilic  
       2020-04-27 11:33:42 +08:00
    这种抢券的,正常应该是在 console 里加载 js 然后直接执行 js 发送请求的,不需要 selenium 的。
    sigone
        9
    sigone  
       2020-04-27 12:27:22 +08:00 via Android
    我觉得你不如写一个京东抢飞天茅台的外挂更有意义。
    gunavy
        10
    gunavy  
       2020-04-27 12:48:14 +08:00
    能行?没有前段分流吗?
    yinuxy
        11
    yinuxy  
    OP
       2020-04-27 12:58:02 +08:00 via Android
    @evilic js 不会,只会 Python
    yinuxy
        12
    yinuxy  
    OP
       2020-04-27 12:58:26 +08:00 via Android
    @sigone 茅台要本钱呐
    LZSZ
        13
    LZSZ  
       2020-04-27 13:22:40 +08:00
    driver.find_elements_by_class_name('flex-box-item')[2].Click();
    行不行?
    zdnyp
        14
    zdnyp  
       2020-04-27 13:29:24 +08:00
    selenium 不行的,速度太慢了。人家接口 2s 请求完了,你浏览器还没打开。
    yinuxy
        15
    yinuxy  
    OP
       2020-04-27 13:43:22 +08:00 via Android
    @zdnyp 那用啥呢
    cquyf
        16
    cquyf  
       2020-04-27 13:46:14 +08:00
    大佬就是厉害
    westoy
        17
    westoy  
       2020-04-27 13:46:43 +08:00
    headless 是抢不到的, 别浪费时间了

    真の黄牛都是直接怼接口的
    heyhumor
        18
    heyhumor  
       2020-04-27 13:54:38 +08:00
    xpath 不行就用 css_selector
    yinuxy
        19
    yinuxy  
    OP
       2020-04-27 14:07:56 +08:00
    @LZSZ 我去试试
    yinuxy
        20
    yinuxy  
    OP
       2020-04-27 14:08:13 +08:00
    @evilic 好得,我等会儿去试试
    xiaoming1992
        21
    xiaoming1992  
       2020-04-27 15:18:48 +08:00 via Android
    同楼上,还是 f12 找找接口直接发请求吧
    2joe
        22
    2joe  
       2020-04-27 18:08:21 +08:00
    selenium 不适用这个抢东西,放弃把,搞接口
    yinuxy
        23
    yinuxy  
    OP
       2020-04-27 21:37:08 +08:00
    @2joe 用 js 吗,我不太会,可以说详细点吗,谢谢
    yinuxy
        24
    yinuxy  
    OP
       2020-04-27 21:39:17 +08:00
    @westoy 大佬能否说得详细点
    yunying
        25
    yunying  
       2020-04-27 21:46:16 +08:00
    headless 虚拟浏览器也就适合模拟登录时偷懒用。。真正爬数据时还是得靠接口直接请求获取。。而且这也不用 js 。直接 python 发起 http 请求就好
    HuberyPang
        26
    HuberyPang  
       2020-04-28 14:26:45 +08:00
    F12 进入控制台,运行下面这个代码
    var timer = setInterval(function() {
    document.querySelector("#app > div > div:nth-child(5) > div > div > a:nth-child(1)").click());
    }, 3000)
    此时每隔秒大概可以看到一次,活动未开始,证明进行了请求
    每隔 3 秒请求一次,clearInterval(timer) 这个是清除定时。至于会不会被拉黑账号这个就不清楚了。
    HuberyPang
        27
    HuberyPang  
       2020-04-28 14:28:32 +08:00
    一会儿 3 点我试一波,哈哈哈
    HuberyPang
        28
    HuberyPang  
       2020-04-28 15:05:37 +08:00
    上面那个 click 多打了半个括号,抢购失败。
    yinuxy
        29
    yinuxy  
    OP
       2020-04-28 16:13:52 +08:00
    @HuberyPang 哈哈哈
    yinuxy
        30
    yinuxy  
    OP
       2020-04-28 16:14:32 +08:00
    @HuberyPang 设置 3s 的话会不会太长了,这个优惠券基本上都是秒的
    yinuxy
        31
    yinuxy  
    OP
       2020-04-28 17:01:06 +08:00
    @HuberyPang 太快了,我调成 1ms 也不行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2447 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 15:55 · PVG 23:55 · LAX 08:55 · JFK 11:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.