def __get_value_from_tr(self, tr, column_relation): """ 解析tbody.tr数据, 获取行数据的内容,以列表的形式返回 :param tr: html 表格中 tr的标签信息, tr是以 beautifulsoup 中的 Tag标签类型传入 :param column_relation: 是一个类似{0: 缺陷, 1:优先级}的字典,key为表格的第几列信息,value为表格对应列表头名称 :return: 返回一个列表,列表信息为该行数据各个字段的内容 """ tr_value = [] for i, td in enumerate(tr.find_all("td")): if column_relation.get(i) == "T": content = "缺陷" elif column_relation.get(i) == "优先级": content = "优先级" elif column_relation.get(i) == "修改单号": content = "无" elif column_relation.get(i) == "打回次数": content = "0" elif column_relation.get(i) is None: continue else: # content = re.search("\s*(\S*)\s*", td.get_text(strip=True)).group(1) content = td.get_text(strip=True) try: tr_value.append(content) logging.info("Target Getted the {0} td -- [{1}]".format( i, content)) except AttributeError as e: logging.warning("Its the {0} td: [{1}]".format(i, td)) return tr_value
def get_table_data_from_html(self): """ 通过jira的接口返回的字段,使用BeautifulSoup进行封装,获取缺陷列表的表格头名称以及表格的数据 :return: 返回表格头名称字典项_head_dic 与 表格数据字典项 _column_dic """ table_data_dic = {} _head_dic = {} for i, th in enumerate(self.soup.thead.find_all("th")): try: column = th.span.string _head_dic.update({i: column}) logging.info("The {1} Table Head Is [{0}]".format(column, i)) except AttributeError as e: logging.warning( "Get The Table Head occurs AttributeError: {}".format( str(e))) # print(self.soup.tbody.prettify()) for i, tr in enumerate(self.soup.tbody.find_all("tr")): data_list = self.__get_value_from_tr(tr, column_relation=_head_dic) table_data_dic.update({i: data_list}) # if not table_dic.get(i): # table_dic.setdefault(i, []) # try: # # table_dic[i].append(tr.td.string) # logging.info("The Table Cell Is [{0}]".format(tr.td.a.string)) # except AttributeError as e: # logging.warning("Get The Table Head occurs AttributeError: {}".format(str(e))) return _head_dic, table_data_dic
def request(self, url, data, is_get_method=True, verify=False, headers={}, response_type="json"): logging.info("Will Reuqeuest Interface: {}".format(url)) logging.info("Augues as follows: \n{}".format(data)) if not headers: headers = self.headers logging.debug("Headers as follows:\n{}".format(headers)) if is_get_method: r = requests.get(url=url, headers=headers, verify=verify, params=data) else: r = requests.post(url=url, headers=headers, verify=verify, data=data) if response_type == "text": result = r.text elif response_type == "json": result = r.json() else: result = r.raw logging.debug("Response: \n{}".format(result)) return result
def sendMail(self, subject, recipient, text, *attachmentFilePaths): '''发送邮件函数:参数(邮件主题,邮件内容,邮件附件(可多选))''' msg = MIMEMultipart() # 发送附件时需调用 MIMEMultipart类,创建 MIMEMultipart,并添加信息头 ''' MIME邮件的基本信息、格式信息、编码方式等重要内容都记录在邮件内的各种域中, 域的基本格式:{域名}:{内容},域由域名后面跟“:”再加上域的信息内容构成,一条域在邮件中占一行或者多行, 域的首行左侧不能有空白字符,比如空格或者制表符,占用多行的域其后续行则必须以空白字符开头。 域的信息内容中还可以包含属性,属性之间以“;”分隔,属性的格式如下:{属性名称}=”{属性值}”。 ''' msg['From'] = self.sender msg['To'] = ";".join(recipient) msg['Subject'] = subject msg.attach(MIMEText(text)) for attachmentFilePath in attachmentFilePaths: #判断添加哪些附件 msg.attach(self.getAttachment(attachmentFilePath)) #如果入参给定附件文件,使用attach 发放添加msg头信息 try: mailServer = smtplib.SMTP('smtp.qq.com', 587) # 连接腾讯邮件的服务器;SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式 mailServer.ehlo() # 使用starttls 方法必须先 ehlo 判断是否是同一个地址。。。 mailServer.starttls() # 以下SMTP都会加密;Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted. mailServer.ehlo() # You should then call ehlo() again. mailServer.login(self.sender, self.password) # 登录邮箱 mailServer.sendmail(self.sender, recipient, msg.as_string()) # 发送邮件(发件人,收件人,发送内容) mailServer.close() # 关闭邮件发送服务 logging.info('Sent email to %s successfully' % recipient) except Exception as e: logging.error('sendEmai failed %s' % e)
def phatomjs_login(self, executable_path="../config/chromedriver.exe"): from selenium import webdriver from selenium.webdriver.chrome.options import Options # driver = webdriver.Chrome() # 模拟无界面谷歌浏览器操作 chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') driver = webdriver.Chrome(executable_path=executable_path, options=chrome_options) driver.get(url=self.login_url) time.sleep(1) # 登录 driver.find_element_by_xpath(xpath='//*[@id="username"]').send_keys( self.authority['jira']['username']) driver.find_element_by_xpath(xpath='//*[@id="password"]').send_keys( self.authority['jira']['password']) driver.find_element_by_xpath( xpath='//*[@id="submit_psd"]/input').click() time.sleep(0.5) # 获取登录后token信息 for cookie in driver.get_cookies(): logging.info("Cookie From Login Is: {}".format(cookie)) token = driver.get_cookie(name="atlassian.xsrf.token") logging.info("atlassian.xsrf.token info is [{}]".format(token)) jessionid = driver.get_cookie(name="JSESSIONID") logging.info("JSESSIONID info is [{}]".format(jessionid)) if "se.hundsun.com" in self.login_url: self.jira_cookie += token.get("name") + "=" + token.get( "value") + "; jira.editor.user.mode=wysiwyg;" self.jira_cookie += jessionid.get("name") + "=" + jessionid.get( "value") logging.info("The valid cookie is [{}]".format(self.jira_cookie)) elif "ts.hundsun.com" in self.login_url: self.ts_cookie += jessionid.get("name") + "=" + jessionid.get( "value") logging.info("The valid cookie is [{}]".format(self.ts_cookie)) else: logging.warning( "The request url [{}] is not dealed correctly.".format( self.login_url)) self.driver = driver return driver
def _extract_se_configurations(self, text): """获取ts请求接口时,一些必要的参数信息,数据来源于接口 SupportPortal.htm""" se_configurations = {} import re user_id = re.search('se.SEConfig.UserId\t*=\s*"(\d+)";', text).group(1) token = re.search('se.SEConfig.token = "(\d+)";', text).group(1) pennanter = re.search('se.SEConfig.pennanter\s*=\s*"(\d+)";', text).group(1) # token = re.search('se.SEConfig.pennanter\s*=\s*"(\d+)";', text).group(1) arhinoceros = re.search('se.SEConfig.arhinoceros\s*=\s*"(\d+)";', text).group(1) current_group = re.search('se.SEConfig.currentGroup \s*=\s*"(\d+)";', text).group(1) se_configurations.setdefault("user_id", user_id) se_configurations.setdefault("token", token) se_configurations.setdefault("pennanter", pennanter) se_configurations.setdefault("arhinoceros", arhinoceros) se_configurations.setdefault("current_group", current_group) for k, v in se_configurations.items(): logging.info("Getted Argue {0}, the value is {1}".format(k, v)) return se_configurations
self.driver = driver return driver def quit(self): self.driver.quit() def get_valid_jira_cookie(self): return self.jira_cookie def get_valid_ts_cookie(self): return self.ts_cookie if __name__ == "__main__": from Jira.public.loading_config import LoadingConfig loading_config = LoadingConfig() config_obj_of_authority = loading_config.loading( filename="../config/authority.conf") login = Login(url=config_obj_of_authority['ts']['url'], config_obj_of_authority=config_obj_of_authority) login.phatomjs_login() valid_jira_cookie = login.get_valid_jira_cookie() valid_ts_cookie = login.get_valid_ts_cookie() import requests # r = requests.get(url="https://ts.hundsun.com/se/portal/SupportPortal.htm", # headers={"Cookie": "modifyPageSize=100; JSESSIONID=4DFCA95C07AFF5A4C493AFAAC766D8CB"}) r = requests.get(url="https://ts.hundsun.com/se/portal/SupportPortal.htm", headers={"Cookie": valid_ts_cookie}) logging.info(r.text)
else: attachment = MIMEBase(mainType, subType) # The MIMEBase class always adds a Content-Type header (based on _maintype, _subtype, and _params), and a MIME-Version header (always set to 1.0). attachment.set_payload(file.read()) # Set the entire message object’s payload(负载) to payload. encode_base64(attachment) # Encodes the payload into base64 form and sets the Content-Transfer-Encoding header to base64. file.close() """ Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名, 文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) 。 """ attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachmentFilePath)) #Content-Disposition为属性名 disposition-type是以什么方式下载,如attachment为以附件方式下载 disposition-parm为默认保存时的文件名 return attachment if __name__ == "__main__": from Jira import ROOT_PATH from Jira.public.loading_config import config_obj_of_authority sender = config_obj_of_authority['email']['username'].strip() password = config_obj_of_authority['email']['password'].strip() recipients = recipient = config_obj_of_authority['email']['recipient'].strip() mail = Mail(sender=sender, password=password) if "," in recipient: recipients = recipient.split(",") file = os.path.join(os.path.dirname(ROOT_PATH, "static/bug_list.xls")) mail.sendMail('邮件主题', recipients, "Its a test.", file) logging.info("Have Send Email Successfully.")