from fake_useragent import UserAgent import requests,os,json from lxml import html import traceback import time,re from urllib3.util.retry import Retry from requests.adapters import HTTPAdapter from utils.Ntfy import ntfy from utils.comic.PathStr import pathStr class htmlUtils: headers = {'User-Agent': UserAgent().random} url_data = {} @classmethod def getPathSaveHtml(cls,url,type=None): rstr = r"[\/\\\:\*\?\"\<\>\|\.]" #  '/ \ : * ? " < > |' try: file_url = re.sub(rstr, "", url) except: file_url = "error_cache" file_path = os.path.join(pathStr.base_html_cache,file_url) if type == "new": return file_path if os.path.exists(file_path): if type == "read": with open(file_path,"r",encoding="utf-8") as fs: return fs.read() return file_path else: return None @classmethod def saveHtml(cls,url,data): file_path = cls.getPathSaveHtml(url,type="new") dir_name = os.path.dirname(file_path) if not os.path.exists(dir_name): os.makedirs(dir_name) with open(file_path,"w",encoding="utf-8") as fs: fs.write(str(data)) @classmethod def remove_HtmlCache(cls,url): file_path = cls.getPathSaveHtml(url,type="new") if os.path.exists(file_path): try: os.remove(file_path) print("已删除") except: print() @classmethod def getHTML(cls, curl,type=None): retries = Retry(total=1, backoff_factor=0.1, status_forcelist=[ 500, 502, 503, 504 ]) s = requests.Session() s.mount('http://', HTTPAdapter(max_retries=retries)) s.mount('https://', HTTPAdapter(max_retries=retries)) count = 1 #数据为空则获取数据 url_text = cls.getPathSaveHtml(curl,"read") if url_text != None: return html.fromstring(url_text) while url_text == None: if count <= 3: try: print(f"请求地址:{curl}") res = s.get(curl,stream=True, headers=cls.headers, timeout=180,allow_redirects=True) if res.status_code != 200: cls.remove_HtmlCache(curl) return None if type == "bytes": url_text = res if type == "json": #url_text = res.json() url_text = json.loads(res.text) cls.saveHtml(curl,res.text) if type == None: url_text = html.fromstring(res.text) cls.saveHtml(curl,res.text) except: print(f'Retry! 第{count}次') time.sleep(1) traceback.print_exc() count += 1 continue else: ntfy.sendMsg(f"fail 请求失败:{curl}") exit() break return url_text @classmethod def getBytes(cls, url): return cls.getHTML(url,type="bytes") @classmethod def getJSON(cls,url): res = requests.get(url,headers=cls.headers, timeout=180) if res.status_code != 200: return None try: return json.loads(res.text) except: return None @classmethod def xpathData(cls,c_xpath,url=None,num=None,not_eq=None,update=False): if url == None: url = cls.temp_url else: cls.temp_url = url result = [] if update: html_cache_path = cls.getPathSaveHtml(url,"new") if os.path.exists(html_cache_path): try: os.remove(html_cache_path) ntfy.sendMsg(f"html_cache更新成功 {html_cache_path}") except: ntfy.sendMsg(f"html_cache更新失败 {html_cache_path}") #获取html实体数据 et = cls.getHTML(url) #比对数据 count = 1 xpaths = et.xpath(c_xpath) for x in xpaths: if x != not_eq: result.append(x) count +=1 if num != None: try: result = result[num] except: result = None return result