test_httpx_vs_curl.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. """
  2. 对比 curl 和 httpx 访问 CDP 端点
  3. 找出为什么 httpx 会失败
  4. """
  5. import subprocess
  6. import time
  7. import httpx
  8. import asyncio
  9. def start_chrome():
  10. """启动 Chrome"""
  11. proc = subprocess.Popen([
  12. '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
  13. '--headless=new',
  14. '--remote-debugging-port=9222',
  15. '--user-data-dir=/tmp/httpx-test-cdp',
  16. 'about:blank'
  17. ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
  18. print("等待 Chrome 启动...")
  19. time.sleep(3)
  20. return proc
  21. async def test_httpx_default():
  22. """测试 httpx 默认配置"""
  23. print("\n【测试 1】httpx 默认配置")
  24. print("="*60)
  25. try:
  26. async with httpx.AsyncClient() as client:
  27. print("发送请求...")
  28. resp = await client.get('http://localhost:9222/json/version')
  29. print(f"✅ 成功: {resp.status_code}")
  30. print(f"内容: {resp.text[:100]}")
  31. return True
  32. except Exception as e:
  33. print(f"❌ 失败: {e}")
  34. return False
  35. async def test_httpx_long_timeout():
  36. """测试 httpx 长超时"""
  37. print("\n【测试 2】httpx 长超时 (30秒)")
  38. print("="*60)
  39. try:
  40. async with httpx.AsyncClient(timeout=30.0) as client:
  41. print("发送请求...")
  42. resp = await client.get('http://localhost:9222/json/version')
  43. print(f"✅ 成功: {resp.status_code}")
  44. print(f"内容: {resp.text[:100]}")
  45. return True
  46. except Exception as e:
  47. print(f"❌ 失败: {e}")
  48. return False
  49. async def test_httpx_no_proxy():
  50. """测试 httpx 禁用代理"""
  51. print("\n【测试 3】httpx 禁用代理")
  52. print("="*60)
  53. try:
  54. # 明确禁用代理
  55. async with httpx.AsyncClient(
  56. timeout=30.0,
  57. proxies={} # 空字典表示不使用代理
  58. ) as client:
  59. print("发送请求...")
  60. resp = await client.get('http://localhost:9222/json/version')
  61. print(f"✅ 成功: {resp.status_code}")
  62. print(f"内容: {resp.text[:100]}")
  63. return True
  64. except Exception as e:
  65. print(f"❌ 失败: {e}")
  66. return False
  67. async def test_httpx_trust_env_false():
  68. """测试 httpx trust_env=False"""
  69. print("\n【测试 4】httpx trust_env=False (忽略环境变量)")
  70. print("="*60)
  71. try:
  72. # trust_env=False 会忽略环境变量中的代理设置
  73. async with httpx.AsyncClient(
  74. timeout=30.0,
  75. trust_env=False
  76. ) as client:
  77. print("发送请求...")
  78. resp = await client.get('http://localhost:9222/json/version')
  79. print(f"✅ 成功: {resp.status_code}")
  80. print(f"内容: {resp.text[:100]}")
  81. return True
  82. except Exception as e:
  83. print(f"❌ 失败: {e}")
  84. return False
  85. async def main():
  86. print("httpx vs curl 对比测试")
  87. print("="*60)
  88. # 启动 Chrome
  89. proc = start_chrome()
  90. # 运行测试
  91. results = {
  92. 'default': await test_httpx_default(),
  93. 'long_timeout': await test_httpx_long_timeout(),
  94. 'no_proxy': await test_httpx_no_proxy(),
  95. 'trust_env_false': await test_httpx_trust_env_false(),
  96. }
  97. # 清理
  98. print("\n清理...")
  99. proc.terminate()
  100. proc.wait(timeout=5)
  101. subprocess.run(['rm', '-rf', '/tmp/httpx-test-cdp'],
  102. stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
  103. # 总结
  104. print("\n" + "="*60)
  105. print("测试总结")
  106. print("="*60)
  107. for name, result in results.items():
  108. status = '✅ 成功' if result else '❌ 失败'
  109. print(f"{name:20s}: {status}")
  110. print("="*60)
  111. # 给出建议
  112. if results['trust_env_false'] and not results['default']:
  113. print("\n💡 发现问题:")
  114. print("httpx 默认会读取环境变量中的代理设置")
  115. print("即使关闭了 VPN,环境变量可能仍然存在")
  116. print("\n解决方案:")
  117. print("在 browser-use 初始化时设置 trust_env=False")
  118. if __name__ == "__main__":
  119. asyncio.run(main())