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

获取验证码是单独的 url, 那么每次的请求怎么能与验证码同步

  •  
  •   wsds · 2018-08-20 16:36:12 +08:00 · 4618 次点击
    这是一个创建于 2322 天前的主题,其中的信息可能已经有所发展或是发生改变。

    This is an example link

    这是获取验证码连接

    没有任何参数,怎么确保每次的查询,才能对应上这个验证码呢?

    第 1 条附言  ·  2018-08-20 20:01:46 +08:00
    不是说用 session 能保持前后访问一致嘛,写爬虫碰到随机验证码,想把它下载下来手动输入,但是下载验证码图片后再访问,验证码又变了,登陆不上去........怎么样才能保证下载的验证码和下次请求的一致呢

    https://bbs.csdn.net/topics/392217434
    30 条回复    2018-08-21 11:26:51 +08:00
    WildCat
        1
    WildCat  
       2018-08-20 16:38:17 +08:00
    cookies / session?
    zhoulv2012
        2
    zhoulv2012  
       2018-08-20 16:54:12 +08:00 via Android
    我处理过的是,同一 session 去访问 example link,然后再去访问验证码,这就就等于刷新了验证码
    harde
        3
    harde  
       2018-08-20 16:54:15 +08:00
    通常的做法是 session 保存。
    wsds
        4
    wsds  
    OP
       2018-08-20 16:56:36 +08:00
    requests.Session().get("http://www.cszjw.net/newCaptcha")获取的验证码,始终与 example link 不同步,不知道为什么
    wangxiaoaer
        5
    wangxiaoaer  
       2018-08-20 16:56:40 +08:00 via Android
    说 session 存储的,如果是集群部署,同时没有 ip 固定的策略怎么处理?
    crab
        6
    crab  
       2018-08-20 16:58:14 +08:00
    响应头:Set-Cookie
    wangxiaoaer
        7
    wangxiaoaer  
       2018-08-20 17:03:00 +08:00 via Android
    @crab 把验证码放 Cookie 中,你认真的吗?
    bk201
        8
    bk201  
       2018-08-20 17:20:44 +08:00
    http://www.cszjw.net/newCaptcha?r=0.37396028425505023
    ====
    这个不是参数?
    ===
    用 session 方式感觉真古老
    beforeuwait
        9
    beforeuwait  
       2018-08-20 17:21:55 +08:00
    要同一个 session 啊
    wangxiaoaer
        10
    wangxiaoaer  
       2018-08-20 17:24:45 +08:00 via Android
    @wangxiaoaer 不好意思,我脑子短路了,集群下的 session 也可以集中存储。
    dbw9580
        11
    dbw9580  
       2018-08-20 17:34:12 +08:00 via Android
    @wangxiaoaer 集中储存就会成为瓶颈哦
    Junwwwww
        12
    Junwwwww  
       2018-08-20 17:42:54 +08:00
    明明带了一个参数
    wsds
        13
    wsds  
    OP
       2018-08-20 17:44:03 +08:00
    @bk201
    @Junwwwww
    那怎么同步这个验证码呢
    lcy630409
        14
    lcy630409  
       2018-08-20 17:49:15 +08:00
    你是要用网页的形式代替 api 么?是的话 记录号 cookie 就行了,服务端根据 cookie 就会认为你是同一个人,同一个人的验证码会覆盖的,永远是最后获取的那个
    wangxiaoaer
        15
    wangxiaoaer  
       2018-08-20 17:50:40 +08:00 via Android
    @dbw9580 可以再弄个 sessions 的集群啊,只是 sessions 的出入口唯一就行了。
    passerbytiny
        16
    passerbytiny  
       2018-08-20 18:08:01 +08:00
    理论依据:HTTP 单次访问是无状态的,但 HTTP 连续访问是有会话状态的;会话状态由服务器保存;只要能够保证获取验证码、使用验证码这两个请求处于同一个会话,那么验证码就是可以验证的。

    HTTP 会话状态是 OSI 第七层应用层独立管理的事,跟第四层传输层 TCP 连接没有任何关系。

    HTTP 会话跟踪原理:首次连接服务器生成唯一标识,并且通知客户端;后续连接,客户端都带上该标识;服务器根据唯一标识,判断是否属于同一个会话。唯一标识由服务器生成和校验,客户端只能够暂存和传递,所以该会话是完全由服务器控制的。

    HTTP 会话 Cookie 实现方式:服务器通过 set-cookie 将唯一标识通知给客户端,一般都会制定 cookie 的有效期是内存级别,级浏览器关了 cookie 就没了。

    HTTP 会话 URL 重写实现方式:服务器通过 URL 重定向将唯一标识通知给客户端,唯一标识就在新的 URL 地址上,客户端不保存唯一标识,但后续的所有请求的 URL 地址中,都回带上唯一标识。此方式很容易失效。

    以上两种,只是传统的实现方式,并不是唯一的。你完全可以抛开浏览器和服务器框架,自己实现会话跟踪。例如:如果服务器愿意,浏览器可以通过 H5 的 web 存储暂存唯一标识;服务器也可以抛开语言框架,自己写业务代码,用 redis 或者独立服务管理唯一标识(此时集群就不是事了)。甚至,经服务器允许后,多个客户端通过共享唯一标识,也可以共享会话;当然会话管理服务器、验证码服务器、业务服务器也可以是不同的服务器。
    crab
        17
    crab  
       2018-08-20 18:41:47 +08:00
    @wangxiaoaer 我是说响应回来的新 cookies 里面可以对应上
    wangxiaoaer
        18
    wangxiaoaer  
       2018-08-20 19:43:01 +08:00
    @crab #17 客户端从 cookie 里面读取出验证码不就直接发过去了吗?
    Trim21
        19
    Trim21  
       2018-08-20 19:58:24 +08:00 via Android
    @wangxiaoaer 可以加密…= =
    wsds
        20
    wsds  
    OP
       2018-08-20 21:29:42 +08:00 via iPhone
    搞不定球,日了狗🐶
    joyfun
        21
    joyfun  
       2018-08-20 21:41:22 +08:00 via Android
    @wangxiaoaer cookies 存的只是验证码的序号,key 呀,验证的是 value
    aru
        22
    aru  
       2018-08-20 21:52:03 +08:00
    @wsds
    1. 创建 session 对象
    2. 请求一次查询页面
    3. 请求验证码页面,识别出验证码
    4. post 请求

    每次请求验证码相当于刷新验证码,别重复请求!
    xiangyuecn
        23
    xiangyuecn  
       2018-08-20 21:54:12 +08:00
    围观楼上诸位大佬扯淡 (doge,极其普通的验证码也能扯上这么多 (滑稽

    @wsds 你下载完了之后要保证后面访问页面的时候不会再次请求验证码这个地址,访问页面时候把验证码图片请求拦截干掉,验证码就不会变动了。。跟 session 什么的鬼东西一毛钱关系都没有,那是后端的玩意,跟请求跟页面有一毛钱关系,亏楼上还讨论的这么津津有味


    或者你换一个方法,不要下载验证码,先访问页面,把验证码区域截个图然后获得验证码图片,还更简单粗暴可靠叼炸天
    crab
        24
    crab  
       2018-08-20 21:56:21 +08:00
    @wsds 你只要明白一点,每一次请求验证码,cookies 都会更新一次回来,你只要输入最后一次请求看到的验证码以及提交正确的 cookies 就行。
    t6attack
        25
    t6attack  
       2018-08-20 22:05:27 +08:00
    @wangxiaoaer 验证码可以放 cookie。只要保证 用户自己还原不出来、而服务端可以还原出来 就行了。discuz 里有个函数叫 authcode(),就能解决这个问题。
    opengps
        26
    opengps  
       2018-08-20 22:06:38 +08:00
    session 在客户端的表现,其实是 cookie 里存了一个 id,所以你只需要带上 cookie 信息就会被服务器识别成同一个回话
    ooTwToo
        27
    ooTwToo  
       2018-08-21 00:38:02 +08:00 via iPhone
    简单,约定下 key,存 redis
    agagega
        28
    agagega  
       2018-08-21 00:51:16 +08:00 via iPhone
    session 可以用 cookie 存呀,加密就行了。Rails 默认就这么搞的
    zsdroid
        29
    zsdroid  
       2018-08-21 11:20:39 +08:00
    session_id 了解下
    下载验证码时要同时保存 cookie,下次提交时要提交保存的 cookie
    wsds
        30
    wsds  
    OP
       2018-08-21 11:26:51 +08:00
    @zsdroid 我就是这种操作,仍不行啊
    下载验证码到本地并获取 cookies
    r = requests.get("获取验证码连接")
    urllib.request.urlretrieve(r.url, "./a.jpg")
    self.cookies = dict(r.cookies)
    ==========================
    查询时,添加下载验证码的 cookies
    r = requests.Session().post("查询链接",data=self.data, cookies=self.cookies)
    print(self.data)
    r.encoding = "utf-8"
    print(r.text)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2274 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:46 · PVG 09:46 · LAX 17:46 · JFK 20:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.