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

scrapy 自动登录后保存 cookie,过段时间登出了

  •  
  •   liyj144 ·
    liyj144 · 2016-08-28 23:08:57 +08:00 · 6090 次点击
    这是一个创建于 3009 天前的主题,其中的信息可能已经有所发展或是发生改变。

    登陆部分写在 start_requests 函数中,然后保存登陆的 cookie 信息( scrapy 会自动把 cookie 信息保存下来),这时可以正常抓取其他页面。但是大约 2 个小时后,应该 session 会过期,这时页面访问就不正常了,但是这时如果直接在 parse 函数中回调 start_requests 不起作用(代码为: return [Request("xxx",callback=self.start_requests)],可以进入 start_requests 函数,但是不能像初始化时一样执行登陆操作)。求解,谢谢。

    5 条回复    2016-08-29 12:27:44 +08:00
    Yc1992
        1
    Yc1992  
       2016-08-29 00:04:38 +08:00
    自己挂个本地代理抓包看看
    liyj144
        2
    liyj144  
    OP
       2016-08-29 09:01:10 +08:00
    @Yc1992 一段时间后 session 确实是过期的,这时按理应该重新出发登陆机制。但是不知道 scrapy 中在 parse 函数中如何重新调用 start_requests 进行初始化登陆操作。
    laoyur
        3
    laoyur  
       2016-08-29 09:23:01 +08:00
    def start_requests(self):
    def parse(self, response):
    要回调也是回调 parse 方法啊,为何要去回调 start_requests ? start_requests 是爬虫启动的时候自动调的
    在 parse 里面判断页面状态是已登录还是未登录,各自做不同的操作呗
    liyj144
        4
    liyj144  
    OP
       2016-08-29 11:45:42 +08:00
    @laoyur 多谢,确实应该是回调 parse 方法。但是现在遇到另外一个问题:在回调重新登陆的 parse 方法如何更改 request 的 url 。现在代码结构为:

    # 重新触发登陆
    def re_login(self, reponse):
    response = response.request.replace(url=login_page)
    return [FormRequest.from_response(response,url="xxxx", formdata={xxx})] # 标记 1

    # 分析页面元素并保存,如果页面上登陆标识不存在,报异常并触发 re_login
    def parse_item(self, response):
    try:
    # download and parse page, when logout , check function raise IndexError exception
    except IndexError:
    self.log("------ start to login again ------")
    self.post_login(response)

    按照这种方法,可以正常执行到标记 1 处,在标记 1 处 request.url 是请求 item 的 url , 不是 login 页面的 url ,于是会报 from 找不到的错误。 通过 response.replace 方法更改 url 和 body 的值后请求未能成功。怀疑是 replace 那个方法用的有问题,暂时还没找到解决办法。有没有前辈遇到过相似问题?谢谢。
    laoyur
        5
    laoyur  
       2016-08-29 12:27:44 +08:00
    def parse_item(self, response):
    看你的描述,一旦爬 item 失败后,服务端并不会重定向到登录页面,也就是说 parse_item 这个方法传入的 response 中不包含登录的表单。那也好办啊,显式地在爬 item 失败后爬一下登录页面就是了,反正 url 都是固定的,你写死即可,回来后你再用 FormRequest.from_response 来登录即可
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2396 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:06 · PVG 00:06 · LAX 08:06 · JFK 11:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.