HttpRequestLib.py
import requests
from requests import utils
import urllib3
import json
from contextlib import closing
from requests import exceptions
class HttpRequest(object):
# base_url的作用,为后续区分开发和测试环境url提供方便
def __init__(self, base_url="", **kwargs):
urllib3.disable_warnings()
self.base_url = base_url
self.session = requests.session()
if "proxies" in kwargs.keys():
print("proxies:%s" % kwargs.get("proxies"))
self.session.proxies = kwargs.get("proxies")
if "headers" in kwargs.keys():
print("headers:%s" % kwargs.get("headers"))
self.session.headers.update(kwargs.get("headers"))
if "verify" in kwargs.keys():
print("verify:%s" % kwargs.get("verify"))
self.session.verify = kwargs.get("verify")
# if "cookies" in kwargs.keys():
# print("cookies:%s" % kwargs.get("cookies"))
# print(type(kwargs.get("cookies")))
# self.session.cookies = kwargs.get("cookies")
if "auth" in kwargs.keys():
print("auth:%s" % kwargs.get("auth"))
self.session.auth = kwargs.get("auth")
if "cert" in kwargs.keys():
print("cert:%s" % kwargs.get("cert"))
self.session.cert = kwargs.get("cert")
def print_re_info(self, response):
print(">>>>General")
print("Request URL: %s" % response.request.url)
print("Request Method: %s" % response.request.method)
print("Status Code: %s" % response.status_code)
print("Request History: %s" % response.history, end="\n\n")
print(">>>>Request Headers")
print(HttpRequest.better_print(response.request.headers), end="\n\n")
print(">>>>Response Headers")
print(HttpRequest.better_print(response.headers))
print(">>>>Encoding")
print("Response encoding:", response.encoding)
print("Content encoding:", utils.get_encodings_from_content(response.text))
@staticmethod
def better_print(response_info):
if isinstance(response_info, requests.structures.CaseInsensitiveDict):
return json.dumps(dict(response_info), indent=4)
return json.dumps(json.loads(response_info), indent=4)
# 重构url,relative_url相对base_url的路径
def build_url(self,relative_url):
self.base_url = self.base_url.strip()
relative_url = relative_url.strip()
if self.base_url != "" and self.base_url[len(self.base_url)-1] == "/":
self.base_url = self.base_url[:len(self.base_url)-1]
if relative_url != "" and relative_url[0] == "/":
relative_url = relative_url[1:]
if self.base_url != "":
return "/".join([self.base_url, relative_url])
return "".join([self.base_url, relative_url])
# 将返回结果写回文件
def write_text_to_html(self,response_text,html_name):
with open(html_name, "w", encoding="utf-8") as f:
f.write(response_text)
# 发送请求
def send_request(self, method, url, *args, **kwargs):
try:
return self.session.request(method,self.build_url(url), verify=False, *args, **kwargs)
except exceptions.ConnectTimeout as timeout:
raise timeout
except exceptions.InvalidURL as invalidurl:
raise invalidurl
except exceptions.ProxyError as proxy:
raise proxy
except exceptions.ConnectionError as connect_error:
raise connect_error
# 下载文件
"""
当下载大的文件的时候,建议使用strea模式.
默认情况下是false,他会立即开始下载文件并存放到内存当中,倘若文件过大就会导致内存不足的情况.
当把get函数的stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载。
需要注意一点:文件没有下载之前,它也需要保持连接。
iter_content:一块一块的遍历要下载的内容
iter_lines:一行一行的遍历要下载的内容
使用上面两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据。
"""
def download_file(self, method, url, file_name, *args, **kwargs):
with closing(self.send_request(method, url, stream=True, *args, **kwargs)) as response:
if response.status_code == 200:
with open(file_name, "wb") as file:
for chunk in response.iter_content(chunk_size=128):
file.write(chunk)
else:
return response
def __del__(self):
self.session.close()
if __name__ == '__main__':
pass
测试代码如下:
# -*- coding:utf-8 -*-
from HttpRequestLib import HttpRequest
# 12306查票,增加headers
print(">>>>>12306查票")
base_url = "https://kyfw.12306.cn"
headers = {
"Cookie": "tk=6RKLoLMQ51q6Gra6cpcR3vd4t04gpYZioqBNxpfyOYssdh1h0; JSESSIONID=DBE84F48CBDC8FF433E5DC81AE0C2D33; _jc_save_wfdc_flag=dc; BIGipServerotn=1574502666.50210.0000; BIGipServerpassport=937951498.50215.0000; RAIL_EXPIRATION=1590595271649; RAIL_DEVICEID=UqL2b3rS5br_7q-rReFIZWJ2NUXUT0vr8O7P6G21oCM4OV7NUtlmF0ve-Ea-S_ZN-kmOvehnyaSF-ATTiTYZPWKFKFbBAZvPmptbRuW8dyCrf_aOXJkMuMBNAVhHrsOBJQCVeBZYp11SEWhrX8kolu5sCAoO8bJ_; route=c5c62a339e7744272a54643b3be5bf64; _jc_save_toDate=2020-05-24; _jc_save_fromDate=2020-05-26; _jc_save_fromStation=%u897F%u5B89%2CXAY; _jc_save_toStation=%u592A%u539F%2CTYV"
}
request = HttpRequest(base_url)
params={
"leftTicketDTO.train_date": "2020-05-27",
"leftTicketDTO.from_station": "XAY",
"leftTicketDTO.to_station": "TYV",
"purpose_codes": "ADULT"
}
response = request.send_request("get", "otn/leftTicket/query", params=params, headers=headers)
request.print_re_info(response)
request.write_text_to_html(response.text, "queryticket.html")
print(response.text)
# 携程网上传文件,个人中心->我的信息->头像设置->上传图片
print(">>>>>>>携程网上传文件")
url = "https://sinfo.ctrip.com/MyInfo/Ajax/UploadPhoto.ashx"
# "uploadFile_180":文件参数的名字
# ”01-linux基础-14.jpg“:上传文件的名字
# open(r"C:\Users\hyongchang\Desktop\01-linux基础-14.jpg","rb"):打开本地文件的名字
# "image/jpeg" 文件类型
# Content-Disposition: form-data; name="uploadFile_180"; filename="01-linux基础-14.jpg" Content-Type: image/jpeg
files = {
"uploadFile_180": ("01-linux基础-14.jpg",open(r"C:\Users\hyongchang\Desktop\01-linux基础-14.jpg","rb"),"image/jpeg")
}
cookies = {
"Cookie": "_abtest_userid=dff0d4e7-0b20-4391-bf81-201a459cb842; _RSG=YEaCaRaZuCDwSJ5l.eO8HB; _RDG=28bc783b9310f7298724348238b6f2f91d; _RGUID=d3388e46-e432-43a2-b448-628faf15373a; _ga=GA1.2.332689222.1587798309; MKT_CKID=1587798309324.14jgg.h25l; appFloatCnt=3; _RF1=113.143.181.157; _gid=GA1.2.531078366.1590314827; _jzqco=%7C%7C%7C%7C1587798309510%7C1.303916781.1587798309347.1587798309348.1590314826866.1587798309348.1590314826866.0.0.0.2.2; MKT_CKID_LMT=1590314826869; __zpspc=9.2.1590314826.1590314826.1%232%7Csp0.baidu.com%7C%7C%7C%25E6%2590%25BA%25E7%25A8%258B%25E7%25BD%2591%7C%23; MKT_Pagesource=PC; Union=AllianceID=1881&SID=2209&OUID=5CA1E79A08DABB2D7F8836D9C66A891E%7C100.1030.00.000.00; Session=SmartLinkCode=U2209&SmartLinkKeyWord=&SmartLinkQuary=&SmartLinkHost=&SmartLinkLanguage=zh; login_uid=9115291CE775B6FA5477ABA20426316E; login_type=0; cticket=3A3E5D6D107A51909899345A417B8C0DA986B6257A2CCF02406FBAF80E8A1A70; AHeadUserInfo=VipGrade=0&VipGradeName=%C6%D5%CD%A8%BB%E1%D4%B1&UserName=&NoReadMessageCount=0; ticket_ctrip=bJ9RlCHVwlu1ZjyusRi+ypZ7X2r4+yoj2x8F/THpFeFdtgx2zprwAeRyF14r1wrzX1k8X6qph8F/La+9hhrK+D45of4fMGXKkSBn6nS3ukcDvtLw8YdrWT8fwoSLP+z0Rm4O6H8Ii9wegrdQZCWTGulmbqQRSm0FJKRhwYV8FTMn5A8Ud6EEjRxDRhmj7xRIsN7WyRToSgfJrgeG9DnoRJI1y84RS/H5Z3S6eKzSGhQi2h25ULUj526EGfW41gwpH87dp2B6XBYUZOSrKe7uElXpZFHeZGmlmaBXf3aSVAM=; DUID=u=6BAB1875C3EBF940A660BDE5A53AA613&v=0; IsNonUser=F; UUID=3C0DB66525544DC2A677FD0C315E0D4C; IsPersonalizedLogin=T; ASP.NET_SessionSvc=MTAuMjUuMjQxLjM3fDkwOTB8b3V5YW5nfGRlZmF1bHR8MTU4OTAwNTY0MjIxMA; ASP.NET_SessionId=gftqcisjsiom24fpg2jpylqk; MyCtripDescription=UID=A5A28972008C203B3E2909751C775BCE&IsClub140=F&IsHoliday=F&CorpMileage=F; _bfa=1.1587798306483.2aj6i.1.1587798306483.1590314823960.2.13; _bfs=1.9; _bfi=p1%3D100013%26p2%3D100021%26v1%3D13%26v2%3D12"
}
request = HttpRequest()
response = request.send_request("post", url=url, files=files, cookies=cookies)
print(response.text)
request.write_text_to_html(response.text,"uploadfile.html")
# 查询手机号码归属地
url = "https://tcc.taobao.com"
params = {
"tel": "15329290153"
}
request = HttpRequest(url)
response = request.send_request("get", url="cc/json/mobile_tel_segment.htm", params=params)
request.print_re_info(response)
# 下载文件接口
base_url = "https://biz.demo.zentao.net"
data = {
"num": "10",
"fileType": "xlsx"
}
cookies = {
"Cookie": "__cfduid=d6c4b764f481679d23d55bc7a66a22adb1588766707; UM_distinctid=171e9e06747aa-0375cf7742573e-5373e62-144000-171e9e0674844a; lang=zh-cn; device=desktop; theme=default; feedbackView=0; zentaosid=oienmd3fjjjcd1isq920hd9n82; lastProduct=38; preBranch=0; preProductID=38; caseModule=0; checkedItem=; CNZZDATA4553360=cnzz_eid%3D1106009506-1589983333-%26ntime%3D1590324001; Hm_lvt_731bb611021e8720f1fc3035dfd2a44f=1589900835,1589983845,1590320769,1590324737; Hm_lpvt_731bb611021e8720f1fc3035dfd2a44f=1590324774; windowWidth=800; windowHeight=175; downloading=0"
}
request = HttpRequest(base_url)
request.download_file("POST", "testcase-exportTemplet-38.html", file_name="download.xlsx", data=data, cookies=cookies)