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

这个需求 Python 是不是无法实现?

  •  
  •   Exin · 2015-12-15 22:18:16 +08:00 · 3911 次点击
    这是一个创建于 3264 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个需要 cookie 的页面,需要先登录再进行后续操作。
    我用如下方法可以在单线程下成功。

    cookie = cookielib.CookieJar()
    handler = urllib2.HTTPCookieProcessor(cookie)
    opener = urllib2.build_opener(handler)
    opener.open(loginUrl, loginData).read() #登陆
    opener.open(otherUrl, otherData).read() #后续操作

    Python 多线程似乎不支持写入全局变量,用以下方式, opener 不能写入,因此后续操作不能进行:

    def do(data):
    global opener
    opener.open(otherUrl, data).read()

    cookie = cookielib.CookieJar()
    handler = urllib2.HTTPCookieProcessor(cookie)
    opener = urllib2.build_opener(handler)
    pool = multiprocessing.Pool(processes = 2)
    outputs = pool.map(do, [otherData, otherData]) #do 内进行后续操作
    pool.close()
    pool.join()

    要求:不能在 pool 内登陆。
    Python 是否不能实现这个需求?

    25 条回复    2015-12-17 18:26:00 +08:00
    bdbai
        1
    bdbai  
       2015-12-16 00:10:14 +08:00 via iPhone
    推荐用 requests ,只要共用一个 session 对象即可。
    Tony042
        2
    Tony042  
       2015-12-16 00:11:28 +08:00 via iPhone
    用 asyncio+aiohttp 异步多好
    Exin
        3
    Exin  
    OP
       2015-12-16 00:18:19 +08:00
    @bdbai 这个 session 难道不需要写入么?问题出在多线程不能写入外部变量上
    Exin
        4
    Exin  
    OP
       2015-12-16 00:18:34 +08:00
    @Tony042 没接触过,改天学习一个
    binux
        5
    binux  
       2015-12-16 00:21:58 +08:00
    1. 你的问题是多进程不是多线程 (这里是考点)
    2. windows 的进程不继承全局变量
    Exin
        6
    Exin  
    OP
       2015-12-16 00:28:46 +08:00
    @binux
    噢。。第二点我之前踩过坑,想起来了
    那能实现吗?
    binux
        7
    binux  
       2015-12-16 00:33:25 +08:00   ❤️ 1
    @Exin 用线程啊!
    pynix
        8
    pynix  
       2015-12-16 02:32:53 +08:00
    先登录完再分发 cookies
    shidenggui
        9
    shidenggui  
       2015-12-16 06:33:26 +08:00   ❤️ 1
    这明明就是多进程吧,多线程如下:
    from threading import Thread
    没有特殊理由的话建议使用 requests
    southwolf
        10
    southwolf  
       2015-12-16 07:48:28 +08:00
    不是,你明知道要先登录再进行其他操作,这不明摆着是个顺序执行的事么,还非要用多进程 /多线程干啥?
    Exin
        11
    Exin  
    OP
       2015-12-16 08:10:56 +08:00 via iPhone
    @binux 原来 multiprocessing 是多进程的啊……

    @shidenggui 好的

    @southwolf 我考虑的是多线程共享一个通信(cookie ?我不知道怎么叫) 因为实践证明分别登录会出问题
    southwolf
        12
    southwolf  
       2015-12-16 08:33:19 +08:00   ❤️ 1
    @Exin 存 session 就好了
    mengzhuo
        13
    mengzhuo  
       2015-12-16 08:39:27 +08:00 via iPhone   ❤️ 1
    多进程共同数据的话得在 os.fork 之前
    est
        14
    est  
       2015-12-16 09:07:34 +08:00
    你们啊,看标题总想搞个大新闻
    paw
        15
    paw  
       2015-12-16 10:04:05 +08:00
    从汇编到 C 到 python 等等等 都是图灵等价的。。。
    什么实现不了,只是你不知道
    powergx
        16
    powergx  
       2015-12-16 11:09:19 +08:00
    python 多线程 是假的
    Exin
        17
    Exin  
    OP
       2015-12-16 11:59:55 +08:00
    @paw 我就是说我不知道才来问问有没有啊
    @est 不取个好的标题,哪有人进来
    mengzhuo
        18
    mengzhuo  
       2015-12-16 12:04:50 +08:00
    @powergx

    多线程是假的
    多进程是真家伙!
    9hills
        19
    9hills  
       2015-12-16 12:08:29 +08:00
    看到标题感觉又是一场大战,没想到。。。只是把 process 当成线程了。。。
    Exin
        20
    Exin  
    OP
       2015-12-16 12:09:35 +08:00
    @9hills 那我的目的达到了
    est
        21
    est  
       2015-12-16 12:32:13 +08:00
    python 明明是 os native thread 。还被讹传成假线程了。真应该用 user thread 糊你们一脸。或者不能共享数据的多线程。让你们唧唧歪歪
    nomaka
        22
    nomaka  
       2015-12-16 13:46:29 +08:00   ❤️ 1
    multiprocessing.Manager 可以共享变量
    bdbai
        23
    bdbai  
       2015-12-16 18:18:03 +08:00 via iPhone   ❤️ 1
    @Exin requests 官方文档表示线程安全 *thread* 这个
    cjsoft
        24
    cjsoft  
       2015-12-16 19:15:53 +08:00 via Android   ❤️ 1
    先构建一个 cookiejar ,然后为每个 thread 构建一个 openner ,并 install 之前那个 jar 。这样 cookie 是可以在不同的 openner 之间共享的,值得一试,但是不保证不会出现一些奇怪的问题。
    jamiesun
        25
    jamiesun  
       2015-12-17 18:26:00 +08:00
    不要用多线程,用异步 io
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5196 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:42 · PVG 11:42 · LAX 19:42 · JFK 22:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.