mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
一些小调整
This commit is contained in:
parent
3f1d396b6d
commit
e6d15054b1
@ -15,6 +15,8 @@ from .common import format_html
|
|||||||
|
|
||||||
|
|
||||||
class BaseParser(object):
|
class BaseParser(object):
|
||||||
|
"""所有页面、元素类的基类"""
|
||||||
|
|
||||||
def __call__(self, loc_or_str):
|
def __call__(self, loc_or_str):
|
||||||
return self.ele(loc_or_str)
|
return self.ele(loc_or_str)
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ class BaseParser(object):
|
|||||||
|
|
||||||
|
|
||||||
class BaseElement(BaseParser):
|
class BaseElement(BaseParser):
|
||||||
"""SessionElement 和 DriverElement 的基类"""
|
"""各元素类的基类"""
|
||||||
|
|
||||||
def __init__(self, ele: Union[WebElement, HtmlElement], page=None):
|
def __init__(self, ele: Union[WebElement, HtmlElement], page=None):
|
||||||
self._inner_ele = ele
|
self._inner_ele = ele
|
||||||
@ -85,6 +87,8 @@ class BaseElement(BaseParser):
|
|||||||
|
|
||||||
|
|
||||||
class DrissionElement(BaseElement):
|
class DrissionElement(BaseElement):
|
||||||
|
"""DriverElement 和 SessionElement的基类,但不是ShadowRootElement的基类"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent(self):
|
def parent(self):
|
||||||
"""返回父级元素"""
|
"""返回父级元素"""
|
||||||
@ -210,6 +214,8 @@ class DrissionElement(BaseElement):
|
|||||||
|
|
||||||
|
|
||||||
class BasePage(BaseParser):
|
class BasePage(BaseParser):
|
||||||
|
"""页面类的基类"""
|
||||||
|
|
||||||
def __init__(self, timeout: float = 10):
|
def __init__(self, timeout: float = 10):
|
||||||
"""初始化函数"""
|
"""初始化函数"""
|
||||||
self._url = None
|
self._url = None
|
||||||
|
@ -12,32 +12,74 @@ from typing import Union
|
|||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
|
||||||
|
def get_ele_txt(e) -> str:
|
||||||
|
"""获取元素内所有文本
|
||||||
|
:param e: 元素对象
|
||||||
|
:return: 元素内所有文本
|
||||||
|
"""
|
||||||
|
# 前面无须换行的元素
|
||||||
|
nowrap_list = ('sub', 'em', 'strong', 'a', 'font', 'b', 'span', 's', 'i', 'del', 'ins', 'img', 'td', 'th',
|
||||||
|
'abbr', 'bdi', 'bdo', 'cite', 'code', 'data', 'dfn', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby',
|
||||||
|
'samp', 'small', 'sub', 'time', 'u', 'var', 'wbr', 'button', 'slot', 'content')
|
||||||
|
# 后面添加换行的元素
|
||||||
|
wrap_after_list = ('p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'li', 'blockquote', 'header',
|
||||||
|
'footer', 'address' 'article', 'aside', 'main', 'nav', 'section', 'figcaption', 'summary')
|
||||||
|
# 不获取文本的元素
|
||||||
|
noText_list = ('script', 'style', 'video', 'audio', 'iframe', 'embed', 'noscript', 'canvas', 'template')
|
||||||
|
# 用/t分隔的元素
|
||||||
|
tab_list = ('td', 'th')
|
||||||
|
|
||||||
|
if e.tag in noText_list:
|
||||||
|
return e.raw_text
|
||||||
|
|
||||||
|
def get_node_txt(ele, pre: bool = False):
|
||||||
|
str_list = []
|
||||||
|
tag = ele.tag.lower()
|
||||||
|
|
||||||
|
if tag in noText_list: # 标签内的文本不返回
|
||||||
|
return str_list
|
||||||
|
if tag == 'br':
|
||||||
|
return '\n'
|
||||||
|
if tag == 'pre':
|
||||||
|
pre = True
|
||||||
|
|
||||||
|
nodes = ele.eles('xpath:./text() | *')
|
||||||
|
prev_ele = ''
|
||||||
|
for el in nodes:
|
||||||
|
if isinstance(el, str): # 字符节点
|
||||||
|
if pre:
|
||||||
|
str_list.append(el)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if sub('[ \n]', '', el) != '': # 字符除了回车和空格还有其它内容
|
||||||
|
txt = el
|
||||||
|
if not pre:
|
||||||
|
txt = txt.replace('\n', ' ').strip(' ')
|
||||||
|
txt = sub(r' {2,}', ' ', txt)
|
||||||
|
str_list.append(txt)
|
||||||
|
|
||||||
|
else: # 元素节点
|
||||||
|
if el.tag.lower() not in nowrap_list and str_list and str_list[-1] != '\n': # 元素间换行的情况
|
||||||
|
str_list.append('\n')
|
||||||
|
if el.tag.lower() in tab_list and prev_ele in tab_list: # 表格的行
|
||||||
|
str_list.append('\t')
|
||||||
|
|
||||||
|
str_list.extend(get_node_txt(el, pre))
|
||||||
|
prev_ele = el.tag.lower()
|
||||||
|
|
||||||
|
if tag in wrap_after_list and str_list and str_list[-1] != '\n': # 有些元素后面要添加回车
|
||||||
|
str_list.append('\n')
|
||||||
|
|
||||||
|
return str_list
|
||||||
|
|
||||||
|
re_str = ''.join(get_node_txt(e))
|
||||||
|
return format_html(re_str, False).strip(' \n')
|
||||||
|
|
||||||
|
|
||||||
def str_to_loc(loc: str) -> tuple:
|
def str_to_loc(loc: str) -> tuple:
|
||||||
"""处理元素查找语句 \n
|
"""处理元素查找语句 \n
|
||||||
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n
|
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n
|
||||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||||
示例: \n
|
|
||||||
.ele_class - class等于ele_class的元素 \n
|
|
||||||
.:ele_class - class含有ele_class的元素 \n
|
|
||||||
#ele_id - id等于ele_id的元素 \n
|
|
||||||
#:ele_id - id含有ele_id的元素 \n
|
|
||||||
@class:ele_class - class含有ele_class的元素 \n
|
|
||||||
@class=ele_class - class等于ele_class的元素 \n
|
|
||||||
@class - 带class属性的元素 \n
|
|
||||||
tag:div - div元素 \n
|
|
||||||
tag:div@class:ele_class - class含有ele_class的div元素 \n
|
|
||||||
tag:div@class=ele_class - class等于ele_class的div元素 \n
|
|
||||||
tag:div@text():search_text - 文本含有search_text的div元素 \n
|
|
||||||
tag:div@text()=search_text - 文本等于search_text的div元素 \n
|
|
||||||
text:search_text - 文本含有search_text的元素 \n
|
|
||||||
text=search_text - 文本等于search_text的元素 \n
|
|
||||||
xpath://div[@class="ele_class"] - 用xpath查找 \n
|
|
||||||
css:div.ele_class - 用css selector查找 \n
|
|
||||||
xpath://div[@class="ele_class"] - 等同于 x://div[@class="ele_class"] \n
|
|
||||||
css:div.ele_class - 等同于 c:div.ele_class \n
|
|
||||||
tag:div - 等同于 t:div \n
|
|
||||||
text:search_text - 等同于 tx:search_text \n
|
|
||||||
text=search_text - 等同于 tx=search_text \n
|
|
||||||
"""
|
"""
|
||||||
loc_by = 'xpath'
|
loc_by = 'xpath'
|
||||||
|
|
||||||
@ -115,64 +157,45 @@ def str_to_loc(loc: str) -> tuple:
|
|||||||
return loc_by, loc_str
|
return loc_by, loc_str
|
||||||
|
|
||||||
|
|
||||||
def get_ele_txt(e) -> str:
|
def translate_loc(loc: tuple) -> tuple:
|
||||||
# 前面无须换行的元素
|
"""把By类型的loc元组转换为css selector或xpath类型的 \n
|
||||||
nowrap_list = ('sub', 'em', 'strong', 'a', 'font', 'b', 'span', 's', 'i', 'del', 'ins', 'img', 'td', 'th',
|
:param loc: By类型的loc元组
|
||||||
'abbr', 'bdi', 'bdo', 'cite', 'code', 'data', 'dfn', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby',
|
:return: css selector或xpath类型的loc元组
|
||||||
'samp', 'small', 'sub', 'time', 'u', 'var', 'wbr', 'button', 'slot', 'content')
|
"""
|
||||||
# 后面添加换行的元素
|
if len(loc) != 2:
|
||||||
wrap_after_list = ('p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'li', 'blockquote', 'header',
|
raise ValueError('定位符长度必须为2。')
|
||||||
'footer', 'address' 'article', 'aside', 'main', 'nav', 'section', 'figcaption', 'summary')
|
|
||||||
# 不获取文本的元素
|
|
||||||
noText_list = ('script', 'style', 'video', 'audio', 'iframe', 'embed', 'noscript', 'canvas', 'template')
|
|
||||||
# 用/t分隔的元素
|
|
||||||
tab_list = ('td', 'th')
|
|
||||||
|
|
||||||
if e.tag in noText_list:
|
loc_by = 'xpath'
|
||||||
return e.raw_text
|
|
||||||
|
|
||||||
def get_node_txt(ele, pre: bool = False):
|
if loc[0] == 'xpath':
|
||||||
str_list = []
|
loc_str = loc[1]
|
||||||
tag = ele.tag.lower()
|
|
||||||
|
|
||||||
if tag in noText_list: # script标签内的文本不返回
|
elif loc[0] == 'css selector':
|
||||||
return str_list
|
loc_by = 'css selector'
|
||||||
if tag == 'br':
|
loc_str = loc[1]
|
||||||
return '\n'
|
|
||||||
if tag == 'pre':
|
|
||||||
pre = True
|
|
||||||
|
|
||||||
nodes = ele.eles('xpath:./text() | *')
|
elif loc[0] == 'id':
|
||||||
prev_ele = ''
|
loc_str = f'//*[@id="{loc[1]}"]'
|
||||||
for el in nodes:
|
|
||||||
if isinstance(el, str): # 字符节点
|
elif loc[0] == 'class name':
|
||||||
if pre:
|
loc_str = f'//*[@class="{loc[1]}"]'
|
||||||
str_list.append(el)
|
|
||||||
|
elif loc[0] == 'link text':
|
||||||
|
loc_str = f'//a[text()="{loc[1]}"]'
|
||||||
|
|
||||||
|
elif loc[0] == 'name':
|
||||||
|
loc_str = f'//*[@name="{loc[1]}"]'
|
||||||
|
|
||||||
|
elif loc[0] == 'tag name':
|
||||||
|
loc_str = f'//{loc[1]}'
|
||||||
|
|
||||||
|
elif loc[0] == 'partial link text':
|
||||||
|
loc_str = f'//a[contains(text(),"{loc[1]}")]'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if sub('[ \n]', '', el) != '': # 字符除了回车和空格还有其它内容
|
raise ValueError('无法识别的定位符。')
|
||||||
txt = el
|
|
||||||
if not pre:
|
|
||||||
txt = txt.replace('\n', ' ').strip(' ')
|
|
||||||
txt = sub(r' {2,}', ' ', txt)
|
|
||||||
str_list.append(txt)
|
|
||||||
|
|
||||||
else: # 元素节点
|
return loc_by, loc_str
|
||||||
if el.tag.lower() not in nowrap_list and str_list and str_list[-1] != '\n': # 元素间换行的情况
|
|
||||||
str_list.append('\n')
|
|
||||||
if el.tag.lower() in tab_list and prev_ele in tab_list: # 表格的行
|
|
||||||
str_list.append('\t')
|
|
||||||
|
|
||||||
str_list.extend(get_node_txt(el, pre))
|
|
||||||
prev_ele = el.tag.lower()
|
|
||||||
|
|
||||||
if tag in wrap_after_list and str_list and str_list[-1] != '\n': # 有些元素后面要添加回车
|
|
||||||
str_list.append('\n')
|
|
||||||
|
|
||||||
return str_list
|
|
||||||
|
|
||||||
re_str = ''.join(get_node_txt(e))
|
|
||||||
return format_html(re_str, False).strip(' \n')
|
|
||||||
|
|
||||||
|
|
||||||
def _make_xpath_str(tag: str, arg: str, val: str, mode: str = 'fuzzy') -> str:
|
def _make_xpath_str(tag: str, arg: str, val: str, mode: str = 'fuzzy') -> str:
|
||||||
@ -232,47 +255,6 @@ def format_html(text: str, trans: bool = True) -> str:
|
|||||||
return text.replace('\xa0', ' ')
|
return text.replace('\xa0', ' ')
|
||||||
|
|
||||||
|
|
||||||
def translate_loc(loc: tuple) -> tuple:
|
|
||||||
"""把By类型的loc元组转换为css selector或xpath类型的 \n
|
|
||||||
:param loc: By类型的loc元组
|
|
||||||
:return: css selector或xpath类型的loc元组
|
|
||||||
"""
|
|
||||||
if len(loc) != 2:
|
|
||||||
raise ValueError('定位符长度必须为2。')
|
|
||||||
|
|
||||||
loc_by = 'xpath'
|
|
||||||
|
|
||||||
if loc[0] == 'xpath':
|
|
||||||
loc_str = loc[1]
|
|
||||||
|
|
||||||
elif loc[0] == 'css selector':
|
|
||||||
loc_by = 'css selector'
|
|
||||||
loc_str = loc[1]
|
|
||||||
|
|
||||||
elif loc[0] == 'id':
|
|
||||||
loc_str = f'//*[@id="{loc[1]}"]'
|
|
||||||
|
|
||||||
elif loc[0] == 'class name':
|
|
||||||
loc_str = f'//*[@class="{loc[1]}"]'
|
|
||||||
|
|
||||||
elif loc[0] == 'link text':
|
|
||||||
loc_str = f'//a[text()="{loc[1]}"]'
|
|
||||||
|
|
||||||
elif loc[0] == 'name':
|
|
||||||
loc_str = f'//*[@name="{loc[1]}"]'
|
|
||||||
|
|
||||||
elif loc[0] == 'tag name':
|
|
||||||
loc_str = f'//{loc[1]}'
|
|
||||||
|
|
||||||
elif loc[0] == 'partial link text':
|
|
||||||
loc_str = f'//a[contains(text(),"{loc[1]}")]'
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise ValueError('无法识别的定位符。')
|
|
||||||
|
|
||||||
return loc_by, loc_str
|
|
||||||
|
|
||||||
|
|
||||||
def clean_folder(folder_path: str, ignore: list = None) -> None:
|
def clean_folder(folder_path: str, ignore: list = None) -> None:
|
||||||
"""清空一个文件夹,除了ignore里的文件和文件夹 \n
|
"""清空一个文件夹,除了ignore里的文件和文件夹 \n
|
||||||
:param folder_path: 要清空的文件夹路径
|
:param folder_path: 要清空的文件夹路径
|
||||||
|
@ -364,7 +364,7 @@ class MixPage(SessionPage, DriverPage, BasePage):
|
|||||||
goal_path: str = None,
|
goal_path: str = None,
|
||||||
rename: str = None,
|
rename: str = None,
|
||||||
file_exists: str = 'rename',
|
file_exists: str = 'rename',
|
||||||
post_data: dict = None,
|
post_data: Union[str, dict] = None,
|
||||||
show_msg: bool = False,
|
show_msg: bool = False,
|
||||||
show_errmsg: bool = False,
|
show_errmsg: bool = False,
|
||||||
retry: int = None,
|
retry: int = None,
|
||||||
@ -376,13 +376,13 @@ class MixPage(SessionPage, DriverPage, BasePage):
|
|||||||
:param goal_path: 存放路径,默认为ini文件中指定的临时文件夹
|
:param goal_path: 存放路径,默认为ini文件中指定的临时文件夹
|
||||||
:param rename: 重命名文件,可不写扩展名
|
:param rename: 重命名文件,可不写扩展名
|
||||||
:param file_exists: 若存在同名文件,可选择 'rename', 'overwrite', 'skip' 方式处理
|
:param file_exists: 若存在同名文件,可选择 'rename', 'overwrite', 'skip' 方式处理
|
||||||
:param post_data: post方式的数据
|
:param post_data: post方式的数据,这个参数不为None时自动转成post方式
|
||||||
:param show_msg: 是否显示下载信息
|
:param show_msg: 是否显示下载信息
|
||||||
:param show_errmsg: 是否显示和抛出异常
|
:param show_errmsg: 是否显示和抛出异常
|
||||||
:param retry: 重试次数
|
:param retry: 重试次数
|
||||||
:param interval: 重试间隔时间
|
:param interval: 重试间隔时间
|
||||||
:param kwargs: 连接参数
|
:param kwargs: 连接参数
|
||||||
:return: 下载是否成功(bool)和状态信息(成功时信息为文件路径)的元组
|
:return: 下载是否成功(bool)和状态信息(成功时信息为文件路径)的元组,跳过时第一位返回None
|
||||||
"""
|
"""
|
||||||
if self.mode == 'd':
|
if self.mode == 'd':
|
||||||
self.cookies_to_session()
|
self.cookies_to_session()
|
||||||
|
@ -267,7 +267,7 @@ class SessionPage(BasePage):
|
|||||||
:param goal_path: 存放路径
|
:param goal_path: 存放路径
|
||||||
:param rename: 重命名文件,可不写扩展名
|
:param rename: 重命名文件,可不写扩展名
|
||||||
:param file_exists: 若存在同名文件,可选择 'rename', 'overwrite', 'skip' 方式处理
|
:param file_exists: 若存在同名文件,可选择 'rename', 'overwrite', 'skip' 方式处理
|
||||||
:param post_data: post方式的数据
|
:param post_data: post方式的数据,这个参数不为None时自动转成post方式
|
||||||
:param show_msg: 是否显示下载信息
|
:param show_msg: 是否显示下载信息
|
||||||
:param show_errmsg: 是否抛出和显示异常
|
:param show_errmsg: 是否抛出和显示异常
|
||||||
:param retry: 重试次数
|
:param retry: 重试次数
|
||||||
@ -285,7 +285,7 @@ class SessionPage(BasePage):
|
|||||||
if 'timeout' not in kwargs:
|
if 'timeout' not in kwargs:
|
||||||
kwargs['timeout'] = 20
|
kwargs['timeout'] = 20
|
||||||
|
|
||||||
mode = 'post' if post_data else 'get'
|
mode = 'post' if post_data is not None else 'get'
|
||||||
# 生成的response不写入self._response,是临时的
|
# 生成的response不写入self._response,是临时的
|
||||||
r, info = self._make_response(file_url, mode=mode, data=post_data, show_errmsg=show_errmsg, **kwargs)
|
r, info = self._make_response(file_url, mode=mode, data=post_data, show_errmsg=show_errmsg, **kwargs)
|
||||||
|
|
||||||
@ -496,15 +496,15 @@ class SessionPage(BasePage):
|
|||||||
return r, 'Success'
|
return r, 'Success'
|
||||||
|
|
||||||
|
|
||||||
def _get_download_file_name(url, headers) -> str:
|
def _get_download_file_name(url, response) -> str:
|
||||||
"""从headers或url中获取文件名,如果获取不到,生成一个随机文件名
|
"""从headers或url中获取文件名,如果获取不到,生成一个随机文件名
|
||||||
:param url: 文件url
|
:param url: 文件url
|
||||||
:param headers: 返回的headers
|
:param response: 返回的response
|
||||||
:return: 下载文件的文件名
|
:return: 下载文件的文件名
|
||||||
"""
|
"""
|
||||||
file_name = ''
|
file_name = ''
|
||||||
charset = ''
|
charset = ''
|
||||||
content_disposition = headers.get('content-disposition', '').replace(' ', '')
|
content_disposition = response.headers.get('content-disposition', '').replace(' ', '')
|
||||||
|
|
||||||
# 使用header里的文件名
|
# 使用header里的文件名
|
||||||
if content_disposition:
|
if content_disposition:
|
||||||
@ -516,16 +516,13 @@ def _get_download_file_name(url, headers) -> str:
|
|||||||
else:
|
else:
|
||||||
file_name = txt[0]
|
file_name = txt[0]
|
||||||
|
|
||||||
else: # 文件名没有编码方式
|
else: # 文件名没带编码方式
|
||||||
txt = search(r'filename="?([^";]+)', content_disposition)
|
txt = search(r'filename="?([^";]+)', content_disposition)
|
||||||
if txt:
|
if txt:
|
||||||
file_name = txt.group(1)
|
file_name = txt.group(1)
|
||||||
|
|
||||||
# 获取编码(如有)
|
# 获取编码(如有)
|
||||||
content_type = headers.get('content-type', '').lower()
|
charset = response.encoding
|
||||||
charset = search(r'charset[=: ]*(.*)?[;]', content_type)
|
|
||||||
if charset:
|
|
||||||
charset = charset.group(1)
|
|
||||||
|
|
||||||
file_name = file_name.strip("'")
|
file_name = file_name.strip("'")
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ from .session_element import make_session_ele
|
|||||||
|
|
||||||
|
|
||||||
class ShadowRootElement(BaseElement):
|
class ShadowRootElement(BaseElement):
|
||||||
|
"""ShadowRootElement是用于处理ShadowRoot的类,使用方法和DriverElement基本一致"""
|
||||||
|
|
||||||
def __init__(self, inner_ele: WebElement, parent_ele: DriverElement):
|
def __init__(self, inner_ele: WebElement, parent_ele: DriverElement):
|
||||||
super().__init__(inner_ele, parent_ele.page)
|
super().__init__(inner_ele, parent_ele.page)
|
||||||
self.parent_ele = parent_ele
|
self.parent_ele = parent_ele
|
||||||
@ -193,22 +195,6 @@ def str_to_css_loc(loc: str) -> tuple:
|
|||||||
"""处理元素查找语句 \n
|
"""处理元素查找语句 \n
|
||||||
查找方式:属性、tag name及属性、文本、css selector \n
|
查找方式:属性、tag name及属性、文本、css selector \n
|
||||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||||
示例: \n
|
|
||||||
.ele_class - class为ele_class的元素 \n
|
|
||||||
.:ele_class - class含有ele_class的元素 \n
|
|
||||||
#ele_id - id为ele_id的元素 \n
|
|
||||||
#:ele_id - id含有ele_id的元素 \n
|
|
||||||
@class:ele_class - class含有ele_class的元素 \n
|
|
||||||
@class=ele_class - class等于ele_class的元素 \n
|
|
||||||
@class - 带class属性的元素 \n
|
|
||||||
tag:div - div元素 \n
|
|
||||||
tag:div@class:ele_class - class含有ele_class的div元素 \n
|
|
||||||
tag:div@class=ele_class - class等于ele_class的div元素 \n
|
|
||||||
tag:div@text():search_text - 文本含有search_text的div元素 \n
|
|
||||||
tag:div@text()=search_text - 文本等于search_text的div元素 \n
|
|
||||||
text:search_text - 文本含有search_text的元素 \n
|
|
||||||
text=search_text - 文本等于search_text的元素 \n
|
|
||||||
css:div.ele_class - 符合css selector的元素 \n
|
|
||||||
"""
|
"""
|
||||||
loc_by = 'css selector'
|
loc_by = 'css selector'
|
||||||
|
|
||||||
|
@ -4,6 +4,3 @@
|
|||||||
"""
|
"""
|
||||||
from .session_element import make_session_ele
|
from .session_element import make_session_ele
|
||||||
from .easy_set import get_match_driver
|
from .easy_set import get_match_driver
|
||||||
|
|
||||||
# TODO: 保存cookies到文件
|
|
||||||
# TODO: 从文件读取cookies
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user