1. # http://docs.python-requests.org/zh_CN/latest/
    2. """
    3. Blocking Or Non-Blocking? With the default Transport Adapter in place, Requests does not provide any kind of non-blocking IO. The Response.content property will block until the entire response has been downloaded. If you require more granularity, the streaming features of the library (see Streaming Requests) allow you to retrieve smaller quantities of the response at a time. However, these calls will still block. If you are concerned about the use of blocking IO, there are lots of projects out there that combine Requests with one of Python’s asynchronicity frameworks. Some excellent examples are requests-threads, grequests, and requests-futures.
    4. 阻塞和非阻塞 使用默认的传输适配器,Requests 不提供任何形式的非阻塞 IO。 Response.content 属性会阻塞,直到整个响应下载完成。 如果你需要更多精细控制,该库的数据流功能(见流式请求)允许你每次接受少量的一部分响应,不过这些调用依然是阻塞式的。 如果你对于阻塞式 IO 有所顾虑,还有很多项目可以供你使用,它们结合了 Requests 和 Python 的某个异步框架。 典型的优秀例子是 grequests 和 requests-futures。
    5. """
    6. N = 5
    7. import requests
    8. def f():
    9. sess = requests.session()
    10. p = sess.get('http://www.baidu.com')
    11. sess.close()
    12. for i in range(N):
    13. %time f()
    14. # CPU times: user 5.25 ms, sys: 885 µs, total: 6.13 ms
    15. # Wall time: 28.9 ms
    16. # CPU times: user 3.03 ms, sys: 4 µs, total: 3.04 ms
    17. # Wall time: 38.6 ms
    18. # CPU times: user 2.43 ms, sys: 0 ns, total: 2.43 ms
    19. # Wall time: 33.2 ms
    20. # CPU times: user 2.37 ms, sys: 29 µs, total: 2.4 ms
    21. # Wall time: 41.2 ms
    22. # CPU times: user 2.52 ms, sys: 0 ns, total: 2.52 ms
    23. # Wall time: 39.2 ms
    24. import requests
    25. sess = requests.session()
    26. for i in range(N):
    27. %time p = sess.get('http://www.baidu.com')
    28. sess.close()
    29. # CPU times: user 1.68 ms, sys: 1.81 ms, total: 3.49 ms
    30. # Wall time: 28.4 ms
    31. # CPU times: user 2.79 ms, sys: 0 ns, total: 2.79 ms
    32. # Wall time: 15.4 ms
    33. # CPU times: user 2.46 ms, sys: 68 µs, total: 2.53 ms
    34. # Wall time: 15.8 ms
    35. # CPU times: user 2.36 ms, sys: 132 µs, total: 2.49 ms
    36. # Wall time: 15.7 ms
    37. # CPU times: user 2.17 ms, sys: 127 µs, total: 2.3 ms
    38. # Wall time: 15.3 ms
    39. import requests
    40. import json
    41. sess = requests.session()
    42. for i in range(N):
    43. %time sess.get('http://www.baidu.com')
    44. sess.close()
    45. # CPU times: user 3.58 ms, sys: 83 µs, total: 3.66 ms
    46. # Wall time: 26.7 ms
    47. # CPU times: user 2.35 ms, sys: 48 µs, total: 2.39 ms
    48. # Wall time: 15.2 ms
    49. # CPU times: user 2.21 ms, sys: 451 µs, total: 2.66 ms
    50. # Wall time: 16.4 ms
    51. # CPU times: user 2.5 ms, sys: 108 µs, total: 2.61 ms
    52. # Wall time: 15.5 ms
    53. # CPU times: user 2.58 ms, sys: 0 ns, total: 2.58 ms
    54. # Wall time: 15.8 ms
    55. import grequests
    56. tasks = []
    57. for i in range(N):
    58. %time grequests.get('http://www.baidu.com')
    59. grequests.map(tasks, size=4)
    60. # CPU times: user 126 µs, sys: 18 µs, total: 144 µs
    61. # Wall time: 149 µs
    62. # CPU times: user 74 µs, sys: 0 ns, total: 74 µs
    63. # Wall time: 77.2 µs
    64. # CPU times: user 57 µs, sys: 9 µs, total: 66 µs
    65. # Wall time: 69.9 µs
    66. # CPU times: user 64 µs, sys: 0 ns, total: 64 µs
    67. # Wall time: 67.7 µs
    68. # CPU times: user 61 µs, sys: 0 ns, total: 61 µs
    69. # Wall time: 65.1 µs
    70. """
    71. /data/soft/py3/lib/python3.6/site-packages/grequests.py:21: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016
    72. curious_george.patch_all(thread=False, select=False)
    73. []
    74. By default a ThreadPoolExecutor is created with 2 workers. If you would like to adjust that value or share a executor across multiple sessions you can provide one to the FuturesSession constructor. from concurrent.futures import ThreadPoolExecutor from requests_futures.sessions import FuturesSession
    75. session = FuturesSession(executor=ThreadPoolExecutor(max_workers=10))
    76. ...
    77. As a shortcut in case of just increasing workers number you can pass max_workers straight to the FuturesSession constructor: from requests_futures.sessions import FuturesSession
    78. session = FuturesSession(max_workers=10)
    79. FutureSession will use an existing session object if supplied:
    80. from requests import session
    81. from requests_futures.sessions import FuturesSession
    82. my_session = session()
    83. future_session = FuturesSession(session=my_session)
    84. That's it. The api of requests.Session is preserved without any modifications beyond returning a Future rather than Response. As with all futures exceptions are shifted (thrown) to the future.result() call so try/except blocks should be moved there. `
    85. """
    86. from requests import session
    87. from requests_futures.sessions import FuturesSession
    88. my_session = session()
    89. sess = FuturesSession(session = my_session)
    90. for i in range(N):
    91. %time sess.get('http://www.baidu.com')
    92. sess.close()
    93. # CPU times: user 2.56 ms, sys: 945 µs, total: 3.51 ms
    94. # Wall time: 3.2 ms
    95. # CPU times: user 1.24 ms, sys: 32 µs, total: 1.27 ms
    96. # Wall time: 1.18 ms
    97. # CPU times: user 44 µs, sys: 0 ns, total: 44 µs
    98. # Wall time: 49.6 µs
    99. # CPU times: user 28 µs, sys: 0 ns, total: 28 µs
    100. # Wall time: 31.5 µs
    101. # CPU times: user 23 µs, sys: 4 µs, total: 27 µs
    102. # Wall time: 30.3 µs