Selenium控制已运行的Edge和Chrome浏览器——在线控制 | 人机交互(详细启动步骤和bug记录)

文章目录

  • 前期准备
  • 1. 浏览器开启远程控制指令
    • (1)Edge
    • (2)Chrome
  • 2. 执行python代码
    • (1)先启动浏览器后执行代码
    • (2)通过代码启动浏览器
    • (3)Bug问题记录
      • 1)python可读取浏览器所有标签标题,但检索网页元素失败
      • 2)浏览器开启程序,但python程序无法链接浏览器进行自动控制
  • 3. 爬取效果
  • 3. 完整代码共享
    • 3.1 包含Excel部分的完整代码
    • 3.2 爬虫部分的完整代码


说明:本记录是在Windows系统上执行的!
起因是:博导要求统计一下国内某个领域的专家情况,统计主持国家自然科学基金的副教授和教授都有哪些大牛!
于是:本人去[NSFC]:https://kd.nsfc.cn/ 下载全部的历史基金项目书。。。。工作量太大就……半自动化实现吧!!!


前期准备

1. python Selenium库
2. Edge浏览器 或 Chrome浏览器

1. 浏览器开启远程控制指令

  1. 无论是哪种浏览器,都需要使用终端独立运行浏览器的远程调试模式。
  2. 开启方式:加入指令(–remote-debugging-port=9222 --user-data-dir=“D:\selenium\AutomationProfile”)

需要进入目标浏览器的根目录! 不然就输入全路径!

(1)Edge

.\msedge.exe --remote-debugging-port=9222 --user-data-dir=“D:\selenium\AutomationProfile”

(2)Chrome

 .\chrome.exe --remote-debugging-port=9222 --user-data-dir=“D:\selenium\AutomationProfile”

在这里插入图片描述

2. 执行python代码

(1)先启动浏览器后执行代码

  • 必须是先执行上述步骤,开启了浏览器的远程调试端口后,才能通过下方代码进行控制。

  • add_experimental_option("debuggerAddress", "127.0.0.1:9222") 这句话是关键!

from selenium import webdriver
from selenium.webdriver.edge.options import Optionsclass Test:def edge(self):edge_driver_path = executable_path=r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'chrome_options = Options()# chrome_options.binary_location = edge_driver_path  #  传入驱动地址chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")  # "127.0.0.1:9222"其中,9222是浏览器的运行端口# 让浏览器带着这个配置运行# chrome_options.add_experimental_option('detach', True)  # 通过option参数,设置浏览器不关闭driver = webdriver.Edge(options=chrome_options, keep_alive=True)driver.implicitly_wait(10)  # 页面元素查找的等待时间self.driver = driverpassdef chrome_drive(self, drive='chrome'):edge_driver_path = executable_path = r'D:\Program Files\Google\Chrome\Application'if drive == 'chrome':chrome_options = webdriver.ChromeOptions()# chrome_options.binary_location = edge_driver_path    #  传入驱动地址# chrome_options.add_experimental_option('detach', True)  # 通过option参数,设置浏览器不关闭chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")driver = webdriver.Chrome(options=chrome_options, keep_alive=False)driver.implicitly_wait(10)  # 页面元素查找的等待时间self.driver = driverpass

(2)通过代码启动浏览器

  • 这个时候被注释掉的 .binary_location = edge_driver_path 是关键!
  • 这种情况下,需要下载对应的驱动软件(.exe)
  • 博主在笔记本电脑上首次尝试Selenium时就下载了驱动软件!但后来在台式电脑使用相同代码时发现,压根不需要下载什么驱动软件!
  • 只需要使用终端提前启动浏览器的调试模型即可。 (这是弯路、坑)
  • 因为,如果是通过代码启动浏览器的调试模型,需要配置路径,然后保证程序关闭后浏览器依旧运行!麻烦!!!

(3)Bug问题记录

