Crawler_controller.py 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. import threading
  2. import time
  3. import hashlib
  4. from time import sleep
  5. import re as regular
  6. import bs4
  7. import requests
  8. from selenium import webdriver
  9. from selenium.webdriver.common.action_chains import ActionChains
  10. from selenium.webdriver.common.keys import Keys
  11. from Crawler import Information_storage
  12. keys_name_dict = {
  13. "ctrl": Keys.CONTROL,
  14. "shift": Keys.SHIFT,
  15. "tab": Keys.TAB,
  16. "left_ctrl": Keys.LEFT_CONTROL,
  17. "left_shift": Keys.LEFT_SHIFT,
  18. "left_alt": Keys.LEFT_ALT,
  19. "ALT": Keys.ALT,
  20. "enter": Keys.ENTER,
  21. "return": Keys.RETURN,
  22. "backspace": Keys.BACKSPACE,
  23. "del": Keys.DELETE,
  24. "pgup": Keys.PAGE_UP,
  25. "pgdn": Keys.PAGE_DOWN,
  26. "home": Keys.HOME,
  27. "end": Keys.END,
  28. "esc": Keys.CANCEL,
  29. "insert": Keys.INSERT,
  30. "meta": Keys.META,
  31. "up": Keys.UP,
  32. "down": Keys.DOWN,
  33. "right": Keys.RIGHT,
  34. "left": Keys.LEFT,
  35. } # 键-值映射
  36. for i in range(1, 13): # F1 - F12按键
  37. keys_name_dict[f"f{i}"] = eval(f"Keys.F{i}")
  38. data_base = Information_storage.DatabaseController()
  39. class Page:
  40. def __init__(self, time_out):
  41. self.url = ""
  42. self.user_agent = ""
  43. self.mode = "PAGE"
  44. self.time_out = time_out
  45. def __str__(self):
  46. return f"[{self.time_out}s]{self.mode}-{self.url}:UA>{self.user_agent}"
  47. class RequestsBase(Page):
  48. def init(self, user_agent, url, cookies):
  49. if user_agent == "":
  50. user_agent = (
  51. f'--user-agent ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
  52. f'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36 Edg/80.0.361.66"'
  53. )
  54. self.user_agent = user_agent
  55. self.headers = {
  56. "Accept": "text/html, application/xhtml+xml, image/jxr, */*",
  57. "Accept - Encoding": "gzip, deflate",
  58. "Accept-Language": "zh-Hans-CN, zh-Hans; q=0.5",
  59. "Connection": "Keep-Alive",
  60. "User-Agent": user_agent,
  61. }
  62. self.url = url
  63. self.cookies = cookies
  64. self.new = True
  65. class UrlPost(RequestsBase): # 通过requests的post请求
  66. def __init__(self, url, data, time_out, user_agent="", cookies=None, **kwargs):
  67. super(UrlPost, self).__init__(time_out)
  68. self.mode = "post"
  69. self.data = data
  70. self.requests = requests.post
  71. self.init(user_agent, url, cookies)
  72. def __str__(self):
  73. return super(UrlPost, self).__str__() + f";data>{self.data}"
  74. class UrlGet(RequestsBase): # 通过requests的post请求
  75. def __init__(self, url, time_out, user_agent="", cookies=None, **kwargs):
  76. super(UrlGet, self).__init__(time_out)
  77. self.mode = "simplify_get"
  78. self.requests = requests.get
  79. self.init(user_agent, url, cookies)
  80. class UrlPage(Page):
  81. def __init__(
  82. self,
  83. url,
  84. time_out,
  85. first_run=False,
  86. head=False,
  87. no_plugins=True,
  88. no_js=False,
  89. no_java=False,
  90. no_img=False,
  91. user_agent="",
  92. cookies=None,
  93. new=False,
  94. down_load_dir="",
  95. **kwargs,
  96. ):
  97. super(UrlPage, self).__init__(time_out)
  98. self.url = url
  99. self.mode = "get"
  100. self.options = webdriver.ChromeOptions()
  101. self.cookies = cookies # cookies存储位置
  102. self.new = new # 新键页面or新键浏览器
  103. self.down_load_dir = down_load_dir
  104. self.init(first_run, head, no_plugins, no_js, no_java, no_img, user_agent)
  105. def init(self, first_run, head, no_plugins, no_js, no_java, no_img, user_agent):
  106. self.options.add_argument("disable-infobars") # 不显示
  107. prefs = {
  108. "profile.default_content_settings.popups": 0,
  109. "download.default_directory": self.down_load_dir,
  110. }
  111. self.options.add_experimental_option("prefs", prefs) # 下载设置
  112. if first_run:
  113. self.options.add_argument("-first run")
  114. if head: # 无头设置
  115. self.options.add_argument("--headless")
  116. self.options.add_argument("--disable-gpu")
  117. if no_plugins:
  118. self.options.add_argument("--disable-plugins")
  119. if no_js:
  120. self.options.add_argument("--disable-javascript")
  121. if no_java:
  122. self.options.add_argument("--disable-java")
  123. if no_img:
  124. self.options.add_argument("blink-settings=imagesEnabled=false")
  125. if user_agent == "":
  126. user_agent = (
  127. f'user-agent ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
  128. f'Chrome/80.0.3987.132 Safari/537.36"'
  129. )
  130. # self.options.add_argument(f'--user-agent ="{UA}"')
  131. self.user_agent = user_agent
  132. def __str__(self):
  133. return f"{self.mode}-{self.url}:UA>{self.user_agent}"
  134. class Url: # url管理器
  135. url_count = 0 # url处理器个数
  136. def __init__(self, dic=f"", dic_run=f""):
  137. Url.url_count += 1
  138. self.save_dir = dic
  139. dic += f"/url[{Url.url_count}].cot_url"
  140. dic_run += f"/url_run[{Url.url_count}].cot_url"
  141. self.dir = dic
  142. self.dir_run = dic_run
  143. self.file = open(dic, "a") # 写入url_history的文件
  144. self.file_run = open(dic_run, "a") # 写入已读url文件
  145. self.url_list = [] # 待读url
  146. self.url_history = [] # url历史
  147. self.filter = {} # 过滤函数
  148. def close(self):
  149. self.file.close()
  150. self.file_run.close()
  151. def filter_func(self, url, **kwargs): # url过滤系统
  152. for i in self.filter:
  153. if not self.filter[i](url):
  154. return False
  155. return True
  156. def add_filter_func(self, func, name): # 添加过滤函数
  157. self.filter[name] = func
  158. def del_filter_func(self, index): # 删除过滤函数
  159. del self.filter[list(self.filter.keys())[index]]
  160. def return_filter_func(self):
  161. return list(self.filter.keys())
  162. def add_url(self, url, func, data=None, **kwargs): # 添加url
  163. if func == "":
  164. func = "get"
  165. if func == "get":
  166. url_ = url
  167. else:
  168. url_ = url + str(data)
  169. if url_ not in self.url_history and self.filter_func(
  170. url, func=func
  171. ): # 1.url不存在历史,2.url满足筛选条件
  172. if func == "get":
  173. self.url_list.append(
  174. UrlPage(url=url, **kwargs, down_load_dir=self.dir)
  175. ) # 添加到待取得url
  176. elif func == "simplify_get":
  177. self.url_list.append(
  178. UrlGet(url=url, **kwargs, down_load_dir=self.dir)
  179. ) # 添加到待取得url
  180. else:
  181. self.url_list.append(UrlPost(url=url, data=data, **kwargs)) # 添加到待取得url
  182. self.url_history.append(url_) # 添加到历史url
  183. self.__out_url_history(url_) # 输出历史url
  184. return True # 写入成功
  185. return False # 写入失败
  186. def del_url(self, index): # 删除url
  187. self.__out_url_run(f"DELETE {self.url_list[index]}")
  188. del self.url_list[index]
  189. def get_url(self) -> (UrlPage, UrlPost): # 取得url
  190. url_page = self.url_list[0]
  191. self.__out_url_run(url_page.url)
  192. del self.url_list[0]
  193. return url_page
  194. def __out_url_history(self, url): # 输出url历史
  195. self.file.write(f"{url}\n")
  196. self.file.flush()
  197. def __out_url_run(self, url): # 输出已经运行的url
  198. self.file_run.write(f"{url}\n")
  199. self.file_run.flush()
  200. def is_finish(self):
  201. return len(self.url_list) == 0
  202. def return_url(self):
  203. return self.url_list.copy()
  204. def return_url_history(self):
  205. return self.url_history.copy()
  206. class PageDownloader:
  207. downloader_count = 0
  208. def __init__(self, url: Url, dic=""):
  209. self.url = url
  210. self.dir = dic
  211. self.log = Information_storage.Log(dic)
  212. PageDownloader.downloader_count += 1
  213. self.page_source_dict = {} # 页面保存信息
  214. self.cookie_Thread = None # 子进程
  215. self.browser = None
  216. self.cookie_dict = {}
  217. self.cookie_dict_list = {} # sele的cookies
  218. self.last_mode = ""
  219. def close(self):
  220. self.log.close()
  221. def stop(self):
  222. try:
  223. self.break_ = False
  224. self.browser.quit()
  225. self.last_mode = ""
  226. except BaseException:
  227. pass
  228. def start_to_run(self, *args, func_cookie): # 用get请求url ->得到一个页面信息
  229. self.break_ = False
  230. self.page_source_dict = {}
  231. self.url_text = self.url.get_url() # 获取一个url
  232. url = self.url_text.url
  233. if self.url_text.mode == "get":
  234. if self.url_text.new and self.last_mode == "get": # 重新启动
  235. self.browser.quit()
  236. self.browser = webdriver.Chrome(chrome_options=self.url_text.options)
  237. try:
  238. self.browser.set_page_load_timeout(self.url_text.time_out) # 设置页面加载超时
  239. self.browser.set_script_timeout(self.url_text.time_out) # 设置页面异步js执行超时
  240. self.browser.get(url)
  241. except BaseException:
  242. self.browser = webdriver.Chrome(chrome_options=self.url_text.options)
  243. self.browser.set_page_load_timeout(self.url_text.time_out) # 设置页面加载超时
  244. self.browser.set_script_timeout(self.url_text.time_out) # 设置页面异步js执行超时
  245. self.browser.get(url)
  246. try:
  247. if not self.url_text.new:
  248. raise Exception
  249. list_ = self.cookie_dict_list[self.url_text.cookies]
  250. self.monitoring_clear_cookier()
  251. try:
  252. for i in list_:
  253. self.monitoring_add_cookies(i)
  254. except BaseException:
  255. pass
  256. except BaseException:
  257. pass
  258. self.start_cookies(func_cookie, url)
  259. else: # requests模式
  260. if self.last_mode == "get":
  261. try:
  262. self.browser.quit()
  263. except BaseException:
  264. pass
  265. try:
  266. args = {"cookies": self.cookie_dict[self.url_text.cookies]}
  267. func_cookie([args["cookies"]])
  268. except BaseException:
  269. args = {}
  270. func_cookie([])
  271. if self.url_text.func == "post":
  272. args["data"] = self.url_text.data
  273. self.browser = self.url_text.requests(
  274. url,
  275. headers=self.url_text.headers,
  276. **args,
  277. timeout=self.url_text.time_out,
  278. )
  279. self.cookie_dict[url] = requests.utils.dict_from_cookiejar(
  280. self.browser.cookies
  281. ) # 保存cookies
  282. func_cookie([self.cookie_dict[url]])
  283. self.last_mode = self.url_text.func
  284. self.parser.browser = self.browser
  285. self.parser.init(url)
  286. return self.browser
  287. def start_cookies(self, func_cookie, url):
  288. self.break_ = True
  289. def update_cookie():
  290. nonlocal self
  291. while self.break_:
  292. try:
  293. cookies = self.browser.get_cookies()
  294. func_cookie(cookies) # 与GUI通信显示cookie
  295. self.cookie_dict[url] = cookies
  296. time.sleep(0.5)
  297. except BaseException:
  298. pass
  299. self.cookie_Thread = threading.Thread(target=update_cookie)
  300. self.cookie_Thread.start()
  301. def monitoring_del_cookies(self, name): # 删除指定cookies
  302. browser = self.browser
  303. browser.delete_cookie(name)
  304. def monitoring_clear_cookier(self): # 清空cookies
  305. browser = self.browser
  306. browser.delete_all_cookies()
  307. def monitoring_add_cookies(self, cookies: dict): # 新增cookies
  308. browser = self.browser
  309. browser.add_cookie(cookies)
  310. def monitoring_update_cookies(self, name, cookies: dict):
  311. browser = self.browser
  312. cookies_list = browser.get_cookies()
  313. for i in cookies_list:
  314. if i.get("name", None) == name:
  315. browser.delete_cookie(name) # 删除原来cookies
  316. i.update(cookies)
  317. browser.add_cookie(i)
  318. return
  319. raise Exception
  320. def set_page_parser(self, parser):
  321. self.parser = parser
  322. self.parser.browser = self.browser
  323. self.parser.url = self.url
  324. self.parser.dir = self.dir
  325. self.parser.log = self.log
  326. class PageParser:
  327. def __init__(self, downloader: PageDownloader):
  328. self.downloader = downloader
  329. self.downloader.set_page_parser(self)
  330. self.func_list = []
  331. self.func_dict = {}
  332. self.n = 0
  333. self.init()
  334. def init(self, url=""):
  335. self.element_dict = {} # 记录属性的名字
  336. self.url_text = url
  337. def add_base(self, func): # 装饰器
  338. def wrap(browser=None, num=None, name=None, *args, **kwargs) -> bool:
  339. try:
  340. func(browser=browser, num=num, name=name, *args, **kwargs)
  341. return True
  342. except BaseException:
  343. return False
  344. return wrap
  345. def add_func(self, name, func):
  346. self.func_list.append(f"{name}[{self.n}]")
  347. self.func_dict[f"{name}[{self.n}]"] = func
  348. self.n += 1
  349. def tra_func(self):
  350. self.func_list = []
  351. self.func_dict = {}
  352. self.n = 0
  353. def del_func(self, index, end=False):
  354. if end:
  355. index = len(self.func_list) - index - 1
  356. del self.func_dict[self.func_list[index]]
  357. self.func_list[index] = "Func_have_been_del"
  358. self.func_dict["Func_have_been_del"] = lambda *args, **kwargs: None
  359. def return_func(self, only=True):
  360. if only:
  361. return self.func_list.copy()
  362. else:
  363. return [
  364. f"var[{index}]@ {i}" for index, i in enumerate(self.func_list.copy())
  365. ]
  366. def find_id(self, id, not_all=False, **kwargs):
  367. @self.add_base
  368. def find(browser, num, name, *args, **kwargs):
  369. nonlocal self, id
  370. if browser is None:
  371. browser = self.browser
  372. if not_all:
  373. self.element_dict[f"{name}[{num}]"] = [
  374. browser.find_element_by_id(id)
  375. ] # 返回必须是list
  376. else:
  377. self.element_dict[f"{name}[{num}]"] = browser.find_elements_by_id(id)
  378. self.add_func(f"find_ID:{id}", find) # 添加func
  379. def find_class(self, class_name, not_all=False, **kwargs):
  380. @self.add_base
  381. def find(browser, num, name, *args, **kwargs):
  382. nonlocal self, class_name
  383. if browser is None:
  384. browser = self.browser
  385. if not_all:
  386. self.element_dict[f"{name}[{num}]"] = [
  387. browser.find_element_by_class_name(class_name)
  388. ] # 返回必须是list
  389. else:
  390. self.element_dict[
  391. f"{name}[{num}]"
  392. ] = browser.find_elements_by_class_name(
  393. class_name
  394. ) # 返回必须是list
  395. self.add_func(f"find_class:{class_name}", find) # 添加func
  396. def find_name(self, name_, not_all=False, **kwargs):
  397. @self.add_base
  398. def find(browser, num, name, *args, **kwargs):
  399. nonlocal self, name_
  400. if browser is None:
  401. browser = self.browser
  402. if not_all:
  403. self.element_dict[f"{name}[{num}]"] = [
  404. browser.find_element_by_name(name_)
  405. ] # 返回必须是list
  406. else:
  407. self.element_dict[f"{name}[{num}]"] = browser.find_elements_by_name(
  408. name_
  409. ) # 返回必须是list
  410. self.add_func(f"find_name:{name_}", find) # 添加func
  411. def find_xpath(self, xpath, not_all=False, **kwargs):
  412. @self.add_base
  413. def find(browser, num, name, *args, **kwargs):
  414. nonlocal self, xpath
  415. if browser is None:
  416. browser = self.browser
  417. if not_all:
  418. self.element_dict[f"{name}[{num}]"] = [
  419. browser.find_element_by_xpath(xpath)
  420. ] # 返回必须是list
  421. else:
  422. self.element_dict[f"{name}[{num}]"] = browser.find_elements_by_xpath(
  423. xpath
  424. ) # 返回必须是list
  425. self.add_func(f"find_xpath:{xpath}", find) # 添加func
  426. def find_css(self, css_selector, not_all=False, **kwargs):
  427. @self.add_base
  428. def find(browser, num, name, *args, **kwargs):
  429. nonlocal self, css_selector
  430. if browser is None:
  431. browser = self.browser
  432. if not_all:
  433. self.element_dict[f"{name}[{num}]"] = [
  434. browser.find_element_by_css_selector(css_selector)
  435. ] # 返回必须是list
  436. else:
  437. self.element_dict[
  438. f"{name}[{num}]"
  439. ] = browser.find_elements_by_css_selector(
  440. css_selector
  441. ) # 返回必须是list
  442. self.add_func(f"find_css:{css_selector}", find) # 添加func
  443. def find_tag_name(self, tag_name, not_all=False, **kwargs):
  444. @self.add_base
  445. def find(browser, num, name, *args, **kwargs):
  446. nonlocal self, tag_name
  447. if browser is None:
  448. browser = self.browser
  449. if not_all:
  450. self.element_dict[f"{name}[{num}]"] = [
  451. browser.find_element_by_tag_name(tag_name)
  452. ] # 返回必须是list
  453. else:
  454. self.element_dict[f"{name}[{num}]"] = browser.find_elements_by_tag_name(
  455. tag_name
  456. ) # 返回必须是list
  457. self.add_func(f"find_tagName:{tag_name}", find) # 添加func\
  458. def find_link_text(self, link_text, not_all=False, **kwargs): # 匹配link
  459. @self.add_base
  460. def find(browser, num, name, *args, **kwargs):
  461. nonlocal self, link_text
  462. if browser is None:
  463. browser = self.browser
  464. if not_all:
  465. self.element_dict[f"{name}[{num}]"] = [
  466. browser.find_element_by_link_text(link_text)
  467. ] # 返回必须是list
  468. else:
  469. self.element_dict[
  470. f"{name}[{num}]"
  471. ] = browser.find_elements_by_link_text(
  472. link_text
  473. ) # 返回必须是list
  474. self.add_func(f"find_link_text:{link_text}", find) # 添加func
  475. def find_partial_link_text(
  476. self, partial_link_text, not_all=False, **kwargs
  477. ): # 模糊匹配
  478. @self.add_base
  479. def find(browser, num, name, *args, **kwargs):
  480. nonlocal self, partial_link_text
  481. if browser is None:
  482. browser = self.browser
  483. if not_all:
  484. self.element_dict[f"{name}[{num}]"] = [
  485. browser.find_element_by_partial_link_text(partial_link_text)
  486. ] # 返回必须是list
  487. else:
  488. self.element_dict[f"{name}[{num}]"] = [
  489. browser.find_element_by_partial_link_text(partial_link_text)
  490. ] # 返回必须是list
  491. self.add_func(f"find_partial_link_text:{partial_link_text}", find) # 添加func
  492. def find_switch_to_alert(self, *args, **kwargs): # 定位弹出框
  493. @self.add_base
  494. def find(browser, num, name, *args, **kwargs):
  495. nonlocal self
  496. if browser is None:
  497. browser = self.browser
  498. self.element_dict[f"{name}[{num}]"] = [browser.switch_to.alert()]
  499. self.add_func(f"find_alert", find) # 添加func
  500. def find_switch_to_active_element(self, *args, **kwargs): # 定位焦点元素
  501. @self.add_base
  502. def find(browser, num, name, *args, **kwargs):
  503. nonlocal self
  504. if browser is None:
  505. browser = self.browser
  506. self.element_dict[f"{name}[{num}]"] = [browser.switch_to.active_element()]
  507. self.add_func(f"active_element", find) # 添加func
  508. def find_switch_to_frame(self, reference, is_id=False, *args, **kwargs): # 定位Frame
  509. @self.add_base
  510. def find(browser, num, name, *args, **kwargs):
  511. nonlocal self, reference, is_id
  512. if browser is None:
  513. browser = self.browser
  514. if reference is None:
  515. self.element_dict[f"{name}[{num}]"] = [
  516. browser.default_content()
  517. ] # 回到主文档
  518. elif reference == "":
  519. self.element_dict[f"{name}[{num}]"] = [browser.parent_frame()] # 回到父文档
  520. else:
  521. if is_id:
  522. reference = int(reference)
  523. self.element_dict[f"{name}[{num}]"] = [
  524. browser.switch_to.frame(str(reference))
  525. ] # 定位进入文档
  526. func_name = {None: "主文档", "": "父文档"}.get(reference, reference)
  527. self.add_func(f"find_frame:{func_name}", find) # 添加func
  528. def send_keys(self, text, element_value, index=0, **kwargs): # 输入文字
  529. @self.add_base
  530. def action(*args, **kwargs):
  531. nonlocal self
  532. self.element_dict[element_value][index].send_keys(text)
  533. self.add_func(f"sent_text:{text}>{element_value}[{index}]", action) # 添加func
  534. def authentication(
  535. self, user, passwd, element_value, index=0, **kwargs
  536. ): # 输入验证(User&Password)
  537. @self.add_base
  538. def action(*args, **kwargs):
  539. nonlocal self
  540. self.element_dict[element_value][index].authenticate(user, passwd)
  541. self.add_func(
  542. f"Authentication:{user};{passwd}>{element_value}[{index}]", action
  543. ) # 添加func
  544. def clear(self, element_value, index=0, **kwargs): # 清空文本
  545. @self.add_base
  546. def action(*args, **kwargs):
  547. nonlocal self
  548. self.element_dict[element_value][index].clear()
  549. self.add_func(f"clear_text>{element_value}[{index}]", action) # 添加func
  550. def click(self, element_value, index=0, **kwargs): # 点击按钮
  551. @self.add_base
  552. def action(*args, **kwargs):
  553. nonlocal self
  554. self.element_dict[element_value][index].click()
  555. self.add_func(f"click>{element_value}[{index}]", action) # 添加func
  556. def accept(self, element_value, index=0, **kwargs): # 点击确定(弹出框)
  557. @self.add_base
  558. def action(*args, **kwargs):
  559. nonlocal self
  560. self.element_dict[element_value][index].accept()
  561. self.add_func(f"accept>{element_value}[{index}]", action) # 添加func
  562. def dismiss(self, element_value, index=0, **kwargs): # 点击取消(弹出框)
  563. @self.add_base
  564. def action(*args, **kwargs):
  565. nonlocal self
  566. self.element_dict[element_value][index].dismiss()
  567. self.add_func(f"dismiss>{element_value}[{index}]", action) # 添加func
  568. def submit(self, element_value, index=0, **kwargs): # 提交表单
  569. @self.add_base
  570. def action(*args, **kwargs):
  571. nonlocal self
  572. self.element_dict[element_value][index].submit()
  573. self.add_func(f"submit>{element_value}[{index}]", action) # 添加func
  574. def deselect_by_index(
  575. self, element_value, deselect, index=0, **kwargs
  576. ): # 根据index取消选择
  577. @self.add_base
  578. def action(*args, **kwargs):
  579. nonlocal self
  580. self.element_dict[element_value][index].deselect_by_index(int(deselect))
  581. self.add_func(
  582. f"deselect_by_index:{deselect}>{element_value}[{index}]", action
  583. ) # 添加func
  584. def deselect_by_text(
  585. self, element_value, deselect, index=0, **kwargs
  586. ): # 根据text取消选择
  587. @self.add_base
  588. def action(*args, **kwargs):
  589. nonlocal self
  590. self.element_dict[element_value][index].deselect_by_visible_text(deselect)
  591. self.add_func(
  592. f"deselect_by_text:{deselect}>{element_value}[{index}]", action
  593. ) # 添加func
  594. def deselect_by_value(
  595. self, element_value, deselect, index=0, **kwargs
  596. ): # 根据value取消选择
  597. @self.add_base
  598. def action(*args, **kwargs):
  599. nonlocal self
  600. self.element_dict[element_value][index].deselect_by_value(deselect)
  601. self.add_func(
  602. f"deselect_by_value:{deselect}>{element_value}[{index}]", action
  603. ) # 添加func
  604. def select_by_index(self, element_value, deselect, index=0, **kwargs): # 根据index选择
  605. @self.add_base
  606. def action(*args, **kwargs):
  607. nonlocal self
  608. self.element_dict[element_value][index].select_by_index(int(deselect))
  609. self.add_func(
  610. f"select_by_index:{deselect}>{element_value}[{index}]", action
  611. ) # 添加func
  612. def select_by_text(self, element_value, deselect, index=0, **kwargs): # 根据text选择
  613. @self.add_base
  614. def action(*args, **kwargs):
  615. nonlocal self
  616. self.element_dict[element_value][index].select_by_visible_text(deselect)
  617. self.add_func(
  618. f"select_by_text:{deselect}>{element_value}[{index}]", action
  619. ) # 添加func
  620. def select_by_value(self, element_value, deselect, index=0, **kwargs): # 根据value选择
  621. @self.add_base
  622. def action(*args, **kwargs):
  623. nonlocal self
  624. self.element_dict[element_value][index].select_by_value(deselect)
  625. self.add_func(
  626. f"select_by_value:{deselect}>{element_value}[{index}]", action
  627. ) # 添加func
  628. def back(self, **kwargs): # 返回
  629. @self.add_base
  630. def action(*args, **kwargs):
  631. nonlocal self
  632. self.browser.back()
  633. self.add_func(f"BACK", action)
  634. def forward(self, **kwargs): # 前进
  635. @self.add_base
  636. def action(*args, **kwargs):
  637. nonlocal self
  638. self.browser.forward()
  639. self.add_func(f"FORWARD", action)
  640. def refresh(self, **kwargs): # 刷新
  641. @self.add_base
  642. def action(*args, **kwargs):
  643. nonlocal self
  644. self.browser.refresh()
  645. self.add_func(f"REFRESH", action)
  646. def wait_sleep(self, time: int = 2, **kwargs): # 暴力等待
  647. @self.add_base
  648. def action(*args, **kwargs):
  649. nonlocal self
  650. sleep(time)
  651. self.add_func(f"WAIT:{time}s", action)
  652. def set_wait(self, time: int = 2, **kwargs): # 隐式等待
  653. @self.add_base
  654. def action(*args, **kwargs):
  655. nonlocal self
  656. sleep(time)
  657. self.add_func(f"Loading_wait:{time}s", action)
  658. def run_js(self, js, **kwargs):
  659. @self.add_base
  660. def action(num, name, *args, **kwargs):
  661. nonlocal self
  662. get = self.browser.execute_script(js)
  663. if hasattr(get, "__getitem__"): # 可切片
  664. self.element_dict[f"{name}[{num}]"] = get # 返回必须是list
  665. else:
  666. self.element_dict[f"{name}[{num}]"] = [get]
  667. self.add_func(f"run_js:{js}", action)
  668. def to_text(self, **kwargs): # 获取网页源码
  669. @self.add_base
  670. def action(num, name, *args, **kwargs):
  671. nonlocal self
  672. try:
  673. self.element_dict[f"{name}[{num}]"] = [
  674. self.browser.page_source,
  675. self.now_url,
  676. ]
  677. except BaseException:
  678. self.element_dict[f"{name}[{num}]"] = [
  679. self.browser.text,
  680. self.now_url,
  681. ] # request
  682. self.add_func(f"get_page_source", action)
  683. def out_html(self, element_value, **kwargs): # 输出网页源码
  684. @self.add_base
  685. def action(*args, **kwargs):
  686. nonlocal self
  687. md5 = hashlib.md5() # 应用MD5算法
  688. md5.update(f"{time.time()}_{self.now_url}".encode("utf-8"))
  689. name = md5.hexdigest()
  690. save_dir = self.dir + "/" + name + ".cotan_source"
  691. print(save_dir)
  692. with open(save_dir, "w") as f:
  693. f.write(self.element_dict[element_value][0])
  694. with open(save_dir + ".CoTanURL", "w") as f:
  695. f.write(self.element_dict[element_value][1])
  696. self.add_func(f"write_html<{element_value}", action)
  697. def del_all_cookies(self, **kwargs): # 删除所有曲奇
  698. @self.add_base
  699. def action(*args, **kwargs):
  700. nonlocal self
  701. self.browser.delete_all_cookies()
  702. self.add_func(f"del_all_cookies", action)
  703. def del_cookies(self, cookies_name, **kwargs): # 删除指定曲奇
  704. @self.add_base
  705. def action(*args, **kwargs):
  706. nonlocal self
  707. self.browser.delete_cookie(cookies_name)
  708. self.add_func(f"del_cookies:{cookies_name}", action)
  709. def add_cookies(self, cookies, **kwargs): # 添加指定曲奇
  710. @self.add_base
  711. def action(*args, **kwargs):
  712. nonlocal self
  713. self.browser.add_cookie(cookies)
  714. self.add_func(f"add_cookies:{cookies}", action)
  715. def update_cookies(self, cookies_name, cookies, **kwargs): # 更新曲奇
  716. @self.add_base
  717. def action(*args, **kwargs):
  718. nonlocal self
  719. now_cookies = self.browser.get_cookie(cookies_name)
  720. self.browser.delete_cookie(cookies_name)
  721. now_cookies.update(cookies)
  722. self.browser.add_cookie(now_cookies)
  723. self.add_func(f"add_cookies:{cookies}", action)
  724. def get_cookies(self, cookies_name, **kwargs): # 获取指定曲奇
  725. @self.add_base
  726. def action(num, name, *args, **kwargs):
  727. nonlocal self
  728. self.element_dict[f"{name}[{num}]"] = [
  729. self.browser.get_cookie(cookies_name)
  730. ]
  731. self.add_func(f"get_cookies:{cookies_name}", action)
  732. def get_all_cookies(self, **kwargs): # 获取所有曲奇
  733. @self.add_base
  734. def action(num, name, *args, **kwargs):
  735. nonlocal self
  736. self.element_dict[f"{name}[{num}]"] = self.browser.get_cookie()
  737. self.add_func(f"get_all_cookies", action)
  738. def make_bs(self, element_value, **kwargs): # 解析成bs4对象
  739. @self.add_base
  740. def action(num, name, *args, **kwargs):
  741. nonlocal self
  742. self.element_dict[f"{name}[{num}]"] = [
  743. bs4.BeautifulSoup(self.element_dict[element_value][0], "html.parser")
  744. ]
  745. self.add_func(f"Parsing:{element_value}", action) # 添加func
  746. def list_slicing(self, index: (slice, int), element_value):
  747. if isinstance(index, int):
  748. return [self.element_dict[element_value][index]]
  749. else:
  750. return self.element_dict[element_value][index]
  751. def to_database(
  752. self, element_value, index, data: (str, list), database_name: str, **kwargs
  753. ): # 传入data Base
  754. @self.add_base
  755. def action(*args, **kwargs):
  756. global data_base
  757. nonlocal self
  758. iter_list = self.list_slicing(index, element_value)
  759. for bs in iter_list:
  760. new = []
  761. for i in data:
  762. if i == "$name&":
  763. new.append(bs.name)
  764. elif i == "$self&":
  765. new.append(str(bs).replace("\n", ""))
  766. elif i == "$string$":
  767. new.append(str(bs.string).replace("\n", ""))
  768. else:
  769. new.append(bs.attrs.get(i, ""))
  770. data_base.add_database(database_name, new)
  771. self.add_func(
  772. f"DataBase:{data}<{element_value}[{index}]>{database_name}", action
  773. ) # 添加func
  774. def to_database_by_re(
  775. self, element_value, index, data: str, database_name: str, **kwargs
  776. ): # 通过正则,传入dataBase
  777. data = regular.compile(data)
  778. @self.add_base
  779. def action(*args, **kwargs):
  780. global data_base
  781. nonlocal self
  782. iter_list = self.list_slicing(index, element_value)
  783. for bs in iter_list:
  784. new = regular.findall(data, str(bs))
  785. data_base.add_database(database_name, new)
  786. self.add_func(
  787. f"DataBase:{data}<{element_value}[{index}]>{database_name}", action
  788. ) # 添加func
  789. def findall(
  790. self,
  791. element_value,
  792. tag: (str, list),
  793. attribute: dict,
  794. limit,
  795. recursive,
  796. index: (slice, int),
  797. **kwargs,
  798. ): # 根据标签定位
  799. if isinstance(tag, str):
  800. tag = str(tag).split(",")
  801. try:
  802. limit = int(limit)
  803. except BaseException:
  804. limit = None
  805. @self.add_base
  806. def action(num, name, *args, **kwargs):
  807. nonlocal self
  808. iter_list = self.list_slicing(index, element_value)
  809. paser_list = []
  810. for bs in iter_list:
  811. try:
  812. re = bs.find_all(tag, attribute, limit=limit, recursive=recursive)
  813. except BaseException:
  814. try:
  815. if str(bs.name) not in tag:
  816. raise Exception
  817. for agrs_name in attribute:
  818. text = attribute[agrs_name]
  819. if isinstance(text, str):
  820. if bs.attrs[agrs_name] != text:
  821. raise Exception
  822. else: # 正则匹配
  823. if not regular.match(text, bs.attrs[agrs_name]):
  824. raise Exception
  825. re = [bs]
  826. except BaseException:
  827. re = []
  828. paser_list += re
  829. self.element_dict[f"{name}[{num}]"] = paser_list
  830. self.add_func(f"findAll:{element_value}[{index}]", action) # 添加func
  831. def findall_by_text(
  832. self,
  833. element_value,
  834. text: (regular.compile, str),
  835. limit,
  836. recursive,
  837. index: (slice, int),
  838. **kwargs,
  839. ): # 根据text定位
  840. try:
  841. limit = int(limit)
  842. except BaseException:
  843. limit = None
  844. @self.add_base
  845. def action(num, name, *args, **kwargs):
  846. nonlocal self
  847. iter_list = self.list_slicing(index, element_value)
  848. paser_list = []
  849. for bs in iter_list:
  850. try:
  851. re = bs.find_all(text=text, limit=limit, recursive=recursive)
  852. except BaseException:
  853. try:
  854. if isinstance(text, str):
  855. if str(bs.string) != text:
  856. raise Exception
  857. else:
  858. if not regular.match(text, str(bs.string)):
  859. raise Exception
  860. re = [bs]
  861. except BaseException:
  862. re = []
  863. paser_list += re
  864. self.element_dict[f"{name}[{num}]"] = paser_list
  865. self.add_func(f"findAll_by_text:{element_value}[{index}]", action) # 添加func
  866. def __get_other_base(
  867. self, element_value, index: (slice, int), who="children", **kwargs
  868. ): # 获得子、后代、兄弟标签的基类
  869. @self.add_base
  870. def action(num, name, *args, **kwargs):
  871. nonlocal self
  872. iter_list = self.list_slicing(index, element_value)
  873. paser_list = []
  874. for bs in iter_list:
  875. if who != "brothers":
  876. paser_list += {
  877. "children": bs.children,
  878. "offspring": bs.descendants,
  879. "down": bs.next_siblings,
  880. "up": bs.previous_siblings,
  881. }.get(who, bs.children)
  882. else:
  883. paser_list += bs.previous_siblings
  884. paser_list += bs.next_siblings
  885. self.element_dict[f"{name}[{num}]"] = list(set(paser_list))
  886. self.add_func(f"get_{who}:{element_value}[{index}]", action) # 添加func
  887. def get_children(self, element_value, index: (slice, int), **kwargs):
  888. return self.__get_other_base(element_value, index)
  889. def get_offspring(self, element_value, index: (slice, int), **kwargs):
  890. return self.__get_other_base(element_value, index, "offspring")
  891. def get_up(self, element_value, index: (slice, int), **kwargs):
  892. return self.__get_other_base(element_value, index, "up")
  893. def get_down(self, element_value, index: (slice, int), **kwargs):
  894. return self.__get_other_base(element_value, index, "down")
  895. def get_brothers(self, element_value, index: (slice, int), **kwargs):
  896. return self.__get_other_base(element_value, index, "brothers")
  897. def get_by_path(
  898. self, element_value, index: (slice, int), path, **kwargs
  899. ): # 根据bs4的目录选择
  900. @self.add_base
  901. def action(num, name, *args, **kwargs):
  902. nonlocal self
  903. iter_list = self.list_slicing(index, element_value)
  904. paser_list = []
  905. for bs in iter_list:
  906. try:
  907. re = eval(str(path), {"self": bs})
  908. if re is None:
  909. raise Exception
  910. paser_list.append(re)
  911. except BaseException:
  912. pass
  913. self.element_dict[f"{name}[{num}]"] = paser_list
  914. self.add_func(f"get>{path}:{element_value}[{index}]", action) # 添加func
  915. def webpage_snapshot(self, **kwargs):
  916. @self.add_base
  917. def action(*args, **kwargs):
  918. nonlocal self
  919. md5 = hashlib.md5() # 应用MD5算法
  920. md5.update(f"{time.time()}_{self.now_url}".encode("utf-8"))
  921. name = md5.hexdigest()
  922. with open(self.dir + "/" + name + ".png.CoTanURL", "w") as f:
  923. f.write(self.now_url)
  924. self.browser.save_screenshot(self.dir + "/" + name + ".png")
  925. sleep(1)
  926. self.add_func(f"Webpage_snapshot", action) # 添加func
  927. def add_url(
  928. self,
  929. element_value,
  930. index: (slice, int),
  931. url_name,
  932. update_func,
  933. url_args: dict,
  934. **kwargs,
  935. ): # 自动添加url
  936. @self.add_base
  937. def action(*args, **kwargs):
  938. nonlocal self
  939. iter_list = self.list_slicing(index, element_value)
  940. for bs in iter_list:
  941. try:
  942. if url_name == "$name&":
  943. new_url = bs.name
  944. elif url_name == "$self&":
  945. new_url = str(bs).replace("\n", "")
  946. elif url_name == "$string$":
  947. new_url = str(bs.string).replace("\n", "")
  948. else:
  949. new_url = bs.attrs.get(url_name, "")
  950. Url.add_url(new_url, **url_args)
  951. except BaseException:
  952. pass
  953. update_func() # 更新tkinter
  954. self.add_func(f"add_URL<{element_value}[{index}]:{url_name}", action) # 添加func
  955. def to_json(self, **kwargs):
  956. @self.add_base
  957. def action(num, name, *args, **kwargs):
  958. nonlocal self
  959. self.element_dict[f"{name}[{num}]"] = [
  960. self.browser.json()
  961. ] # request 解析为 json
  962. self.add_func(f"to_json", action) # 添加func
  963. def make_action_chains(self, **kwargs): # 创建动作链
  964. @self.add_base
  965. def action(num, name, *args, **kwargs):
  966. nonlocal self
  967. self.element_dict[f"{name}[{num}]"] = [ActionChains(self.browser)]
  968. self.add_func(f"make_ActionChains", action) # 添加func
  969. def action_click(self, chains, element_value, index, **kwargs): # 单击左
  970. @self.add_base
  971. def action(*args, **kwargs):
  972. nonlocal self
  973. self.element_dict[chains][0].click(self.element_dict[element_value][index])
  974. self.add_func(f"[{chains}]click>[{element_value}][{index}]", action) # 添加func
  975. def action_double_click(self, chains, element_value, index, **kwargs): # 双击左
  976. @self.add_base
  977. def action(*args, **kwargs):
  978. nonlocal self
  979. self.element_dict[chains][0].double_click(
  980. self.element_dict[element_value][index]
  981. )
  982. self.add_func(
  983. f"[{chains}]double_click>[{element_value}][{index}]", action
  984. ) # 添加func
  985. def action_click_right(self, chains, element_value, index, **kwargs): # 点击右
  986. @self.add_base
  987. def action(*args, **kwargs):
  988. nonlocal self
  989. self.element_dict[chains][0].context_click(
  990. self.element_dict[element_value][index]
  991. )
  992. self.add_func(
  993. f"[{chains}]right_click>[{element_value}][{index}]", action
  994. ) # 添加func
  995. def action_click_and_hold(self, chains, element_value, index, **kwargs): # 按住左
  996. @self.add_base
  997. def action(*args, **kwargs):
  998. nonlocal self
  999. self.element_dict[chains][0].click_and_hold(
  1000. self.element_dict[element_value][index]
  1001. )
  1002. self.add_func(
  1003. f"[{chains}]click_and_hold>[{element_value}][{index}]", action
  1004. ) # 添加func
  1005. def action_release(self, chains, element_value, index, **kwargs): # 松开左键
  1006. @self.add_base
  1007. def action(*args, **kwargs):
  1008. nonlocal self
  1009. self.element_dict[chains][0].release(
  1010. self.element_dict[element_value][index]
  1011. )
  1012. self.add_func(f"[{chains}]release>[{element_value}][{index}]", action) # 添加func
  1013. def action_drag_and_drop(
  1014. self, chains, element_value, index, element_value2, index2, **kwargs
  1015. ): # 拽托、松开
  1016. @self.add_base
  1017. def action(*args, **kwargs):
  1018. nonlocal self
  1019. self.element_dict[chains][0].drag_and_drop(
  1020. self.element_dict[element_value][index],
  1021. self.element_dict[element_value2][index2],
  1022. )
  1023. self.add_func(
  1024. f"[{chains}]drag_and_drop>[{element_value}][{index}]", action
  1025. ) # 添加func
  1026. def action_move(self, chains, element_value, index, **kwargs): # 移动鼠标
  1027. @self.add_base
  1028. def action(*args, **kwargs):
  1029. nonlocal self
  1030. self.element_dict[chains][0].move_to_element(
  1031. self.element_dict[element_value][index]
  1032. )
  1033. self.add_func(
  1034. f"[{chains}]drag_and_drop>[{element_value}][{index}]", action
  1035. ) # 添加func
  1036. def special_keys(self, key: str, is_special_keys):
  1037. if is_special_keys:
  1038. return keys_name_dict.get(key.lower(), key), f"[{key.upper()}]"
  1039. else:
  1040. return key, key
  1041. def action_key_down(
  1042. self, chains, key, element_value, index, is_special_keys, **kwargs
  1043. ): # down
  1044. new_key, key = self.special_keys(key, is_special_keys)
  1045. @self.add_base
  1046. def action(*args, **kwargs):
  1047. nonlocal self
  1048. self.element_dict[chains][0].key_down(
  1049. new_key, self.element_dict[element_value][index]
  1050. )
  1051. self.add_func(
  1052. f"[{chains}]key_down>{key}:[{element_value}][{index}]", action
  1053. ) # 添加func
  1054. def action_key_up(
  1055. self, chains, key, element_value, index, is_special_keys, **kwargs
  1056. ): # down
  1057. new_key, key = self.special_keys(key, is_special_keys)
  1058. @self.add_base
  1059. def action(*args, **kwargs):
  1060. nonlocal self
  1061. self.element_dict[chains][0].key_up(
  1062. new_key, self.element_dict[element_value][index]
  1063. )
  1064. self.add_func(
  1065. f"[{chains}]key_up>{key}:[{element_value}][{index}]", action
  1066. ) # 添加func
  1067. # 发送到指定元素
  1068. def action_send_keys_to_element(
  1069. self, chains, key, element_value, index, is_special_keys, **kwargs
  1070. ):
  1071. new_key, key = self.special_keys(key, is_special_keys)
  1072. @self.add_base
  1073. def action(*args, **kwargs):
  1074. nonlocal self
  1075. self.element_dict[chains][0].send_keys_to_element(
  1076. self.element_dict[element_value][index], new_key
  1077. )
  1078. self.add_func(
  1079. f"[{chains}]sent>{key}:[{element_value}][{index}]", action
  1080. ) # 添加func
  1081. def action_send_keys(self, chains, key, is_special_keys, **kwargs): # 发送到焦点元素
  1082. new_key, key = self.special_keys(key, is_special_keys)
  1083. @self.add_base
  1084. def action(*args, **kwargs):
  1085. nonlocal self
  1086. self.element_dict[chains][0].send_keys(new_key)
  1087. self.add_func(f"[{chains}].sent>{key}", action) # 添加func
  1088. def action_run(self, chains, run_time=1, **kwargs): # 执行
  1089. @self.add_base
  1090. def action(*args, **kwargs):
  1091. nonlocal self
  1092. self.element_dict[chains][0].perform()
  1093. sleep(run_time)
  1094. self.add_func(f"[{chains}].run<{run_time}s", action) # 添加func
  1095. def get_all_windows(self, *args, **kwargs): # 获取所有句柄
  1096. @self.add_base
  1097. def find(browser, num, name, *args, **kwargs):
  1098. nonlocal self
  1099. if browser is None:
  1100. browser = self.browser
  1101. # 获得窗口句柄
  1102. self.element_dict[f"{name}[{num}]"] = browser.window_handles
  1103. self.add_func(f"get_all_windows", find) # 添加func
  1104. def get_now_windows(self, *args, **kwargs): # 获取当前窗口句柄
  1105. @self.add_base
  1106. def find(browser, num, name, *args, **kwargs):
  1107. nonlocal self
  1108. if browser is None:
  1109. browser = self.browser
  1110. self.element_dict[f"{name}[{num}]"] = [
  1111. browser.current_window_handle
  1112. ] # 获得当前窗口句柄
  1113. self.add_func(f"get_now_window", find) # 添加func
  1114. def switch_to_windwos(self, element_value, index=0, **kwargs): # 切换窗口
  1115. @self.add_base
  1116. def action(*args, **kwargs):
  1117. nonlocal self
  1118. self.browser.switch_to.window(self.element_dict[element_value][index])
  1119. self.add_func(f"switch_to_window>{element_value}[{index}]", action) # 添加func
  1120. def element_interaction(self, update_func=lambda *args: None): # 元素交互
  1121. func_list = self.func_list
  1122. status = None
  1123. self.log.write(f'{"*"*5}url:{self.url_text}{"*" * 5}')
  1124. def update_log(func_name):
  1125. nonlocal status, self
  1126. if status:
  1127. success_code = "Success to run"
  1128. elif status is None:
  1129. success_code = "No status"
  1130. else:
  1131. success_code = "Wrong to run"
  1132. self.log.write(
  1133. f"last:[{success_code}];now:[{func_name}];url:{self.now_url} [END]"
  1134. )
  1135. value_box = []
  1136. for i in self.element_dict:
  1137. try:
  1138. value_box.append(f"{i}[{len(i)}] = {self.element_dict[i]}")
  1139. except BaseException:
  1140. value_box.append(f"{i} = {self.element_dict[i]}")
  1141. update_func(func_name, success_code, value_box) # 信息更新系统
  1142. update_log("start")
  1143. for func_num in range(len(func_list)):
  1144. func_name = func_list[func_num]
  1145. update_log(func_name)
  1146. status = self.func_dict[func_name](num=f"{func_num}", name="var")
  1147. update_log("Finish")