158 lines
5.8 KiB
Python
158 lines
5.8 KiB
Python
import requests, requests.utils
|
|
from typing import Any, Text, Dict, SupportsInt, SupportsFloat, SupportsBytes
|
|
|
|
|
|
def msg_digest(res, **kwargs):
|
|
import urllib.parse
|
|
toshort = lambda t: t[0:256] + ' ... [MORE ' + str(
|
|
int(((len(t) - 256) / len(t)) * 100)) + '% OMITTED HERE]' if len(t) > 256 else t
|
|
reqline = '%s %s HTTP/%.1f\n' % (res.request.method, res.request.path_url, res.raw.version * 0.1)
|
|
reqhead = 'Host: %s\n' % urllib.parse.urlparse(res.request.url).netloc
|
|
for k, v in dict(res.request.headers).items():
|
|
reqhead += '%s: %s\n' % (k, v)
|
|
else:
|
|
reqhead += '\n'
|
|
reqbody = ''
|
|
if isinstance(res.request.body, bytes):
|
|
reqbody += str(res.request.body)[2:-1]
|
|
elif res.request.body:
|
|
reqbody += str(res.request.body)
|
|
resline = 'HTTP/%.1f %d %s\n' % (res.raw.version * 0.1, res.raw.status, res.raw.reason)
|
|
reshead = ''
|
|
for k, v in dict(res.headers).items():
|
|
reshead += '%s: %s\n' % (k, v)
|
|
else:
|
|
reshead += '\n'
|
|
resbody = ''
|
|
if res.text:
|
|
resbody += res.text
|
|
return {
|
|
"req": reqline + reqhead + toshort(reqbody),
|
|
"res": resline + reshead + toshort(resbody)
|
|
}
|
|
|
|
|
|
def hook_response_debug(res, **kwargs):
|
|
info = msg_digest(res, **kwargs)
|
|
logs = '[->]' + '\n' + info["req"] + '\n' + '[<-]' + '\n' + info["res"]
|
|
print(logs)
|
|
try:
|
|
import logging
|
|
logging.log(logging.DEBUG, logs)
|
|
except:
|
|
pass
|
|
|
|
|
|
class Request:
|
|
__http__ = requests
|
|
__method_list__ = ('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'PATCH')
|
|
__response_object__ = None
|
|
__response_briefs__ = None
|
|
|
|
@staticmethod
|
|
def _msg_digest(res, **kwargs):
|
|
import urllib.parse
|
|
toshort = lambda t: t[0:256] + ' ... [MORE ' + str(
|
|
int(((len(t) - 256) / len(t)) * 100)) + '% OMITTED HERE]' if len(t) > 256 else t
|
|
reqline = '%s %s HTTP/%.1f\n' % (res.request.method, res.request.path_url, res.raw.version * 0.1)
|
|
reqhead = 'Host: %s\n' % urllib.parse.urlparse(res.request.url).netloc
|
|
for k, v in dict(res.request.headers).items():
|
|
reqhead += '%s: %s\n' % (k, v)
|
|
else:
|
|
reqhead += '\n'
|
|
reqbody = ''
|
|
if isinstance(res.request.body, bytes):
|
|
reqbody += str(res.request.body)[2:-1]
|
|
elif res.request.body:
|
|
reqbody += str(res.request.body)
|
|
resline = 'HTTP/%.1f %d %s\n' % (res.raw.version * 0.1, res.raw.status, res.raw.reason)
|
|
reshead = ''
|
|
for k, v in dict(res.headers).items():
|
|
reshead += '%s: %s\n' % (k, v)
|
|
else:
|
|
reshead += '\n'
|
|
resbody = ''
|
|
if res.text:
|
|
resbody += res.text
|
|
return {
|
|
"req": reqline + reqhead + toshort(reqbody),
|
|
"res": resline + reshead + toshort(resbody)
|
|
}
|
|
|
|
def _response_briefs(self, res, **kwargs):
|
|
info = msg_digest(res, **kwargs)
|
|
logs = '[->]' + '\n' + info["req"] + '\n' + '[<-]' + '\n' + info["res"]
|
|
self.__response_briefs__ = logs
|
|
|
|
def http(self,
|
|
method: Text = 'GET',
|
|
url: Text = None,
|
|
query: Dict | Text = None,
|
|
data: Dict | Text | SupportsBytes = None,
|
|
json: Any = None,
|
|
file: Dict = None,
|
|
header: Dict = None,
|
|
cookie: Dict = None,
|
|
auth: Any = None,
|
|
timeout: SupportsInt | SupportsFloat = None,
|
|
proxy: Text = None,
|
|
auto_redirect=False,
|
|
ignore_cert_error=False,
|
|
debug=False):
|
|
if method is None:
|
|
raise Exception('未指定的请求方法 | Unspecified request method.')
|
|
method = method.upper()
|
|
if method not in self.__method_list__:
|
|
raise Exception('不支持的请求方法 | Unsupported request method.')
|
|
if method == 'HEAD':
|
|
auto_redirect = False
|
|
if isinstance(proxy, str) and len(proxy) >= 5:
|
|
proxy = {"http": proxy, "https": proxy}
|
|
else:
|
|
proxy = None
|
|
self.__response_briefs__ = None
|
|
self.__response_object__ = self.__http__.request(
|
|
method=method,
|
|
url=url,
|
|
params=query,
|
|
data=data,
|
|
headers=header,
|
|
cookies=cookie,
|
|
files=file,
|
|
auth=auth,
|
|
timeout=timeout,
|
|
allow_redirects=auto_redirect,
|
|
proxies=proxy,
|
|
verify=not ignore_cert_error,
|
|
json=json,
|
|
hooks=[None, {"response": self._response_briefs}][debug]
|
|
)
|
|
try:
|
|
json_content = self.__response_object__.json()
|
|
except:
|
|
json_content = None
|
|
return {
|
|
"url": self.__response_object__.url, "encoding": self.__response_object__.encoding,
|
|
"status": self.__response_object__.status_code,
|
|
"reason": self.__response_object__.reason,
|
|
"header": self.__response_object__.headers,
|
|
"duration": round(self.__response_object__.elapsed.microseconds / 1000, 1),
|
|
"cookie": requests.utils.dict_from_cookiejar(self.__response_object__.cookies),
|
|
"text": self.__response_object__.text,
|
|
"json": json_content,
|
|
"content": self.__response_object__.content,
|
|
"brief": self.__response_briefs__
|
|
}
|
|
|
|
|
|
class Session(Request):
|
|
__http__ = requests.session()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
req = Session()
|
|
print(req.http('GET', 'https://www.baidu.com/s', query={"wd": '社会主义核心价值观'},
|
|
header={"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
|
|
'Chrome/86.0.4240.198 Safari/537.36'},
|
|
auto_redirect=True, debug=False))
|