走近 Requests 库。
文章目录
https://requests.readthedocs.io/en/master/
https://kenreitz.org/
wow ~ ~ 恭喜。
环境准备。
安装虚拟环境 ~ pip3 install virtualenv。
geek@ubuntu:~$ pip3 install virtualenv
Collecting virtualenv
Downloading virtualenv-20.0.21-py2.py3-none-any.whl (4.7 MB)
|████████████████████████████████| 4.7 MB 53 kB/s
Collecting distlib<1,>=0.3.0
Downloading distlib-0.3.0.zip (571 kB)
|████████████████████████████████| 571 kB 107 kB/s
Requirement already satisfied: six<2,>=1.9.0 in /usr/lib/python3/dist-packages (from virtualenv) (1.14.0)
Collecting filelock<4,>=3.0.0
Downloading filelock-3.0.12-py3-none-any.whl (7.6 kB)
Collecting appdirs<2,>=1.4.3
Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
Building wheels for collected packages: distlib
Building wheel for distlib (setup.py) ... done
Created wheel for distlib: filename=distlib-0.3.0-py3-none-any.whl size=340427 sha256=226792df5368715c36acf2bf46622fcbb4e0ed505ba013ea5afaf4c22fad1707
Stored in directory: /home/geek/.cache/pip/wheels/eb/4e/d2/a903d4184fb49e4ac06474d65715b129aee13d69f7d227e78e
Successfully built distlib
Installing collected packages: distlib, filelock, appdirs, virtualenv
WARNING: The script virtualenv is installed in '/home/geek/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed appdirs-1.4.4 distlib-0.3.0 filelock-3.0.12 virtualenv-20.0.21
- 查看 virtualenv 参数。
geek@ubuntu:~$ /home/geek/.local/bin/virtualenv --help
usage: virtualenv [--version] [--with-traceback] [-v | -q] [--app-data APP_DATA] [--reset-app-data] [--discovery {builtin}] [-p py] [--creator {builtin,cpython3-posix,venv}] [--seeder {app-data,pip}] [--no-seed]
[--activators comma_sep_list] [--clear] [--system-site-packages] [--symlinks | --copies] [--no-download | --download] [--extra-search-dir d [d ...]] [--pip version] [--setuptools version] [--wheel version] [--no-pip]
[--no-setuptools] [--no-wheel] [--symlink-app-data] [--prompt prompt] [-h]
dest
optional arguments:
--version display the version of the virtualenv package and it's location, then exit
--with-traceback on failure also display the stacktrace internals of virtualenv (default: False)
--app-data APP_DATA a data folder used as cache by the virtualenv (default: /home/geek/.local/share/virtualenv)
--reset-app-data start with empty app data folder (default: False)
-h, --help show this help message and exit
verbosity:
verbosity = verbose - quiet, default INFO, mapping => CRITICAL=0, ERROR=1, WARNING=2, INFO=3, DEBUG=4, NOTSET=5
-v, --verbose increase verbosity (default: 2)
-q, --quiet decrease verbosity (default: 0)
discovery:
discover and provide a target interpreter
--discovery {builtin} interpreter discovery method (default: builtin)
-p py, --python py target interpreter for which to create a virtual (either absolute path or identifier string) (default: /usr/bin/python3)
creator:
options for creator builtin
--creator {builtin,cpython3-posix,venv}
create environment via (builtin = cpython3-posix) (default: builtin)
dest directory to create virtualenv at
--clear remove the destination directory if exist before starting (will overwrite files otherwise) (default: False)
--system-site-packages give the virtual environment access to the system site-packages dir (default: False)
--symlinks try to use symlinks rather than copies, when symlinks are not the default for the platform (default: True)
--copies, --always-copy try to use copies rather than symlinks, even when symlinks are the default for the platform (default: False)
seeder:
options for seeder app-data
--seeder {app-data,pip} seed packages install method (default: app-data)
--no-seed, --without-pip do not install seed packages (default: False)
--no-download, --never-download
pass to disable download of the latest pip/setuptools/wheel from PyPI (default: True)
--download pass to enable download of the latest pip/setuptools/wheel from PyPI (default: False)
--extra-search-dir d [d ...] a path containing wheels the seeder may also use beside bundled (can be set 1+ times) (default: [])
--pip version pip version to install, bundle for bundled (default: latest)
--setuptools version setuptools version to install, bundle for bundled (default: latest)
--wheel version wheel version to install, bundle for bundled (default: latest)
--no-pip do not install pip (default: False)
--no-setuptools do not install setuptools (default: False)
--no-wheel do not install wheel (default: False)
--symlink-app-data symlink the python packages from the app-data folder (requires seed pip>=19.3) (default: False)
activators:
options for activation scripts
--activators comma_sep_list activators to generate - default is all supported (default: bash,cshell,fish,powershell,python,xonsh)
--prompt prompt provides an alternative prompt prefix for this environment (default: None)
config file /home/geek/.config/virtualenv/virtualenv.ini missing (change via env var VIRTUALENV_CONFIG_FILE)
创建环境目录。
geek@ubuntu:~$ /home/geek/.local/bin/virtualenv .env
created virtual environment CPython3.8.2.final.0-64 in 218ms
creator CPython3Posix(dest=/home/geek/.env, clear=False, global=False)
seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/home/geek/.local/share/virtualenv/seed-app-data/v1.0.1)
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
激活虚拟环境。
geek@ubuntu:~/geek/py$ /home/geek/.local/bin/virtualenv .env
created virtual environment CPython3.8.2.final.0-64 in 121ms
creator CPython3Posix(dest=/home/geek/geek/py/.env, clear=False, global=False)
seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/home/geek/.local/share/virtualenv/seed-app-data/v1.0.1)
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
geek@ubuntu:~/geek/py$ ls
ts
geek@ubuntu:~/geek/py$ ls -a
. .. .env ts
geek@ubuntu:~/geek/py$ source .env/
bin/ .gitignore lib/ pyvenv.cfg
geek@ubuntu:~/geek/py$ source .env/bin/activate
(.env) geek@ubuntu:~/geek/py$
(.env) geek@ubuntu:~/geek/py$ pip freeze
(.env) geek@ubuntu:~/geek/py$ pip install requests
Collecting requests
Downloading requests-2.23.0-py2.py3-none-any.whl (58 kB)
|████████████████████████████████| 58 kB 123 kB/s
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
Downloading urllib3-1.25.9-py2.py3-none-any.whl (126 kB)
|████████████████████████████████| 126 kB 147 kB/s
Collecting chardet<4,>=3.0.2
Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
|████████████████████████████████| 133 kB 125 kB/s
Collecting idna<3,>=2.5
Downloading idna-2.9-py2.py3-none-any.whl (58 kB)
|████████████████████████████████| 58 kB 118 kB/s
Collecting certifi>=2017.4.17
Downloading certifi-2020.4.5.1-py2.py3-none-any.whl (157 kB)
|████████████████████████████████| 157 kB 123 kB/s
Installing collected packages: urllib3, chardet, idna, certifi, requests
Successfully installed certifi-2020.4.5.1 chardet-3.0.4 idna-2.9 requests-2.23.0 urllib3-1.25.9
httpbin.org ~ http 请求测试 bin。
0.9.2
[ Base URL: httpbin.org/ ]
A simple HTTP Request & Response Service.
http://httpbin.org/
将 httpbin.org 环境移植到本地。
由于 http.org 站点部署在国外,国内用户访问慢。可以将 http.org 环境移植到本地。
(.env) geek@ubuntu:~/geek/py$ pip install gunicorn httpbin
Collecting gunicorn
Downloading gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
|████████████████████████████████| 77 kB 149 kB/s
Collecting httpbin
Downloading httpbin-0.7.0-py2.py3-none-any.whl (86 kB)
|████████████████████████████████| 86 kB 207 kB/s
Requirement already satisfied: setuptools>=3.0 in ./.env/lib/python3.8/site-packages (from gunicorn) (46.4.0)
Collecting MarkupSafe
Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Collecting itsdangerous
Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting raven[flask]
Downloading raven-6.10.0-py2.py3-none-any.whl (284 kB)
|████████████████████████████████| 284 kB 219 kB/s
Collecting werkzeug>=0.14.1
Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
|████████████████████████████████| 298 kB 188 kB/s
Collecting six
Downloading six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting brotlipy
Downloading brotlipy-0.7.0.tar.gz (413 kB)
|████████████████████████████████| 413 kB 194 kB/s
Collecting Flask
Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
|████████████████████████████████| 94 kB 418 kB/s
Collecting decorator
Downloading decorator-4.4.2-py2.py3-none-any.whl (9.2 kB)
Collecting blinker>=1.1; extra == "flask"
Downloading blinker-1.4.tar.gz (111 kB)
|████████████████████████████████| 111 kB 332 kB/s
Collecting cffi>=1.0.0
Using cached cffi-1.14.0-cp38-cp38-manylinux1_x86_64.whl (409 kB)
Collecting Jinja2>=2.10.1
Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
|████████████████████████████████| 125 kB 384 kB/s
Collecting click>=5.1
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
|████████████████████████████████| 82 kB 347 kB/s
Collecting pycparser
Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Building wheels for collected packages: brotlipy, blinker
Building wheel for brotlipy (setup.py) ... done
Created wheel for brotlipy: filename=brotlipy-0.7.0-cp38-cp38-linux_x86_64.whl size=1008099 sha256=5fbe4fe35ad291cc414db1d3732aa96a438e6254fc03de3d0138870738f5b641
Stored in directory: /home/geek/.cache/pip/wheels/cf/1a/c2/6960e0438c1b79edcee75bc8a2a34e972a93ef5738f8e28e03
Building wheel for blinker (setup.py) ... done
Created wheel for blinker: filename=blinker-1.4-py3-none-any.whl size=13452 sha256=b8d67b3d6400b802bb21c861b2b0e303604f104d4c4cd5e0e23317e474e0bb56
Stored in directory: /home/geek/.cache/pip/wheels/b7/a5/68/fe632054a5eadd531c7a49d740c50eb6adfbeca822b4eab8d4
Successfully built brotlipy blinker
Installing collected packages: gunicorn, MarkupSafe, itsdangerous, blinker, Jinja2, werkzeug, click, Flask, raven, six, pycparser, cffi, brotlipy, decorator, httpbin
Successfully installed Flask-1.1.2 Jinja2-2.11.2 MarkupSafe-1.1.1 blinker-1.4 brotlipy-0.7.0 cffi-1.14.0 click-7.1.2 decorator-4.4.2 gunicorn-20.0.4 httpbin-0.7.0 itsdangerous-1.1.0 pycparser-2.20 raven-6.10.0 six-1.15.0 werkzeug-1.0.1
(.env) geek@ubuntu:~/geek/py$
本地虚拟环境中启动 httpbin。
(.env) geek@ubuntu:~/geek/py$ gunicorn httpbin:app
[2020-06-04 22:27:22 +0800] [4768] [INFO] Starting gunicorn 20.0.4
[2020-06-04 22:27:22 +0800] [4768] [INFO] Listening at: http://127.0.0.1:8000 (4768)
[2020-06-04 22:27:22 +0800] [4768] [INFO] Using worker: sync
[2020-06-04 22:27:22 +0800] [4770] [INFO] Booting worker with pid: 4770
访问本地 8000 端口。
http://127.0.0.1:8000/
HTTP ~ 互联网基石。
HyperText Transfer Protocol。
The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed(分布式), collaborative(协作式), hypermedia information systems(超文本信息系统).[1] HTTP is the foundation of data communication for the World Wide Web, where hypertext documents include hyperlinks to other resources that the user can easily access, for example by a mouse click or by tapping the screen in a web browser.
~wikipedia
curl 命令。
geek@ubuntu:~$ curl --help
Usage: curl [options...] <url>
--abstract-unix-socket <path> Connect via abstract Unix domain socket
--alt-svc <file name> Enable alt-svc with this cache file
--anyauth Pick any authentication method
-a, --append Append to target file when uploading
--basic Use HTTP Basic Authentication
--cacert <file> CA certificate to verify peer against
--capath <dir> CA directory to verify peer against
-E, --cert <certificate[:password]> Client certificate file and password
--cert-status Verify the status of the server certificate
--cert-type <type> Certificate file type (DER/PEM/ENG)
--ciphers <list of ciphers> SSL ciphers to use
--compressed Request compressed response
--compressed-ssh Enable SSH compression
-K, --config <file> Read config from a file
--connect-timeout <seconds> Maximum time allowed for connection
--connect-to <HOST1:PORT1:HOST2:PORT2> Connect to host
-C, --continue-at <offset> Resumed transfer offset
-b, --cookie <data|filename> Send cookies from string/file
-c, --cookie-jar <filename> Write cookies to <filename> after operation
--create-dirs Create necessary local directory hierarchy
--crlf Convert LF to CRLF in upload
--crlfile <file> Get a CRL list in PEM format from the given file
-d, --data <data> HTTP POST data
--data-ascii <data> HTTP POST ASCII data
--data-binary <data> HTTP POST binary data
--data-raw <data> HTTP POST data, '@' allowed
--data-urlencode <data> HTTP POST data url encoded
--delegation <LEVEL> GSS-API delegation permission
--digest Use HTTP Digest Authentication
-q, --disable Disable .curlrc
--disable-eprt Inhibit using EPRT or LPRT
--disable-epsv Inhibit using EPSV
--disallow-username-in-url Disallow username in url
--dns-interface <interface> Interface to use for DNS requests
--dns-ipv4-addr <address> IPv4 address to use for DNS requests
--dns-ipv6-addr <address> IPv6 address to use for DNS requests
--dns-servers <addresses> DNS server addrs to use
--doh-url <URL> Resolve host names over DOH
-D, --dump-header <filename> Write the received headers to <filename>
--egd-file <file> EGD socket path for random data
--engine <name> Crypto engine to use
--etag-save <file> Get an ETag from response header and save it to a FILE
--etag-compare <file> Get an ETag from a file and send a conditional request
--expect100-timeout <seconds> How long to wait for 100-continue
-f, --fail Fail silently (no output at all) on HTTP errors
--fail-early Fail on first transfer error, do not continue
--false-start Enable TLS False Start
-F, --form <name=content> Specify multipart MIME data
--form-string <name=string> Specify multipart MIME data
--ftp-account <data> Account data string
--ftp-alternative-to-user <command> String to replace USER [name]
--ftp-create-dirs Create the remote dirs if not present
--ftp-method <method> Control CWD usage
--ftp-pasv Use PASV/EPSV instead of PORT
-P, --ftp-port <address> Use PORT instead of PASV
--ftp-pret Send PRET before PASV
--ftp-skip-pasv-ip Skip the IP address for PASV
--ftp-ssl-ccc Send CCC after authenticating
--ftp-ssl-ccc-mode <active/passive> Set CCC mode
--ftp-ssl-control Require SSL/TLS for FTP login, clear for transfer
-G, --get Put the post data in the URL and use GET
-g, --globoff Disable URL sequences and ranges using {} and []
--happy-eyeballs-timeout-ms <milliseconds> How long to wait in milliseconds for IPv6 before trying IPv4
--haproxy-protocol Send HAProxy PROXY protocol v1 header
-I, --head Show document info only
-H, --header <header/@file> Pass custom header(s) to server
-h, --help This help text
--hostpubmd5 <md5> Acceptable MD5 hash of the host public key
--http0.9 Allow HTTP 0.9 responses
-0, --http1.0 Use HTTP 1.0
--http1.1 Use HTTP 1.1
--http2 Use HTTP 2
--http2-prior-knowledge Use HTTP 2 without HTTP/1.1 Upgrade
--http3 Use HTTP v3
--ignore-content-length Ignore the size of the remote resource
-i, --include Include protocol response headers in the output
-k, --insecure Allow insecure server connections when using SSL
--interface <name> Use network INTERFACE (or address)
-4, --ipv4 Resolve names to IPv4 addresses
-6, --ipv6 Resolve names to IPv6 addresses
-j, --junk-session-cookies Ignore session cookies read from file
--keepalive-time <seconds> Interval time for keepalive probes
--key <key> Private key file name
--key-type <type> Private key file type (DER/PEM/ENG)
--krb <level> Enable Kerberos with security <level>
--libcurl <file> Dump libcurl equivalent code of this command line
--limit-rate <speed> Limit transfer speed to RATE
-l, --list-only List only mode
--local-port <num/range> Force use of RANGE for local port numbers
-L, --location Follow redirects
--location-trusted Like --location, and send auth to other hosts
--login-options <options> Server login options
--mail-auth <address> Originator address of the original email
--mail-from <address> Mail from this address
--mail-rcpt <address> Mail to this address
-M, --manual Display the full manual
--max-filesize <bytes> Maximum file size to download
--max-redirs <num> Maximum number of redirects allowed
-m, --max-time <seconds> Maximum time allowed for the transfer
--metalink Process given URLs as metalink XML file
--negotiate Use HTTP Negotiate (SPNEGO) authentication
-n, --netrc Must read .netrc for user name and password
--netrc-file <filename> Specify FILE for netrc
--netrc-optional Use either .netrc or URL
-:, --next Make next URL use its separate set of options
--no-alpn Disable the ALPN TLS extension
-N, --no-buffer Disable buffering of the output stream
--no-keepalive Disable TCP keepalive on the connection
--no-npn Disable the NPN TLS extension
--no-progress-meter Do not show the progress meter
--no-sessionid Disable SSL session-ID reusing
--noproxy <no-proxy-list> List of hosts which do not use proxy
--ntlm Use HTTP NTLM authentication
--ntlm-wb Use HTTP NTLM authentication with winbind
--oauth2-bearer <token> OAuth 2 Bearer Token
-o, --output <file> Write to file instead of stdout
-Z, --parallel Perform transfers in parallel
--parallel-immediate Do not wait for multiplexing (with --parallel)
--parallel-max Maximum concurrency for parallel transfers
--pass <phrase> Pass phrase for the private key
--path-as-is Do not squash .. sequences in URL path
--pinnedpubkey <hashes> FILE/HASHES Public key to verify peer against
--post301 Do not switch to GET after following a 301
--post302 Do not switch to GET after following a 302
--post303 Do not switch to GET after following a 303
--preproxy [protocol://]host[:port] Use this proxy first
-#, --progress-bar Display transfer progress as a bar
--proto <protocols> Enable/disable PROTOCOLS
--proto-default <protocol> Use PROTOCOL for any URL missing a scheme
--proto-redir <protocols> Enable/disable PROTOCOLS on redirect
-x, --proxy [protocol://]host[:port] Use this proxy
--proxy-anyauth Pick any proxy authentication method
--proxy-basic Use Basic authentication on the proxy
--proxy-cacert <file> CA certificate to verify peer against for proxy
--proxy-capath <dir> CA directory to verify peer against for proxy
--proxy-cert <cert[:passwd]> Set client certificate for proxy
--proxy-cert-type <type> Client certificate type for HTTPS proxy
--proxy-ciphers <list> SSL ciphers to use for proxy
--proxy-crlfile <file> Set a CRL list for proxy
--proxy-digest Use Digest authentication on the proxy
--proxy-header <header/@file> Pass custom header(s) to proxy
--proxy-insecure Do HTTPS proxy connections without verifying the proxy
--proxy-key <key> Private key for HTTPS proxy
--proxy-key-type <type> Private key file type for proxy
--proxy-negotiate Use HTTP Negotiate (SPNEGO) authentication on the proxy
--proxy-ntlm Use NTLM authentication on the proxy
--proxy-pass <phrase> Pass phrase for the private key for HTTPS proxy
--proxy-pinnedpubkey <hashes> FILE/HASHES public key to verify proxy with
--proxy-service-name <name> SPNEGO proxy service name
--proxy-ssl-allow-beast Allow security flaw for interop for HTTPS proxy
--proxy-tls13-ciphers <list> TLS 1.3 ciphersuites for proxy (OpenSSL)
--proxy-tlsauthtype <type> TLS authentication type for HTTPS proxy
--proxy-tlspassword <string> TLS password for HTTPS proxy
--proxy-tlsuser <name> TLS username for HTTPS proxy
--proxy-tlsv1 Use TLSv1 for HTTPS proxy
-U, --proxy-user <user:password> Proxy user and password
--proxy1.0 <host[:port]> Use HTTP/1.0 proxy on given port
-p, --proxytunnel Operate through an HTTP proxy tunnel (using CONNECT)
--pubkey <key> SSH Public key file name
-Q, --quote Send command(s) to server before transfer
--random-file <file> File for reading random data from
-r, --range <range> Retrieve only the bytes within RANGE
--raw Do HTTP "raw"; no transfer decoding
-e, --referer <URL> Referrer URL
-J, --remote-header-name Use the header-provided filename
-O, --remote-name Write output to a file named as the remote file
--remote-name-all Use the remote file name for all URLs
-R, --remote-time Set the remote file's time on the local output
-X, --request <command> Specify request command to use
--request-target Specify the target for this request
--resolve <host:port:address[,address]...> Resolve the host+port to this address
--retry <num> Retry request if transient problems occur
--retry-connrefused Retry on connection refused (use with --retry)
--retry-delay <seconds> Wait time between retries
--retry-max-time <seconds> Retry only within this period
--sasl-authzid <identity> Use this identity to act as during SASL PLAIN authentication
--sasl-ir Enable initial response in SASL authentication
--service-name <name> SPNEGO service name
-S, --show-error Show error even when -s is used
-s, --silent Silent mode
--socks4 <host[:port]> SOCKS4 proxy on given host + port
--socks4a <host[:port]> SOCKS4a proxy on given host + port
--socks5 <host[:port]> SOCKS5 proxy on given host + port
--socks5-basic Enable username/password auth for SOCKS5 proxies
--socks5-gssapi Enable GSS-API auth for SOCKS5 proxies
--socks5-gssapi-nec Compatibility with NEC SOCKS5 server
--socks5-gssapi-service <name> SOCKS5 proxy service name for GSS-API
--socks5-hostname <host[:port]> SOCKS5 proxy, pass host name to proxy
-Y, --speed-limit <speed> Stop transfers slower than this
-y, --speed-time <seconds> Trigger 'speed-limit' abort after this time
--ssl Try SSL/TLS
--ssl-allow-beast Allow security flaw to improve interop
--ssl-no-revoke Disable cert revocation checks (Schannel)
--ssl-reqd Require SSL/TLS
-2, --sslv2 Use SSLv2
-3, --sslv3 Use SSLv3
--stderr Where to redirect stderr
--styled-output Enable styled output for HTTP headers
--suppress-connect-headers Suppress proxy CONNECT response headers
--tcp-fastopen Use TCP Fast Open
--tcp-nodelay Use the TCP_NODELAY option
-t, --telnet-option <opt=val> Set telnet option
--tftp-blksize <value> Set TFTP BLKSIZE option
--tftp-no-options Do not send any TFTP options
-z, --time-cond <time> Transfer based on a time condition
--tls-max <VERSION> Set maximum allowed TLS version
--tls13-ciphers <list> TLS 1.3 ciphersuites (OpenSSL)
--tlsauthtype <type> TLS authentication type
--tlspassword TLS password
--tlsuser <name> TLS user name
-1, --tlsv1 Use TLSv1.0 or greater
--tlsv1.0 Use TLSv1.0 or greater
--tlsv1.1 Use TLSv1.1 or greater
--tlsv1.2 Use TLSv1.2 or greater
--tlsv1.3 Use TLSv1.3 or greater
--tr-encoding Request compressed transfer encoding
--trace <file> Write a debug trace to FILE
--trace-ascii <file> Like --trace, but without hex output
--trace-time Add time stamps to trace/verbose output
--unix-socket <path> Connect through this Unix domain socket
-T, --upload-file <file> Transfer local FILE to destination
--url <url> URL to work with
-B, --use-ascii Use ASCII/text transfer
-u, --user <user:password> Server user and password
-A, --user-agent <name> Send User-Agent <name> to server
-v, --verbose Make the operation more talkative
-V, --version Show version number and quit
-w, --write-out <format> Use output FORMAT after completion
--xattr Store metadata in extended file attributes
geek@ubuntu:~$ curl -v https://www.imooc.com/ > tmp.txt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:14 --:--:-- 0* Trying 117.121.101.40:443...
* TCP_NODELAY set
* Connected to www.imooc.com (117.121.101.40) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [106 bytes data]
* NPN, negotiated HTTP1.1
{ [5 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2675 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Next protocol (67):
} [36 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.imooc.com
* start date: Sep 9 00:00:00 2019 GMT
* expire date: Nov 7 12:00:00 2020 GMT
* subjectAltName: host "www.imooc.com" matched cert's "*.imooc.com"
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=RapidSSL RSA CA 2018
* SSL certificate verify ok.
} [5 bytes data]
> GET / HTTP/1.1
> Host: www.imooc.com
> User-Agent: curl/7.68.0
> Accept: */*
>
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Sat, 06 Jun 2020 07:06:16 GMT
< Content-Type: text/html; charset=UTF-8
< Content-Length: 375021
< Connection: keep-alive
< Vary: Accept-Encoding
< Vary: Accept-Encoding
< X-Varnish: 1073608231 79251
< Age: 32
< Via: 1.1 varnish (Varnish/6.0)
< X-Cache: HIT from CS42
< Accept-Ranges: bytes
<
{ [16063 bytes data]
100 366k 100 366k 0 0 24333 0 0:00:15 0:00:15 --:--:-- 93312
* Connection #0 to host www.imooc.com left intact
HTTP ~ Request。
> GET / HTTP/1.1
> Host: www.imooc.com
> User-Agent: curl/7.68.0
> Accept: */*
HTTP ~ Response。
HTTP ~ Body(html)。
urllib(原生) & Requests。
urllib。
# -*- coding: utf-8 -*-
import urllib2
import urllib
# URL_IP = 'http://www.httpbin.org/ip'
URL_IP = 'http://127.0.0.1:8000/ip'
def use_simple_urllib2():
response = urllib2.urlopen(URL_IP)
print '>>>>> Response Headers: '
print response.info()
print '>>>>> Response Body: '
print ''.join([line for line in response.readlines()])
if __name__ == '__main__':
print '>>>>> use simple urllib2: '
use_simple_urllib2()
/home/geek/PycharmProjects/untitled/venv/bin/python /home/geek/PycharmProjects/untitled/urllib2_demo.py
>>>>> use simple urllib2:
>>>>> Response Headers:
Server: gunicorn/20.0.4
Date: Sat, 06 Jun 2020 09:29:31 GMT
Connection: close
Content-Type: application/json
Content-Length: 23
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
>>>>> Response Body:
{"origin":"127.0.0.1"}
Process finished with exit code 0
- 带参数请求。
# -*- coding: utf-8 -*-
import urllib2
import urllib
# URL_IP = 'http://www.httpbin.org/ip'
URL_IP = 'http://127.0.0.1:8000/ip'
URL_GET = 'http://127.0.0.1:8000/get'
def use_simple_urllib2():
response = urllib2.urlopen(URL_IP)
print '>>>>> Response Headers: '
print response.info()
print '>>>>> Response Body: '
print ''.join([line for line in response.readlines()])
def use_params_urllib2():
# 构建请求参数。
params = urllib.urlencode({'param1': 'hello', 'param2': 'world'})
print 'Request Params: '
print params
# 发送请求。
response = urllib2.urlopen('?'.join([URL_GET]))
# 处理相应。
print '>>>>> Response Headers: '
print response.info()
print '>>>>> Status Code: '
print response.getcode()
print '>>>>> Response Body: '
print ''.join([line for line in response.readlines()])
if __name__ == '__main__':
# print '>>>>> use simple urllib2: '
# use_simple_urllib2()
print '>>>>> use params urllib2: '
use_params_urllib2()
/home/geek/PycharmProjects/untitled/venv/bin/python /home/geek/PycharmProjects/untitled/urllib2_demo.py
>>>>> use params urllib2:
Request Params:
param2=world¶m1=hello
>>>>> Response Headers:
Server: gunicorn/20.0.4
Date: Sat, 06 Jun 2020 13:56:37 GMT
Connection: close
Content-Type: application/json
Content-Length: 186
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
>>>>> Status Code:
200
>>>>> Response Body:
{"args":{},"headers":{"Accept-Encoding":"identity","Connection":"close","Host":"127.0.0.1:8000","User-Agent":"Python-urllib/2.7"},"origin":"127.0.0.1","url":"http://127.0.0.1:8000/get"}
Process finished with exit code 0
Requests。
# -*- coding:UTF-8 -*-
# SyntaxError: Non-ASCII character '\xe6' in file /home/geek/PycharmProjects/untitled/requests_demo.py on line 18, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
import requests
# URL_IP = 'http://www.httpbin.org/ip'
URL_IP = 'http://127.0.0.1:8000/ip'
def use_simple_requests():
response = requests.get(URL_IP)
print '>>>>> Response Headers: '
print response.headers
print '>>>>> Response Body: '
print response.text
if __name__ == '__main__':
print '>>>>> use simple requests: '
use_simple_requests()
/home/geek/PycharmProjects/untitled/venv/bin/python /home/geek/PycharmProjects/untitled/requests_demo.py
>>>>> use simple requests:
>>>>> Response Headers:
{'Content-Length': '23', 'Server': 'gunicorn/20.0.4', 'Connection': 'close', 'Access-Control-Allow-Credentials': 'true', 'Date': 'Sat, 06 Jun 2020 13:47:37 GMT', 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'}
>>>>> Response Body:
{"origin":"127.0.0.1"}
Process finished with exit code 0
- 带参数请求。
# -*- coding:UTF-8 -*-
# SyntaxError: Non-ASCII character '\xe6' in file /home/geek/PycharmProjects/untitled/requests_demo.py on line 18, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
import requests
# URL_IP = 'http://www.httpbin.org/ip'
URL_IP = 'http://127.0.0.1:8000/ip'
def use_simple_requests():
response = requests.get(URL_IP)
print '>>>>> Response Headers: '
print response.headers
print '>>>>> Response Body: '
print response.text
def use_params_requests():
# 构建请求参数。
params = {'param1': 'hello', 'param2': 'world'}
print 'Request Params: '
print params
# 发送请求。
response = requests.get(URL_IP, params=params)
# 处理相应。
print '>>>>> Response Headers: '
print response.headers
print '>>>>> Status Code: '
print response.status_code
print response.reason
print '>>>>> Response Body: '
print response.json()
if __name__ == '__main__':
# print '>>>>> use simple requests: '
# use_simple_requests()
print '>>>>> use_params_requests'
use_params_requests()
/home/geek/PycharmProjects/untitled/venv/bin/python /home/geek/PycharmProjects/untitled/requests_demo.py
>>>>> use_params_requests
Request Params:
{'param2': 'world', 'param1': 'hello'}
>>>>> Response Headers:
{'Content-Length': '23', 'Server': 'gunicorn/20.0.4', 'Connection': 'close', 'Access-Control-Allow-Credentials': 'true', 'Date': 'Sat, 06 Jun 2020 13:58:50 GMT', 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'}
>>>>> Status Code:
200
OK
>>>>> Response Body:
{u'origin': u'127.0.0.1'}
Process finished with exit code 0
Requests 库。
Github API。
https://developer.github.com/v3/
发送请求。
请求方法。
GET:查看资源。
POST:增加资源。
PUT:修改资源。
DELETE:删除资源。
HEAD:查看响应头。
OPTIONS:查看可用请求方法。
代码。
- 查询用户。
import json
import requests
URL = 'https://api.github.com'
def build_uri(endpoint):
return '/'.join([URL, endpoint])
def better_print(json_str):
return json.dumps(json.loads(json_str), indent=4)
def request_method():
response = requests.get(build_uri('users/lyfGeek'))
print better_print(response.text)
if __name__ == '__main__':
request_method()
/home/geek/PycharmProjects/untitled/venv/bin/python /home/geek/PycharmProjects/untitled/github_api.py
{
"public_repos": 18,
"site_admin": false,
"subscriptions_url": "https://api.github.com/users/lyfGeek/subscriptions",
"gravatar_id": "",
"hireable": null,
"id": 35895457,
"followers_url": "https://api.github.com/users/lyfGeek/followers",
"following_url": "https://api.github.com/users/lyfGeek/following{/other_user}",
"blog": "",
"followers": 0,
"location": null,
"type": "User",
"email": null,
"bio": null,
"gists_url": "https://api.github.com/users/lyfGeek/gists{/gist_id}",
"company": null,
"events_url": "https://api.github.com/users/lyfGeek/events{/privacy}",
"html_url": "https://github.com/lyfGeek",
"updated_at": "2020-05-27T15:54:48Z",
"twitter_username": null,
"node_id": "MDQ6VXNlcjM1ODk1NDU3",
"received_events_url": "https://api.github.com/users/lyfGeek/received_events",
"starred_url": "https://api.github.com/users/lyfGeek/starred{/owner}{/repo}",
"public_gists": 0,
"name": null,
"organizations_url": "https://api.github.com/users/lyfGeek/orgs",
"url": "https://api.github.com/users/lyfGeek",
"created_at": "2018-01-28T15:09:13Z",
"avatar_url": "https://avatars1.githubusercontent.com/u/35895457?v=4",
"repos_url": "https://api.github.com/users/lyfGeek/repos",
"following": 0,
"login": "lyfGeek"
}
Process finished with exit code 0
- 查询 email。
# -*- encoding: utf-8 -*-
import json
import requests
URL = 'https://api.github.com'
def build_uri(endpoint):
return '/'.join([URL, endpoint])
def better_print(json_str):
return json.dumps(json.loads(json_str), indent=4)
def request_method():
# response = requests.get(build_uri('users/lyfGeek'))
response = requests.get(build_uri('user/emails'), auth=('lyfGeek', '你的密码'))
print better_print(response.text)
if __name__ == '__main__':
request_method()
/home/geek/PycharmProjects/requests_geek/venv/bin/python /home/geek/PycharmProjects/requests_geek/main.py
[
{
"verified": true,
"email": "lyfGeek@qq.com",
"visibility": "private",
"primary": true
},
{
"verified": true,
"email": "35895457+lyfGeek@users.noreply.github.com",
"visibility": null,
"primary": false
}
]
Process finished with exit code 0
带参数的请求。
URL Parameters。URL 参数。
表单参数提交。
Content-Type: application/x-www-form-urlencoded
内容:key1=value1&key2=value2
requests.post(url, data={‘key1’: ‘value1’, ‘key2’: ‘value2’})
Json 参数提交。
Content-Type: applicatio/json
内容:{‘key1’: ‘value1’, ‘key2’: ‘value2’}
requests.post(url, json={‘key1’: ‘value1’, ‘key2’: ‘value2’})
# 修改账户信息。
def json_request():
response = requests.patch(build_uri('user'), auth=('lyfGeek', '你的密码'),
json={'name': 'lyfGeek', 'email': 'liyifan@lyfGeek.club'})
print better_print(response.text)
print response.request.headers
print response.request.body
print response.status_code
请求异常处理。
def timeout_request():
try:
response = requests.get(build_uri('user/emails'), timeout=0.1)
except exceptions.Timeout as e:
print e.message
else:
print response.status_code
/home/geek/PycharmProjects/requests_geek/venv/bin/python /home/geek/PycharmProjects/requests_geek/main.py
HTTPSConnectionPool(host=‘api.github.com’, port=443): Max retries exceeded with url: /user/emails (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7efd5adb9a90>, ‘Connection to api.github.com timed out. (connect timeout=0.1)’))Process finished with exit code 0
自定义 Request。
def hard_request():
from requests import Request, Session
session = Session()
headers = {'User-Agent': 'fake1.3.4'}
request = Request('GET', build_uri('user/emails'), auth=('lyfGeek', '你的密码'), headers=headers)
prepared = request.prepare()
print prepared.headers
print prepared.body
response = session.send(prepared, timeout=5)
print response.status_code
print response.request.headers
print response.text
'''
/home/geek/PycharmProjects/requests_geek/venv/bin/python /home/geek/PycharmProjects/requests_geek/main.py
{'Authorization': 'Basic bHlmR2VlazpzUW01ODEyNTc=', 'User-Agent': 'fake1.3.4'}
None
200
{'Authorization': 'Basic bHlmR2VlazpzUW01ODEyNTc=', 'User-Agent': 'fake1.3.4'}
[{"email":"lyfGeek@qq.com","primary":true,"verified":true,"visibility":"private"},{"email":"35895457+lyfGeek@users.noreply.github.com","primary":false,"verified":true,"visibility":null}]
Process finished with exit code 0
'''
处理响应。
geek@ubuntu:~$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> response = requests.get('https://api.github.com')
>>> response.status_code
200
>>> response.reason
'OK'
>>> response.headers
{'date': 'Fri, 12 Jun 2020 07:12:25 GMT', 'content-type': 'application/json; charset=utf-8', 'server': 'GitHub.com', 'status': '200 OK', 'cache-control': 'public, max-age=60, s-maxage=60', 'vary': 'Accept, Accept-Encoding, Accept, X-Requested-With, Accept-Encoding', 'etag': 'W/"c6bac8870a7f94b08b440c3d5873c9ca"', 'x-github-media-type': 'github.v3; format=json', 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset', 'access-control-allow-origin': '*', 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload', 'x-frame-options': 'deny', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin', 'content-security-policy': "default-src 'none'", 'content-encoding': 'gzip', 'X-Ratelimit-Limit': '60', 'X-Ratelimit-Remaining': '59', 'X-Ratelimit-Reset': '1591949545', 'Accept-Ranges': 'bytes', 'Content-Length': '496', 'X-GitHub-Request-Id': 'DD2D:17A7:8D868:BE222:5EE32AD8'}
下载图片和文件。
# -*- encoding: utf-8 -*-
import requests
def download_improved():
'''demo 下载图片。
'''
url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591956828853&di=190aa39f15bceb3673aa94a58524d20f&imgtype=0&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D2351377820%2C1473555572%26fm%3D214%26gp%3D0.jpg'
response = requests.get(url, stream=True)
from contextlib import closing
# 打开文件。
with closing(requests.get(url, stream=True)) as response:
with open('demo1.jpg', 'wb') as fd:
# 每 128 写入一次。
for chunk in response.iter_content(128):
fd.write(chunk)
def download_image():
'''demo 下载图片。
'''
url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591956828853&di=190aa39f15bceb3673aa94a58524d20f&imgtype=0&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D2351377820%2C1473555572%26fm%3D214%26gp%3D0.jpg'
response = requests.get(url)
# print response.content
with open('demo.jpg', 'wb') as fd:
for chunk in response.iter_content(128):
fd.write(chunk)
if __name__ == '__main__':
download_image()
# download_improved()
事件钩子 ~ Event Hooks。
# -*- encoding: utf-8 -*-
import requests
def get_key_info(response, *args, **kwargs):
"""回调函数。
"""
print response.headers['Content-Type']
def main():
"""主程序。
"""
requests.get('https://www.baidu.com', hooks=dict(response=get_key_info))
# text/html
if __name__ == '__main__':
main()
HTTP 认证。
# -*- encoding: utf-8 -*-
import requests
BASE_URL = 'https://api.github.com'
def construct_url(end_point):
return '/'.join([BASE_URL, end_point])
def basic_auth():
'''基本认证。
'''
response = requests.get(construct_url('user'), auth=('lyfGeek', 'sQm581257'))
print response.text
print response.request.headers
# {'Authorization': 'Basic b1HlmR2VlazpzUW01ODEyNTc=', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'python-requests/2.23.0'}
basic_auth()
{'Authorization': 'Basic b1HlmR2VlazpzUW01ODEyNTc=',
这里其实是用了 BASE64 加密。
解密看看。
In [1]: import base64
In [2]: base64.b64decode('b1HlmR2VlazpzUW01ODEyNTc=')
Out[2]: b'lyfGeek:你的密码'
OAuth。
Proxy 代理。
启动代理服务 Heroku。
在主机 1080 端口启动 Socks 服务。
将请求转发到 1080 端口。
获取相应资源。
pip install ‘requests[socksv5]’