最新要闻
- 当前热议!神似梅西男子成网红 被民众围堵合影:这也太像了
- 分析师称《阿凡达2》难以回本:卡梅隆标准定太高了
- 2199元 掌阅Smart Air Pro电纸书上架:8寸大屏、300PPI显示
- 天天即时:怀旧情怀拉满:宾得宣布将开发新款胶片相机
- 阿根廷夺冠“拯救”伊利 但“奶茅”光环渐黯
- 环球快讯:一加宣布与OPPO服务融合:12月底全面加入OPPO售后服务系统
- 东北将迎今冬以来最强降雪:持续时间最长、范围最广
- PCIe 5.0 SSD终于满血了!读写都是14GB/s、容量8TB
- 热消息:蔚来遭遇225万美元数据勒索 官方声明
- 当前讯息:铃木“大G”!吉姆尼五门版无伪谍照:最多能塞进7个人
- 奇迹!女子手机从26楼掉落未摔坏 真身竟是这款手机
- 5499元 联合创新推出新款32英寸显示器:4K MiniLED屏、144Hz高刷
- “非洲之王”拥抱新技术:传音首台折叠屏手机已通过蓝牙SIG认证
- 天天短讯!世界北极熊之都升温过快 已危及北极熊生存:吃不上饭了
- 即时看!1月1日起:澳门私家车可经港珠澳大桥出入内地
- 观速讯丨巡游大巴太高 梅西险些撞上电缆!他带回阿根廷的大力神杯居然是复制品
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
速讯:python + selenium实现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.divId = "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: homediv = self.driver.find_element(By.ID, "xxxyoucangohomenow") if homediv 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"]/div[2]/div[1]/ul/li[1]/a"))) projects = self.driver.find_elements(By.XPATH, "//*[@id="projects"]/div/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"]/div[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 =
正在查询"{}"
{}
.....
速讯:python + selenium实现gitlab全文搜索
热资讯!Codeforces 1763 F Edge Queries 题解
天天视讯!如何使用Yum History查找已安装或已删除的软件包信息
天天新消息丨混合场景
当前热议!神似梅西男子成网红 被民众围堵合影:这也太像了
分析师称《阿凡达2》难以回本:卡梅隆标准定太高了
2199元 掌阅Smart Air Pro电纸书上架:8寸大屏、300PPI显示
前端工程化Vue-cli
天天微头条丨Python unittest数据处理ddt
前端CSS Flex布局8大重难点知识,收藏起来吧
世界新消息丨django10 分页器与Form组件
【全球新要闻】FreeSWITCH学习笔记:XML配置文件
天天即时:怀旧情怀拉满:宾得宣布将开发新款胶片相机
阿根廷夺冠“拯救”伊利 但“奶茅”光环渐黯
环球快讯:一加宣布与OPPO服务融合:12月底全面加入OPPO售后服务系统
东北将迎今冬以来最强降雪:持续时间最长、范围最广
世界速递!框架第九课---ajax补充说明,多对多三种创建方式,django内置序列化组件(drf前身),ORM批量操作数据(ORM操作优化),自定义分页器,f
WPF工控组态软件之温度计
每日播报!Iceberg在袋鼠云的探索及实践
每日关注!hibernate validate工具,小心你的姿势不对
PCIe 5.0 SSD终于满血了!读写都是14GB/s、容量8TB
热消息:蔚来遭遇225万美元数据勒索 官方声明
当前讯息:铃木“大G”!吉姆尼五门版无伪谍照:最多能塞进7个人
奇迹!女子手机从26楼掉落未摔坏 真身竟是这款手机
5499元 联合创新推出新款32英寸显示器:4K MiniLED屏、144Hz高刷
“非洲之王”拥抱新技术:传音首台折叠屏手机已通过蓝牙SIG认证
天天短讯!世界北极熊之都升温过快 已危及北极熊生存:吃不上饭了
天天热资讯!深度学习炼丹-数据处理和增强
世界热门:记录--可视化大屏-用threejs撸一个3d中国地图
Python操作Excel(openpyxl)
全球热点评!Html5 canvas创意特效合集
即时看!1月1日起:澳门私家车可经港珠澳大桥出入内地
观速讯丨巡游大巴太高 梅西险些撞上电缆!他带回阿根廷的大力神杯居然是复制品
天天短讯!中国联通科技人才占比已达30% 曾发话不能再用老眼光看电信行业
空难曾致346人死亡 波音737 Max飞机延期采用最新安全标准
每日观察!广州多个外卖平台下单后配送慢 平台:员工已是全负荷工作
世界视讯!数据结构堆(Heap)&排序&二叉树
今日播报!用好这个任务管理工具,轻松躲避职场明枪暗箭
世界今日报丨彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-登录与图形验证码(captcha)EP06
今日热闻!低代码:如何成为企业业务价值提升的一大利器?
热消息:Intel第二代独立显卡1年后见:要追上RTX 4070!
主页不刷新了 小红书崩了累坏网友:WiFi、流量疯狂切换
罗永浩称他的失败不是理想主义的错 是他们自己的错
世界热讯:吴京《流浪地球2》吃苹果皮:大年初一上映
世界要闻:中国移动千兆宽带用户已达2.4亿!你是其中之一吗?
安全信息流工具-中文安全RSS小程序
supervisor+gunicorn+uvicorn部署fastapi项目
天天实时:四年保质期囤货无压力!900压缩饼干8斤85元
天天热资讯!iPhone 15系列或重新划分机型组合:14 Plus太拉胯 要大改
一加11质感绝了!刘作虎给员工秀真机:围观群众都发出WOW
美国“显卡税”又推迟9个月:一旦征收 最多涨价25%
全球讯息:大无语 车主称理想L9半个月坏三次 充电口从电动变手动
天天关注:企业转型难?火山引擎数智平台提供数智升级新路径
焦点热门:Dubbo架构设计与源码解析(一) 架构设计
Redis的AOF持久化
【报资讯】防火墙功能(锐捷安全篇)
当前热文:多方安全计算(4)MPC万能积木:秘密共享
【全球时快讯】多方安全计算(3)MPC万能钥匙:混淆电路
全力推进企业数智赋能发展主线,低代码任重道远
天天要闻:linux安装stable diffusion2.0完整教程-还不会安装sd2.0?一篇文章教会你AI绘画
焦点速读:proto IDL管理工具buf使用实践
P2329 栅栏
全球观点:Xml转Java实体类对象 xml转Javabena 对象 且多级嵌套 复杂嵌套
世界动态:用Python写一个一次性计算出加减乘除的运算小程序
世界热文:实验一:获取主机信息
全球播报:MySQL-InnoDB磁盘结构
今日热议:pkg对egg项目打包
天天精选!java的final关键字
环球快报:【验证码逆向专栏】某片滑块、点选验证码逆向分析
环球热议:别再用 JWT 作为 Session 系统了,问题重重,后果很危险!
全球球精选!Osx10.14升级watchman踩坑记
时讯:二分法
用Python来写个小型购物车程序
天天观速讯丨基于 Dubbo Admin 动态进行流量隔离
赫德-德普官司以一百万美元赔偿和解
百度地图首发自研“北斗高精”技术 升级“真”车道级导航
【环球时快讯】中国版“猛禽”!长城山海炮大型皮卡实车现身:配自研3.0T、9AT
上海首张城市高级辅助驾驶地图许可来了 百度率先获批
环球快看点丨伊朗男子65厘米创吉尼斯最矮纪录:站起来才到到成人膝盖处
热门:如何基于 Spring Boot 快速开发一个 Dubbo 微服务应用
【世界时快讯】安卓抄错了?iPhone 15 Pro最新概念图:告别纯直边
当前关注:网络谣言别再传了!短视频中梅西抱的不是母亲:是阿根廷队女厨师
天天通讯!微软、谷歌之后 欧盟反垄断又对美国Meta下手:可罚款上百亿美元
每日视讯:4K游戏串流没了 NVIDIA删除使用9年的GameStream功能引用户不满
2022最后一跌!今起油价下调:加满一箱92号汽油少花19.5元
消息!苹果App Store被法国罚款100万美元:Epic CEO、扎克伯格都曾痛批
多次骂新能源!丰田再度质疑汽车全面电动化:中国品牌弯道超车
35岁本泽马宣布从法国队退役:球迷唏嘘 祝福俱乐部继续精彩
Python单元测试框架unittest
环球播报:北京等多地天空疑现震撼的火箭夜光云:原理科普
年出货3亿只、逛店必买的一次性碱性电池:被宜家正式停售了
环球新资讯:抖音在世界杯上下的功夫 远不止撒币10亿买版权这么简单
差评如潮!《三体》动画评分暴跌至6.4:网友"口吐芬芳"
快讯:Epic与美国FTC和解:36.6亿元摆平两起官司
Spring IOC官方文档学习笔记(二)之Bean概述
焦点观察:FreeSWITCH学习笔记:通道变量
焦点关注:32开书本大小!华硕新款12代酷睿i7迷你机PC发布:零噪音
环球即时:内蒙古上空巨大发光体划破天际 网友:像手电筒一样
192个框框的怪兽!AMD Zen4线程撕裂者7000来了
世界快报:Django框架:9、Ajax简介、基本语法、数据编码格式、携带文件数据