1)python可读取浏览器所有标签标题,但检索网页元素失败

  • 部分网页不支持爬取!特别是当网页开启F12的开发人选项后,会出现无法查找元素的问题。
  • 此时,关闭 “开发人选项” 即可。

2)浏览器开启程序,但python程序无法链接浏览器进行自动控制

  • 关闭原有浏览器,重新打开浏览器(需搭配命令:–remote-debugging-port=9222 --user-data-dir=“xxx folder”

3. 爬取效果

![(https://img-blog.csdnimg.cn/direct/492fe54da6c24809a654191a43365f14.png)

3. 完整代码共享

以下代码主要实现了:

  • 浏览器标签页的翻动和选择
  • 爬取 – 青塔网检索”国家自然科学基金项目“的作者信息,并保存到表格。
  • 爬取 – NSFC”国家自然科学基金项目“的作者信息,并保存到表格。
  • 爬取 – 国际某个领域专家的作者信息,并保存到表格。

3.1 包含Excel部分的完整代码

包含Excel部分的完整代码见:资源文件

3.2 爬虫部分的完整代码

import os
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.action_chains import ActionChains# '.\chrome.exe --remote-debugging-port=9222 --user-data-dir=“D:\selenium\AutomationProfile”             n "*" --ws --allow-insecure-unlock --nodiscover --authrpc.addr 127.0.1.2 --authrpc.port 8545'
# '.\chrome.exe --remote-debugging-port=9222 --user-data-dir=“D:\selenium\AutomationProfile”'class Web_Browser:def __init__(self, drive='chrome'):self.driver = None# self.edge()self.chrome_drive()def edge(self):# edge_driver_path = executable_path=r'D:\Program Files\Google\Chrome\Application\chromedriver.exe'edge_driver_path = executable_path=r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'chrome_options = Options()# chrome_options.binary_location = edge_driver_path# 配置浏览器# 添加User-Agent到Chrome选项中# chrome_options.add_argument("--user-agent=windows 10 Edge")# "127.0.0.1:9222"其中,9222是浏览器的运行端口chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")# 让浏览器带着这个配置运行# chrome_options.add_experimental_option('detach', True)  # 通过option参数,设置浏览器不关闭driver = webdriver.Edge(options=chrome_options, keep_alive=True)# driver = webdriver.Chrome( options=chrome_options)print('===================')# driver.get('www.baidu.com')driver.implicitly_wait(10)self.driver = driverdef chrome_drive(self, drive='chrome'):edge_driver_path = executable_path = r'D:\Program Files\Google\Chrome\Application\chromedriver.exe'if drive == 'chrome':chrome_options = webdriver.ChromeOptions()# chrome_options.binary_location = edge_driver_path# chrome_options.add_experimental_option('detach', True)  # 通过option参数,设置浏览器不关闭chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")driver = webdriver.Chrome(options=chrome_options, keep_alive=False)self.driver = driverdriver.implicitly_wait(10)self.opened_windows_dict = Nonepassdef get_all_opened_windows(self):driver = self.drivercw = driver.current_window_handleres = {}# 获取已打开的标签页的信息tabs = driver.window_handlesfor t in tabs:driver.switch_to.window(t)res[str(driver.title)] = str(t)self.opened_windows_dict = resdriver.switch_to.window(cw)print('已打开的标签页的信息:',)for k in res: print(f"\t{k}: {res[k]}")return resdef switch_window(self, key):driver = self.drivercw = driver.current_window_handle# 获取已打开的标签页的信息tabs = driver.window_handlesfor t in tabs:driver.switch_to.window(t)if key in str(driver.title): cw = tbreak# driver.switch_to.window(cw)self.driver = driverpassdef open_new_window(self, driver=None, url=None, delay_t=0.6):'''# 打开新标签页'''driver = self.driver if not driver else driverold_handle = driver.window_handles  # 获取已打开的标签页的信息# driver.find_element("body").send_keys(Keys.CONTROL + 't')  # 没有实体会报错# driver.execute_script("window.open('','_blank');")  # 可能被拦截driver.switch_to.new_window('tab')time.sleep(delay_t)if len(driver.window_handles) >len(old_handle): return Truedriver.execute_script(f"window.open('{url if url else ''}');")time.sleep(delay_t)if len(driver.window_handles) >len(old_handle): return Truereturn Falsedef func1(self, xlsx):""" 学术网 """for p in range(50):# self.switch_window('故障诊断')driver = self.driverweb = driver.find_element(by=By.XPATH, value='//*[@id="search_body"]/div[2]/div[3]/div[1]/div[2]/div[1]/div[3]/div[2]/div/div[2]/div[2]/div/div')web1 = web.find_elements(by=By.CLASS_NAME, value='inner-content')print('web1 len=', len(web1))num = 0for i, w in enumerate(web1):try:# '//*[@id="search_body"]/div[2]/div[3]/div[1]/div[2]/div[1]/div[3]/div[2]/div/div[2]/div[2]/div/div'#a = w.find_element(by=By.XPATH, value=f'//div[{1+i}]/div/div[2]/div[1]/div[1]/div/a/strong/span/span').texttry:b = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[3]/p[2]').textschool = str(b).split(',')for s in school:if 'university' in s.lower(): b = s[1:]except: b = Nonec = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[3]/p[1]').textd = Nonee = Nonef = Nonetry:h_index = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[1]/span[3]').textpaper = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[2]/span[3]').textcite = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[3]/span[3]').textf = f"H-index: {h_index},  papers: {paper}, cites: {cite}"except: passg = Noneh = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[1]/div[1]/div/a')h = 'https://www.aminer.cn/' + h.get_attribute('href')print(a, b ,c, g)xlsx.input_data(a,b,c,d,e,f,g, h)num += 1except: passprint('记录:', num)# aa = driver.find_elements(by=By.XPATH, value='//*[@id="search_body"]/div[2]/div[3]/div[1]/div[2]/div[1]/div[3]/div[2]/div/div[2]/div[3]/ul/li')# aa = aa[-1]aa = driver.find_element(by=By.CLASS_NAME, value='ant-pagination-next')# v = '#search_body > div.ant-tabs.ant-tabs-top.a-aminer-core-search-index-searchPageTab.ant-tabs-line.ant-tabs-no-animation > div.ant-tabs-content.ant-tabs-content-no-animated.ant-tabs-top-content > div.ant-tabs-tabpane.ant-tabs-tabpane-active > div.a-aminer-core-search-index-componentContent > div.a-aminer-core-search-c-search-component-temp-searchComponent > div.view > div:nth-child(2) > div > div:nth-child(2) > div.paginationWrap > ul > li.ant-pagination-next'# aa = driver.find_element(by=By.CSS_SELECTOR, value=v)# 创建一个ActionChains对象,用于执行鼠标动作action_chains = ActionChains(driver)# 将鼠标移动到链接元素上并点击action_chains.move_to_element(aa).click().perform()print(f'第{p+1}页 --> 第{p+2}页')try:xlsx.make_frame()xlsx.save_excel()except: passtime.sleep(5)passdef func2(self, xlsx=None):for p in range(50):self.switch_window('青塔')driver = self.driverweb = driver.find_element(by=By.XPATH,value='//*[@id="app"]/div[2]/div[1]/div/div[2]/div[2]/div/div[2]')web1 = web.find_elements(by=By.CLASS_NAME, value='list-item')print('web1 len=', len(web1))num = 0for i, w in enumerate(web1):# try:# //*[@id="app"]/div[2]/div[1]/div/div[2]/div[2]/div/div[2]# '//*[@id="app"]/div[2]/div[1]/div/div[2]/div[2]/div/div[2]/div/div[2]/div[2]/div[2]/div[1]/div[2]'# //*[@id="app"]/div[2]/div[1]/div/div[2]/div[2]/div/div[2]/div/div[1]/div[2]/div[2]/div[1]/div[1]b = w.find_element(by=By.XPATH, value=f'//div[2]/div[1]/div[1]/div[2]')print(b)b = b.textprint('b=', b)a = w.find_element(by=By.XPATH, value=f'//div[2]/div[2]/div[1]/div[2]').textprint('a=', a)c = Noned = Nonee = w.find_element(by=By.XPATH, value=f'//div[1]/div[1]').textprint('e=', e)year = w.find_element(by=By.XPATH, value=f'//div[2]/div[2]/div[2]/div[2]').textmoney = w.find_element(by=By.XPATH, value=f'//div[2]/div[1]/div[2]/div[2]').textprint('year=', year, 'money=', money)e = f"{e}, 立项: {year}, 资助: {money}"jijin = w.find_element(by=By.XPATH, value=f'//div[2]/div[3]/div[1]/div[2]').textdomain = w.find_element(by=By.XPATH, value=f'//div[2]/div[3]/div[2]/div[2]').textprint('jijin=',jijin, 'domain=', domain)f = f"{jijin}, 领域: {domain}"g = Noneh = Noneprint(i, '-----------', i)print(a, b, c, d, e, f)xlsx.input_data(a, b, c, d, e, f, g, h)num += 1break# except: passprint('记录:', num)breakaa = driver.find_element(by=By.XPATH, value=f'//*[@id="app"]/div[2]/div[1]/div/div[2]/div[2]/div/div[3]/button[2]')# 创建一个ActionChains对象,用于执行鼠标动作action_chains = ActionChains(driver)# 将鼠标移动到链接元素上并点击action_chains.move_to_element(aa).click().perform()print(f'第{p + 1}页 --> 第{p + 2}页')try:xlsx.make_frame()xlsx.save_excel()except:passtime.sleep(5)passdef func3(self, xlsx=None):for p in range(50):self.switch_window('大数据知识管理服务门户')driver = self.driverd = driver.find_element(by=By.CLASS_NAME, value='container_list_right')print('d==', d)# web = driver.find_element(by=By.XPATH,#                           value='//*[@id="app"]/div[1]/div[3]/div/div[3]/div[1]/div')web = d.find_element(by=By.XPATH, value='//div[1]/div')# web1 = web.find_elements(by=By.CLASS_NAME, value='list-item')# print('web1 len=', len(web1))num = 0for i, w2 in enumerate(range(6)):w = webtry:# //*[@id="app"]/div[1]/div[3]/div/div[3]/div[1]/div# //*[@id="app"]/div[1]/div[3]/div/div[3]# //*[@id="app"]/div[1]/div[3]/div/div[3]/div[1]/div/div[2]/div[2]/div[1]b = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[3]/div[4]/a')b = b.text# print('b=', b)a = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[2]/div[4]/a').text# print('a=', a)c = Noned = Nonee = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[1]/div[1]/p/a').text# print('e=', e)year = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[3]/div[3]').textmoney = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[3]/div[1]').text# print('year=', year, 'money=', money)e = f"{e}, {year}, {money}"jijin = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[2]/div[3]').textdomain = w.find_element(by=By.XPATH, value=f'//div[{i+1}]/div[2]/div[1]').text# print('jijin=',jijin,  domain)f = f"{jijin}, {domain}"g = Noneh = Noneprint(i+1, '-----------', i+1)print(a, b, c, d, e, f)xlsx.input_data(a, b, c, d, e, f, g, h)num += 1# breakexcept: passprint('记录:', num)# break# aa = driver.find_element(by=By.CLASS_NAME, value=f'btn-next')# # 创建一个ActionChains对象,用于执行鼠标动作# action_chains = ActionChains(driver)# # 将鼠标移动到链接元素上并点击# action_chains.move_to_element(aa).click().perform()print(f'第{p + 1}页 --> 第{p + 2}页')try:xlsx.make_frame()xlsx.save_excel()except:passbreak# time.sleep(5)passdef func4(self, xlsx=None, key='Google2'):if key == 'Google': self.switch_window('Google')else: self.switch_window('必应')driver = self.driverdata = xlsx.read_excel()# print(data['姓名'])for i, name in enumerate(data['姓名']):school = data['学校'][i]text = f'{school}{name}是不是教授'print(f'search [{i+1}]:  {name} -》 ', text)if key == 'Google': web = driver.find_element(by=By.XPATH, value='//*[@id="APjFqb"]')else: web = driver.find_element(by=By.XPATH, value='//*[@id="sb_form_q"]')web.clear()web.send_keys(text)if key == 'Google': web = driver.find_element(by=By.XPATH, value='//*[@id="tsf"]/div[1]/div[1]/div[2]/button')else: web = driver.find_element(by=By.XPATH, value='//*[@id="sb_form_go"]')# try:web.click()# except: passtime.sleep(5)num = 0if __name__ == '__main__':from temp import Make_Excel, input_data_list, input_dataxlsx = Make_Excel()web = Web_Browser()web.get_all_opened_windows()# web.switch_window('故障诊断')''' 学术网 '''web.func1(xlsx)  # 学术网# web.func2(xlsx)  #  青塔网# web.func3(xlsx)  #  NSFC官网# web.func4(xlsx, )    # goole搜索网# xlsx.make_frame()# xlsx.save_excel()pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/748542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯决赛2023 RE CyberChef2

思路很清晰,爆IV 但是题目出的有点屎,六位字符串,62的6次方,要我爆到猴年马月? 就当练习脚本吧 #Cyber2 wp from Crypto.Cipher import DES, AES from Crypto.Util.Padding import pad, unpad key_des b0a0b0c0…

PHP异世界云商系统开源源码

系统更新与修复列表 1. 基于彩虹的二次开发 - 对彩虹系统进行了二次开发,增强了系统的功能和性能。2. 新增自定义输入框提示内容(支持批量修改) - 用户可以自定义输入框的提示内容,并支持批量修改,提升用户体验。3. 新…

TCP相关特性

协议段格式 • 源/⽬的端⼝号:表⽰数据是从哪个进程来,到哪个进程去; • 32位序号/32位确认号:后⾯详细讲; • 4位TCP报头⻓度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15*460 • 6位标志位: ◦ URG:紧急指针是否有效 ◦ ACK:确认号是否有效…

ARMv8架构特殊寄存器介绍-0

一、zero 寄存器 零寄存器用作源寄存器时读取零,用作目标寄存器时丢弃结果。您可以在大多数指令中使用零寄存器,但不是所有指令。二、sp寄存器 在ARMv8架构中,要使用的堆栈指针的选择在某种程度上与Exception级别。默认情况下,异…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:ScrollBar)

滚动条组件ScrollBar,用于配合可滚动组件使用,如List、Grid、Scroll。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 可以包含单个子组件。 接口 ScrollBar(val…

6、Design Script之列表

Range 在DesignScript中,Range是从起点到终点的一系列数字,使用指定的步距(间距类型),并有以下的初始化方法: start..end..step; start..end..#amount; start..end..~approximate; Range可以是数字的,也可以是字母的。 字母范围因大小写而异。 开始,结束. .#数量范围(…

springboot276基于JS的个人云盘管理系统的设计与实现

个人云盘管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装个人云盘管理系统软件来发挥其…

P6技巧:导出XER设置老版本/新版本

前言 在一个大型的项目中,虽然业主方已要求承包商必须使用P6格式来提交计划,但实际情况是承包商会给到你多种不同版本的XER文件,使得得在Oracle Primavera P6 之间导入或导出。 如果收到的 XER 文件不适合你使用的 Primavera P6 版本&#x…

java学习之路-程序逻辑控制

目录 1.分支结构 1.1 if语句 栗子 判断奇数还是偶数 判断一个年份是否为闰年 1.2switch语句 栗子 2. 循环结构 2.1while 循环 栗子 2.2break和continue break continue 2.3for循环 基本语法 栗子 2.4 do while 循环 3.输入输出 3.1输出 3.2从键盘输入 栗子…

南大通用数据库-Gbase-8a-学习-43-SQL长时间处于Writing to net状态排查

目录 一、问题截图 二、排查思路 1、Gbase8a SQL有几种状态 2、问题导致原因猜想 3、观察服务端(集群端)网络情况 4、观察客户端网络情况 5、排查客户端程序处理数据慢 5.1、send (1)声明 (2)作用…

数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)

本期作者 前言 云原生时代下, Kubernetes已成为容器技术的事实标准, 使得基础设施领域应用下自动化运维管理与编排成为可能。对于无状态服务而言, 业界早已落地数套成熟且较完美的解决方案。可对于有状态的服务, 方案的复杂度就以…

精简版 Obsidian 图床配置 PicGo+ gitee

精简版 Obsidian 图床配置 PicGo gitee 图床的作用 图床(Image Hosting Service)是一种在线服务,用于存储和托管用户上传的图片文件。用户可以将图片上传到图床服务器,并获得一个可访问的图片链接,然后可以在网页、博…

模板进阶:非类型模板参数,特化

一、非类型模板参数 非类型模板参数&#xff0c;就是用一个常量作为 类/函数 的模板参数&#xff0c;在 类/函数 中可以被当成常量使用。 template<class T, size_t N>// N 为一个非类型模板参数 class Stack { public:Stack(){_a new T[N];} protected:T* _a; };int m…

GAMMA数据处理(六)

最近进行Sentinel-1数据处理,需要用到拼接三个iw的命令,找了一下 但是这样大的数据提取进来,处理速度很慢,后面可能要进行研究区的裁剪,除了开始用的方法,直接在生成的burst_tab文件里面修改参数:删去自己不需要的iw,也就是下面说的这种方法 在指导手册上面看到了其他的…

前端接口防止重复请求实现方案

虽然大部分的接口处理我们都是加了loading的&#xff0c;但又不能确保真的是每个接口都加了的&#xff0c;可是如果要一个接口一个接口的排查&#xff0c;那这维护了四五年的系统&#xff0c;成百上千的接口肯定要耗费非常多的精力&#xff0c;根本就是不现实的&#xff0c;所以…

使用OpenCV实现人脸特征点检测与实时表情识别

引言&#xff1a; 本文介绍了如何利用OpenCV库实现人脸特征点检测&#xff0c;并进一步实现实时表情识别的案例。首先&#xff0c;通过OpenCV的Dlib库进行人脸特征点的定位&#xff0c;然后基于特征点的变化来识别不同的表情。这种方法不仅准确度高&#xff0c;而且实时性好&am…

Serverless:无服务器架构的魅力与实践

导语&#xff1a;随着云计算的不断发展&#xff0c;无服务器架构&#xff08;Serverless&#xff09;逐渐成为开发人员关注的焦点。本文将为您深入解析 Serverless 的概念、优势、应用场景以及实践经验&#xff0c;带您领略 Serverless 的魅力&#xff01; 一、Serverless 是什…

打卡学习kubernetes——了解kubernetes组成及架构

目录 1 什么是kubernetes 2 kubernetes组件 3 kubernetes架构 1 什么是kubernetes kubernetes是一个旨在自动部署、扩展和运行应用容器的开源平台。目标是构建一个生态系统&#xff0c;提供组件和工具以减轻在公共和私有云中运行应用程序的负担。 kubernetes是&#xff1a…

deepin23beta中SQLite3数据库安装与使用

SQLite 是一个嵌入式 SQL 数据库引擎&#xff0c;它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。 SQLite 的代码属于公共领域&#xff0c;因此可以免费用于任何商业或私人目的。 SQLite 是世界上部署最广泛的数据库&#xff0c;其应用程序数量之多&#xff0c…

Linux使用Docker部署Registry结合内网穿透实现公网远程拉取推送镜像

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…