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

Python 爬虫模拟登陆的一些问题

  •  
  •   Huayx9 · 2016-07-30 10:59:04 +08:00 · 4772 次点击
    这是一个创建于 2827 天前的主题,其中的信息可能已经有所发展或是发生改变。

    import Requests

    有三个 url ,登陆页面,表单提交页面,登陆返回页面

    首先浏览器过程如下:

    1.登陆要输入验证码,验证码在登陆页面显示

    2.输入登录信息之后, post 表单到表单提交页面

    3.然后页面跳转到登陆返回页面,也就是我要抓取的页面

    我用爬虫模拟登陆,然后抓取登陆返回页面的信息

    requests.get 登陆页面,然后提取页面中的验证码链接,但是验证码链接刷新,验证码就会变化

    验证码页面 http://ah.189.cn/sso/VImage.servlet?random=0.17272478651825085 (参数在登陆页面是会变化的)

    requests.port 表单提交页面(验证码,我通过 ocr 验证码图片来解决)

    我现在有三个个问题:

    • 我提取到的验证码能否 post 成功(不能保证是否同步)?
    • requests 这三个页面,带的 cookies 和 headers 是否相同?
    • 用之前 post 过程中的 cookies 和 headers 来直接抓取登陆返回页面?

    谢谢

    29 条回复    2016-09-11 10:45:17 +08:00
    raycool
        1
    raycool  
       2016-07-30 11:32:09 +08:00   ❤️ 1
    1.可以成功,试一下就知道了,需要 cookies
    2.cookies 和 header 可以看作相同, cookies 那一点对于这个问题不用纠结
    3.是的,可以直接抓取
    Huayx9
        2
    Huayx9  
    OP
       2016-07-30 11:54:34 +08:00 via iPhone
    @raycool 十分感谢
    aeshfawre
        3
    aeshfawre  
       2016-07-30 11:57:08 +08:00   ❤️ 1
    楼主是想做业务处理软件吧,多年前我也做过,想不到现在还有市场.
    这个简单的验证码,用点阵位置模版来识别,编译型语言可以 1 毫秒内识别出来.
    你的三个问题很简单:
    1:可能你没研究清楚网站交互过程的,你 get 验证码的时候,服务器后台会将这验证码和 cookie 绑定,你只要用这个 cookie 去提交,验证码就是对的.
    2:requests.Session(), 研究下这个
    3:requests.Session()
    jackyspy
        4
    jackyspy  
       2016-07-30 15:05:58 +08:00   ❤️ 1
    requests 自动处理 cookies
    Huayx9
        5
    Huayx9  
    OP
       2016-07-30 16:18:23 +08:00 via iPhone
    @aeshfawre 我就是做一个批查询的脚本,查询账号信息。
    但是账号要登录,还有验证码。
    谢谢详细解答, rerequests.sessession()我知道。
    开始将请求验证码的 headerers 和 cookies 装到 session 中来请求验证码,然后用这个 session 来 post ,然后再直接 get 登陆后的 URL 。
    这样保持都是同一个 session ?
    prasanta
        6
    prasanta  
       2016-07-30 16:26:53 +08:00   ❤️ 1
    建议直接从浏览器中复制 cookie 放到 requests 请求的 headers 里面。这样就不用去纠结登陆的问题了。
    aeshfawre
        7
    aeshfawre  
       2016-07-30 16:28:01 +08:00   ❤️ 1
    @Huayx9 httpdebugger 我以前研究都是用这个软件,你点击浏览器发生了什么 http 数据,都看在眼里.
    用 python 模拟浏览器,你只需要对比下你代码执行的时候发出和接收的 http,与浏览器有什么区别.
    就知道怎么修改代码了.
    Huayx9
        8
    Huayx9  
    OP
       2016-07-30 16:29:50 +08:00 via iPhone
    @prasanta 但还是要输入验证码,我试过的。。
    Huayx9
        9
    Huayx9  
    OP
       2016-07-30 16:30:20 +08:00 via iPhone
    @jackyspy cookie 要自己传入呀
    Huayx9
        10
    Huayx9  
    OP
       2016-07-30 16:31:53 +08:00 via iPhone
    @aeshfawre 好的,谢谢。
    确实对 http 交互不太熟悉,就是不知道怎么用代码模仿浏览器打开操作。
    prasanta
        11
    prasanta  
       2016-07-30 16:39:34 +08:00   ❤️ 1
    @Huayx9 cookie 的格式要正确,可以用 http://httpbin.org/cookie 接口来测试你的 cookie
    prasanta
        12
    prasanta  
       2016-07-30 16:40:12 +08:00   ❤️ 1
    Huayx9
        13
    Huayx9  
    OP
       2016-07-30 16:44:47 +08:00 via iPhone
    @prasanta 嗯,格式是字典格式
    prasanta
        14
    prasanta  
       2016-07-30 16:47:41 +08:00   ❤️ 1
    我喜欢直接放到 header 的 cookie 字段里面,字符串格式。
    prasanta
        15
    prasanta  
       2016-07-30 16:58:36 +08:00   ❤️ 1
    我的意思是使用登录后的 cookie 直接访问目标页面就可以了。不需要再考虑登录的问题。
    Huayx9
        16
    Huayx9  
    OP
       2016-07-30 17:07:51 +08:00 via iPhone
    @prasanta 那就不单独传入 cookie ,直接全都放 header 里
    Huayx9
        17
    Huayx9  
    OP
       2016-07-30 17:08:30 +08:00 via iPhone
    @prasanta 可是那样子还是要验证码。。
    Arnie97
        18
    Arnie97  
       2016-07-30 17:10:37 +08:00 via Android   ❤️ 1
    @Huayx9 加载验证码、提交表单、抓去页面都用同一个 requests session 既可,相当于同一个浏览器标签访问这三处,不需要特意处理 Cookies 问题
    Huayx9
        19
    Huayx9  
    OP
       2016-07-30 17:37:37 +08:00 via iPhone
    @Arnie97 可是,登录之前和登录之后的 cookie 肯定是不同的呀。登录之后的应该有账号信息。
    aeshfawre
        20
    aeshfawre  
       2016-07-30 18:14:00 +08:00   ❤️ 1
    Huayx9
        21
    Huayx9  
    OP
       2016-07-30 18:28:37 +08:00 via iPhone
    @aeshfawre 。。。要哭了,不过,我自己摸着石头走了一段路
    jackyspy
        22
    jackyspy  
       2016-07-30 19:17:53 +08:00   ❤️ 1
    @Huayx9 不需要自己手工管理 cookie
    ```
    import requests
    s = requests.session()
    print(s.get('http://httpbin.org/cookies').json())
    s.get('http://httpbin.org/cookies/set?sessionid=abcdefg')
    print(s.get('http://httpbin.org/cookies').json())
    ```
    Output
    ```
    {'cookies': {}}
    {'cookies': {'sessionid': 'abcdefg'}}
    ```
    Huayx9
        23
    Huayx9  
    OP
       2016-07-31 10:13:32 +08:00 via iPhone
    @jackyspy 昨晚折腾了好久, cookie 终于弄明白了。

    可是登录 post 表单到一个接收页面, post 和获取验证码带的都是之前的 cookies (初始化)。

    在浏览器下,显示是登录之后跳转到之后的页面, header 是带上新的 cookie (登录成功)来 get 的。

    但是代码在 post 之后,从哪儿得到登录成功的 cookie 。。
    eoo
        24
    eoo  
       2016-07-31 11:39:50 +08:00   ❤️ 1
    后面的 random 其实就是 JS 的函数 Mate.random()产生的 0-1 的随机数 服务端不做验证的 只是为了防止浏览器缓存
    Huayx9
        25
    Huayx9  
    OP
       2016-07-31 22:30:35 +08:00
    @eoo 这个我明白,登陆之前的问题都解决了,但是现在不知道该怎么得到 post 过程中和登陆成功之后的 cookies
    aeshfawre
        26
    aeshfawre  
       2016-07-31 22:34:51 +08:00
    @Huayx9 所以让你研究 Seesion(), 这个功能就是帮你处理了 cookie 的所有事情,也就是不需要考虑 cookie 的问题的.
    登录成功之后服务器会在返回的数据包中给你 cookie,而这个返回的 cookie 会自动被 requests 处理好,存放起来的,你后面继续 get,post,这 cookie 会自动帮你加上的.
    eoo
        27
    eoo  
       2016-07-31 23:06:46 +08:00 via Android
    @eoo 抓包就知道啊
    jackyspy
        28
    jackyspy  
       2016-08-01 08:08:17 +08:00
    @Huayx9 估计你不是用的同一个 session 。

    PS :提问最好附带能提现问题的可运行简易代码段
    mingyun
        29
    mingyun  
       2016-09-11 10:45:17 +08:00
    requests.get(url, headers=header,cookies=cookies)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2935 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 13:53 · PVG 21:53 · LAX 06:53 · JFK 09:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.