pythonselenium实现gitlab全文搜索
一般来说软件开发相关企业都会有自己内部的源代码管理工具,比如私有部署的gitlab服务器。特别是企业上规模之后会有多个产品线,各个业务产品线各自的项目解决方案会非常多。
以我们公司为例,就招聘事业部来说,内部的大大小小的中台ESB、MRest、各种Consumer消费端、各种工具等等解决方案现在已经上百个了。这个时候你就会遇到如下一些场景:
1.需要修改某个公共接口的参数或者某个基础库项目包中的公共方法,但是不知道到底哪些项目、哪些地方引用了该接口,不好评估影响点?
2.业务代码中已知道某个Kafka Topic,但是当初写代码兄弟没备注消费端的项目,找了很久就是找不到Consumer项目在哪儿?
3.我想通过某一些特定的关键词搜索某一段代码,记不清到底在哪些项目中使用了?
如果你有上述的困惑,那么下面介绍的这个gitlab 全局 Search代码搜索工具能够帮你解决这些问题。工具的实现采用python + selenium + chromedriver实现自动化登录内部gitlab站点,通过勾选默认配置的产品分组,实现对多个分组内的项目代码特定多个关键词查询搜索。工具的运行流程及界面大概如下面几幅截图所示:
step1.读取配置文件信息自动登录:{ "username": "yourname", "password": "yourpassword", "projectGroups": [ "recrxxx", "platform-uiframework", "platform-infrastructure", "ux-share-platform" ] }
step2: 登陆成功后主页注入搜索填充信息,可选择的搜索项目分组、关键词录入框等
step3:开始遍历项目分组,获取项目id,并执行关键词搜索
step4:获取命中结果展示,小于等于10个结果的会默认打开浏览器tab页全部展开,大于10个结果的需要手动打开单个或全部
step5:因为使用的chromedriver来驱动实现的,需要注意chrome浏览器版本与chromedriver版本的匹配,如不匹配会记录如下日志;
主要利用python 驱动 selenium 实现自动化控制gitlab项目页面,通过注入特定html标签代码,实现自动化搜索gitlab项目代码。下面是python脚本部分主要实现:class GitLabSearchTool(object): def __init__(self): self.__username = "" self.__password = "" self.projectGroups = [] self.usedKeywords = [] self.__getConfigInfo() self.maxPageIndex = 50 self.pId = "spiderContainer" self.searchDivId = "searchContainer" self.base_url = "http://gitlab.xxxcorp.com" self.baseLoginUrl = "http://gitlab.xxxcorp.com/users/sign_in" self.startTime = datetime.now() self.isSearching = False self.stopSearch = False self.isClose = False self.successUrls = dict() self.searchGroup = [] self.keywords = [] self.request = None self.driver = None def start(self): user_agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" chrome_options = Options() chrome_options.add_argument("user-agent={}".format(user_agent)) chrome_options.add_argument("--disable-plugins") # 禁用插件 chrome_options.add_argument("--start-maximized") # 启动Google Chrome就最大化 chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 隐藏"Chrome正在受到自动软件的控制" pathItem = ["chromedriver.exe"] driverPath = Path.cwd().joinpath(*pathItem) self.driver = webdriver.Chrome(driverPath, options=chrome_options) self.driver.get(self.baseLoginUrl) if self.__username and self.__password: WebDriverWait(self.driver, 1000).until( EC.presence_of_element_located((By.XPATH, "//*[@id="new_ldap_user"]"))) time.sleep(0.3) self.driver.find_element(By.XPATH, "//*[@id="username"]").send_keys(self.__username) time.sleep(0.3) self.driver.find_element(By.XPATH, "//*[@id="password"]").send_keys(self.__password) time.sleep(0.3) self.driver.find_element(By.XPATH, "//*[@id="remember_me"]").click() self.driver.find_element(By.XPATH, "//*[@id="new_ldap_user"]/input[3]").click() threading.Thread(target=self.__checkBrowserIsClose).start() self.request = requests.session() try: while not self.isClose: try: homep = self.driver.find_element(By.ID, "xxxyoucangohomenow") if homep is not None: self.driver.get(self.base_url) except: pass try: searchDiv = self.driver.find_element(By.ID, "xxxyoucanstartsearchnow") if searchDiv is None: time.sleep(1) else: self.startTime = datetime.now() self.successUrls.clear() self.searchGroup.clear() self.keywords.clear() chkList = self.driver.find_elements(By.XPATH, "//*[@id="searchGroup"]/descendant::input[@type="checkbox"]") for chk in chkList: if chk.get_attribute("checked") == "true": self.searchGroup.append(chk.get_attribute("attrvalue").strip()) if len(self.searchGroup) <= 0: return keywordInput = self.driver.find_element(By.ID, "searchKeyword") searchKeyword = keywordInput.get_attribute("value").strip() keywords = re.split(",|,", searchKeyword) if len(keywords) > 0: for kw in keywords: kw = kw.strip() if len(kw) > 0: self.keywords.append(kw) if len(self.keywords) <= 0: self.driver.execute_script("arguments[0].focus();", keywordInput) return self._search() except : time.sleep(1) print("webdriver is close") return except Exception as ex: print("异常:{}".format(ex)) return def _search(self): self.isSearching = True self.stopSearch = False for group in self.searchGroup: if self.stopSearch: break for page in range(1, self.maxPageIndex): if self.stopSearch: break url = "http://gitlab.xxxcorp.com/{}?page={}".format(group, page) self.driver.get(url) WebDriverWait(self.driver, 5).until( EC.presence_of_element_located((By.XPATH, "//*[@id="content-body"]/p[2]/p[1]/ul/li[1]/a"))) projects = self.driver.find_elements(By.XPATH, "//*[@id="projects"]/p/ul/descendant::a[@class="project"]") if len(projects) <= 0: break for proj in projects: try: stopSearch = self.driver.find_element(By.ID, "xxxyoucanstopsearchnow") if stopSearch is not None: self.stopSearch = True break except: pass projUrl = proj.get_attribute("href") self.__searchProject(projUrl) endTime = datetime.now() delta = (endTime - self.startTime).seconds successCount = len(self.successUrls) searchKeyword = ",".join(self.keywords) if successCount > 0: searchedPojectUrl = self.__getSearchedProject() html = """ 查询{}
耗时:{} 秒! 命中{}个项目
{} """.format(searchKeyword, delta, successCount, searchedPojectUrl) else: html = """ 查询{}
耗时:{} 秒! 命中{}个项目
""".format(searchKeyword, delta, successCount) self.__createDom(html) self.isSearching = False if len(self.successUrls) <= 10: for url, name in self.successUrls.items(): self.driver.execute_script("window.open("{}")".format(url)) def __searchProject(self, projUrl): proj = self.__getProjectId(projUrl) if proj[0] <= 0: return for keyword in self.keywords: if not (keyword and len(keyword.strip()) > 0): continue searchUrl = "{}/search?utf8=&snippets=&scope=&search={}&project_id={}" .format(self.base_url, keyword, proj[0]) data = self.request.get(searchUrl).text html = etree.HTML(data) topResults = html.xpath("//*[@id="content-body"]/p[contains(@class,"prepend-top-10")]") if len(topResults) > 0: self.successUrls[searchUrl] = proj[1] # js = "window.open("{}")".format(searchUrl) # self.driver.execute_script(js) # self.driver.switch_to.window(self.driver.window_handles[0]) successCount = len(self.successUrls) if successCount > 0: searchedPojectUrl = self.__getSearchedProject() html = """
正在查询"{}"
{}
查询命中{}个项目
{} """.format(keyword, projUrl, successCount, searchedPojectUrl) else: html = """
正在查询"{}"
{} """.format(keyword, projUrl) self.__createDom(html) def __getProjectId(self, url): proj_id = 0 proj_name = "" data = self.request.get(url).text html = etree.HTML(data) values = html.xpath("//*[@id="search_project_id"]/@value") if len(values) > 0: proj_id = int(values[0]) names = html.xpath("//*[@id="search_project_id"]/@data-name") if len(names) > 0: proj_name = names[0] return (proj_id, proj_name) .....
一代名将苏定方,助唐朝国土达到顶峰,死后却被演义黑化争议不断文章字数3601字,预计阅读时长9分钟。如果您喜欢这篇文章,请点击右上方的关注。感谢您的支持和鼓励,希望能给您带来舒适的阅读体验。我国古时有这样的一位名将,他在年少时便已经因为骁勇
中国房地产的ampampquot康波ampampquot汹涌而来,众大佬纷纷跳水洗澡一大洗牌该来的还是来了房地产终究还是走到大洗牌的时候看看这预亏的企业跳水一个比一个厉害泛海控股预亏70亿至100亿华侨城预亏80亿至110亿荣盛发展预亏190亿至250亿2022年
韵达快递大量延误,怪谁?深燃(shenrancaijing)原创作者邹帅编辑唐亚华春节刚过,快递怎么又派送异常了?近日,大量用户表示韵达快递出现派送异常延迟送达的情况。有用户讲述,在淘宝购买的商品通过韵达
我对ChatGPT产品的实践这两天睡眠不好,也没有什么好的思路写东西,于是躺在沙发上看新闻,却不想接连刷到了好几篇关于人工智能的报道。我的好奇心一直很强,是什么原因让专家们都十分看好这种产品,甚至比尔盖茨都下
华为Mate50Pro首发CML八线SMAOIS马达设计集微网消息,昨日供应链企业CambridgeMechatronics(以下简称CML)宣布华为Mate50Pro和华为Mate50RS保时捷设计两款手机首发了旗下的8线SMAOIS
专题征稿机器视觉与农业智能感知专题征稿机器视觉与农业智能感知以机器视觉为主的农业信息智能感知技术已成为农业机器人发展的关键技术。作为外部传感器,各种光学相机是农业机器人最大的信息源,具有非接触测量长时间稳定工作
Qt开发多线程同步一多线程间的同步1多线程编程的本质(1)并发性是多线程编程的本质(2)在宏观上,所有线程并行执行(3)多个线程间相互独立,互不干涉2特殊情况下,多线程存在依赖煮菜和煮饭这两个线程结
ChatGPT承认不能打败胡锡进,能打败胡锡进的只有他自己2月7日早晨,胡锡进谈ChatGPT的时候不屑一顾,自诩是155毫米榴弹炮,不能被人工智能打败。2月7日晚上,胡锡进发文称ChatGPT打不败老胡,还问这段话谁说的。准确的说,胡锡
山东出台37条措施促进经济加快恢复发展山东省人民政府召开新闻发布会。李明芮摄中新网济南2月8日电(李明芮)组织企业抱团出海加大境外展会支持力度支持跨境电商等外贸新业态更大力度招引外资山东出台37条措施,促进经济加快恢复
厦门自驾租车厦门租车超跑豪车租赁厦门汽车租赁厦门租车公司厦门市亿路达汽车服务有限公司厦门是福建的省辖市副省级城市。位于福建省东南端,与金门岛隔海相望地处热带地区,面临台湾海峡属亚热带海洋性季风
国足亚运队国奥国青2023年全线出击,老球迷们这次看好中国男足吗昨晚和今天一早,中国足协连续发布了国奥队和U17国青队的集训通知。这两支国字号球队在春节假期结束后将分别在上海和珠海集训。对于中国男足各年龄段球队来说,2023年将会是最忙碌的一年
天气凉了,宝宝出现这4种情况,再脏也别洗澡天气一冷,给娃洗澡就是个难题。比如要不要天天洗?不洗吧,孩子玩了一天,在地上摸爬滚打的,肯定沾了不少的脏东西。洗吧,可天气实在冷,又怕冻着了,得不偿失。比如温度,说实话,秋冬季给娃
小车迷的心头好绘本分享晚安,工地上的车这本书讲述了五种工程车,对于工程车小车迷来说,这就是打开他们认知工程车大门的第一步,不仅让孩子们直观的了解他们最喜欢的工程车,也告诉给他们一些生活秩序。打开绘本,一辆大吊车好像正吊
孩子被打了,家长上门讨公道,失控打了对方孩子今天南京好多群里都在讨论这个事情,起因是小孩A在幼儿园打了小孩B,致使小孩B头部受伤,如图这样的伤口,家长看到肯定心疼坏了,故小孩B的父亲和母亲带上孩子上门讨公道,小孩B的父亲和小
孕妇应如何补充水分,哪些饮料会造成不良影响?孕期由于血容量增加等代谢变化,合理补充水分对于成功妊娠更为关键。根据自身的身体活动环境温度及时调整补充水分,饮水应少量多次为宜,一般一天内任何时刻都可以饮水。目前我们的饮用水主要有
喝水要根据体质度身而行每个人的体质不一样,一定要掌握适合自己的食品和饮食方法,不能因为大家都吃的东西,认为有营养就一哄而上。人家吃完这些变成营养吸收了,可您吃完成毒素堵那儿了,不一样。就像喝水,也要度身
出现这5种情况,说明肾精要用光了,教你3个中成药,补肾填精如果你身体出现这5种情况,可能是体内肾精不足了,大家好,我是和医生,今天送你三个中成药补肾填精。首先第一个就是腰酸腿疼,中医认为肾主骨,肾为腰之府如果你肾精不足呀,就可能会出现肾精
你身体乏力没劲可能是吃出来的我们的中国饮食是非常多样的,从南到北,从东西,都有无数的选择,这极大丰富着人们的味蕾。但是于此同时也出现了两种饮食极端,一种是人生得意须尽欢,暴饮暴食,不知节制一种是为了减肥,一天
俗话说生吃萝卜淡饮茶,为什么不能喝浓茶?主要有2点原因茶叶,作为国民饮品,喜欢喝的人非常多,但是很多人喝茶的方式却不是很好,因此常常有同样的一款茶,不同的人喝,结果也大相径庭的情况。不知道大家有没有听说过一句俗语生吃萝卜淡饮茶,这句话
火箭10换1报价杜兰特!斯通一箭双雕?借机招募哈登重回休城新赛季的布鲁克林篮网队可谓是一波未平一波又起,他们在赛季初就经历了西蒙斯的状态低迷,球队基本全是杜兰特和欧文两位巨头在苦苦支撑。然而,球队没等来西蒙斯的复苏不说,欧文这边又出了问题
产后遭受恶露纠缠?也许是身体发出的信号!产妇要清楚每一位产后的母亲都要经历排泄恶露的过程,但是各位的经历也各不相同,顺利的话就能按时排净,而部分则会出现淋漓不尽的情况。那么对于产后恶露的定义大家是真的有所了解?怀孕过程中,胎儿在子
宝妈们需要重视!科学健康解决产后问题的方法是?从怀孕到生产再到拥有自己的宝宝,对于女性来说是一件幸福的事情,但同时也会给女性朋友们带来一些困扰。比如,宝妈在生完宝宝之后要独自承受身材走样腹部肌肉松弛盆骨变宽耻骨疼痛等问题。尤其