You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python模拟Web交互时PHPSESSID Cookie缺失问题及修复

我有一段PHP页面代码:

<?php session_start(); ?>
<html>
<body>
<?php echo '<!-- cookies -->'; foreach($_COOKIE as $k => $v) { echo '<!-- ' . $k . '=>' . $v . ' -->'; } ?>
</body>
</html>

通过浏览器访问https://daley.ws/file1.php时,页面源码显示包含PHPSESSID Cookie:

<html>
<body>
<!-- cookies --><!-- PHPSESSID=>22u20jsi288vtk5epser56d2bn7leb6n --></body>
</html>

但我在Mac上运行以下Python代码时:

#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
import urllib.request
REQ_HOST = "daley.ws"
DALEY_WS = 'https://daley.ws'
DALEY_WS_FILE1 = '{}/file1.php'.format(DALEY_WS)
DALEY_WS_FILE2 = '{}/file2.php'.format(DALEY_WS)
if __name__ == "__main__":
    print(DALEY_WS_FILE1)
    req = urllib.request.Request(DALEY_WS_FILE1,\
unverifiable=True, origin_req_host=REQ_HOST,\
method='POST')
    with urllib.request.urlopen(req) as response:
        data = response.read().decode()
        print('data: {}'.format(data))

得到的输出里没有PHPSESSID:

https://daley.ws/file1.php
data: <html>
<body>
<!-- cookies --></body>
</html>

想请教为什么PHPSESSID Cookie没出现?怎么修改Python代码才能获取正确的输出?


原因分析

这事儿其实是会话Cookie的生成和传递逻辑在搞怪:

  • 你用浏览器访问时,大概率之前已经和这个站点打过交道,浏览器本地已经保存了PHPSESSID Cookie,所以这次请求会自动把Cookie带过去,PHP的$_COOKIE数组就能读到它,自然页面输出里就有了。
  • 而你的Python请求是完全全新的无状态请求,没有携带任何Cookie过去。这时候PHP执行session_start()时,发现请求里没有PHPSESSID,就会生成一个新的会话ID,但这个ID是通过响应头的Set-Cookie字段返回给你的,并不会出现在当前请求的$_COOKIE数组里——毕竟$_COOKIE存的是这次请求客户端发过来的内容,不是服务器刚生成的内容。

解决方案

要让Python请求能拿到包含PHPSESSID的页面输出,核心就是要让后续请求带上服务器生成的Cookie。咱们可以用Python的http.cookiejar来自动管理Cookie,它会帮你保存服务器返回的Cookie,下次请求自动带上。

修改后的代码如下:

#!/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
import urllib.request
from http.cookiejar import CookieJar

REQ_HOST = "daley.ws"
DALEY_WS = 'https://daley.ws'
DALEY_WS_FILE1 = '{}/file1.php'.format(DALEY_WS)

if __name__ == "__main__":
    # 创建CookieJar对象来自动管理Cookie
    cookie_jar = CookieJar()
    # 构建带Cookie处理能力的请求器
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie_jar))
    
    # 第一次请求:获取服务器生成的PHPSESSID并保存
    print("第一次请求(无Cookie):")
    req = urllib.request.Request(DALEY_WS_FILE1, method='POST')
    with opener.open(req) as response:
        data = response.read().decode()
        print('data: {}'.format(data))
        # 可以查看服务器返回的Set-Cookie头,这里就能看到刚生成的PHPSESSID
        print('服务器返回的Cookie:', response.getheader('Set-Cookie'))
    
    # 第二次请求:自动携带保存的Cookie访问
    print("\n第二次请求(带Cookie):")
    req2 = urllib.request.Request(DALEY_WS_FILE1, method='POST')
    with opener.open(req2) as response2:
        data2 = response2.read().decode()
        print('data: {}'.format(data2))

代码说明:

  1. CookieJar负责存储服务器返回的Cookie;
  2. build_opener创建的请求器会自动处理Cookie的收发,第二次请求时会自动带上之前保存的PHPSESSID;
  3. 第二次请求时,PHP收到你带过去的PHPSESSID,$_COOKIE数组里就会包含这个ID,页面输出也就和浏览器访问的结果一致了。

如果你的需求是只发一次请求就看到PHPSESSID,那其实做不到——因为$_COOKIE只能读取本次请求客户端发送的内容,而PHPSESSID是服务器在这次响应中才生成的,不会出现在本次请求的输出里。浏览器能看到是因为它之前已经保存了Cookie,不是第一次访问的结果哦。


内容的提问来源于stack exchange,提问作者AixNPanes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:59:09