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
Nostalgia
V2EX  ›  Python

[求助] Python Selenium click() 无效

  •  
  •   Nostalgia · 2016-11-18 17:01:56 +08:00 · 8815 次点击
    这是一个创建于 2954 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚接触 Python 的 Selenium 不久,就想做个小玩具练练手。我写的玩具是登录淘宝,签到领取淘金币。
    现在遇到的问题是,从「店铺签到」入口进入到各家店铺( eg. URL https://shop136560499.taobao.com/ugo.htm?spm=a217e.7759359.15285.2.pa4eVE&signin=true )后,想模拟点击「立即签到」,但是 click() 事件无效。

    相关代码如下:

        # 店铺签到
        def shop_check_in(self):
            urls = [
                    'https://nongfutechan.taobao.com/ugo.htm?spm=a217e.7759359.15285.1.4xE9Il&signin=true#ugo-jinbi',
                    'https://shop136560499.taobao.com/ugo.htm?spm=a217e.7759359.15285.2.muhVBy&signin=true#ugo-jinbi',
                    'https://shop33473134.taobao.com/ugo.htm?spm=a217e.7759359.15285.3.yW2N4E&signin=true#ugo-jinbi'
                    ]
            for url in urls:
                self.driver.get(url)
                time.sleep(5)
                print("page_source\t%s" % self.driver.page_source)
                self.driver.find_element_by_xpath('//a[@href="#" and @class="now-take J_NowSignIn" and text()="立即签到"]').click()
    

    我尝试过的方法有:

    • 增加 wait 时间,确保新页面已经完全加载
    • 用 Google Chrome 的 XPath Helper 插件,确保自己写的 XPath selector 无误
    • 打印源代码 driver.page_source ,确认页面内有「立即签到」这个元素,并且 XPath selector 无误
    • 用鼠标右键 element.context_click() 测试,确认确实选中了「立即签到」这个元素
    • 尝试用 ActionChains + element.send_keys(Keys.ESCAPE) + element.send_keys(Keys.ENTER) 等类似方式,尝试无效
    • 尝试过 Chrome/FireFox 两种浏览器,尝试无效

    实际测试过程中发现,只有极少数情形,模拟点击「立即签到」成功;其它大多数情形下, click() 事件都是无效的。
    目前没有想到别的方法了……
    一般而言, Selenium click() 无效,可能会是什么原因呢?
    请大家帮忙分析下原因,指点一二?
    谢谢大家。

    20 条回复    2016-11-19 10:11:47 +08:00
    Nostalgia
        1
    Nostalgia  
    OP
       2016-11-18 21:05:30 +08:00
    @lilydjwg 仙子童鞋了解么? V2EX 上人都不认识……
    lilydjwg
        2
    lilydjwg  
       2016-11-18 21:14:30 +08:00   ❤️ 1
    可能是时序方面的原因?你点早了?
    Nostalgia
        3
    Nostalgia  
    OP
       2016-11-18 21:33:21 +08:00
    @lilydjwg 哇哦,仙子在线哟。
    应该不是时间的问题,我 time.sleep() 设置了延时,确保页面已经加载完成了。
    另外,用 ActionChains.context_click() 测试,发现鼠标右键确实放在了相应的 element 上。
    lilydjwg
        4
    lilydjwg  
       2016-11-18 21:48:20 +08:00   ❤️ 1
    我不会用 Selenium ……在页面加载完之后,选择器没错。你把你程序执行时的元素打印出来看看获取到了没?请求发出去了没?
    不过你何不通过抓包来看怎么发请求呢?
    misaka19000
        5
    misaka19000  
       2016-11-18 21:54:21 +08:00
    头像太可怕了🤢
    Nostalgia
        6
    Nostalgia  
    OP
       2016-11-18 21:58:11 +08:00
    @lilydjwg 哈哈,以为你啥都会呢。:-)
    不通过发 HTTP 请求的方式是因为淘宝这类网站登陆太复杂,而且很多操作涉及到很多 JS 代码,光靠 urllib/requests 之类的不行。
    还是很谢谢仙子,笑口常开,常喜乐。
    Nostalgia
        7
    Nostalgia  
    OP
       2016-11-18 21:59:51 +08:00
    @misaka19000 瞎说什么大实话。
    holajamc
        8
    holajamc  
       2016-11-18 22:01:11 +08:00   ❤️ 1
    driver.implicitly_wait() 或者 WebDriverWait(driver, 10).until()

    第一个是隐式等待;第二个是显式等待,可以等待某一个元素加载完成,推荐去虫师的博客翻翻
    Nostalgia
        9
    Nostalgia  
    OP
       2016-11-18 22:04:05 +08:00
    @holajamc explicit/implicit wait 我还是懂的。
    确定是页面加载完了,我才点击的。
    holajamc
        10
    holajamc  
       2016-11-18 22:05:38 +08:00
    @Nostalgia 我用一般用等待就好了哈哈哈淘宝难道有什么限制?
    holajamc
        11
    holajamc  
       2016-11-18 22:08:23 +08:00   ❤️ 1
    @Nostalgia
    //*[@id="ugo-jinbi"]/div/div[2]/div[1]/div/div[2]/p[1]/a
    #ugo-jinbi > div > div.act-module-bd > div.act-jinbi-take > div > div.J_SignInCon > p.today-can-do > a
    用 Chrome 复制出来的~试试换一下 xpath 或者用 css 选择器~
    Nostalgia
        12
    Nostalgia  
    OP
       2016-11-18 22:08:56 +08:00
    @holajamc 不知道哎。
    觉得自己该考虑的都考虑了。有点儿怀疑是 Selenium 的 bug ……
    Nostalgia
        13
    Nostalgia  
    OP
       2016-11-18 22:11:00 +08:00
    @holajamc 谢谢你,我也试下 CSS selector 。
    unfurl
        14
    unfurl  
       2016-11-18 22:30:11 +08:00
    相信不是楼主 selenium 使用的问题
    unfurl
        15
    unfurl  
       2016-11-18 22:31:05 +08:00   ❤️ 1
    我不记得在哪个场合听说过,淘宝的前端能精确识别非人类的操作, so....
    bbxiong
        16
    bbxiong  
       2016-11-19 00:03:38 +08:00   ❤️ 1
    你试试点击浏览器式浏览器前台,发现 click 有些地方浏览器必须前台才能用......
    Nostalgia
        17
    Nostalgia  
    OP
       2016-11-19 00:17:16 +08:00
    @unfurl 感觉除了 referer 及操作时间间隔以外, Selenium 与普通的用户点击没有什么区别吧……
    Nostalgia
        18
    Nostalgia  
    OP
       2016-11-19 00:23:19 +08:00
    @bbxiong 你的意思是把 Selenium 放在所有窗口的最前面么?
    这个也试过,尝试无效。
    Nostalgia
        19
    Nostalgia  
    OP
       2016-11-19 00:53:51 +08:00   ❤️ 2
    @lilydjwg @holajamc @unfurl @bbxiong
    问题基本定位到了。
    原因是, WebElement.click() 之后,没有留足够的时间,就把页面切走或关闭了。 click() 之后,应该留有足够的时间,让 browser 客户端执行 JS 代码,再把请求发到服务端。
    谢谢大家。
    lilydjwg
        20
    lilydjwg  
       2016-11-19 10:11:47 +08:00
    @Nostalgia 果然是这样子……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1254 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 18:01 · PVG 02:01 · LAX 10:01 · JFK 13:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.