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

news2025/3/13 3:28:28

文章目录

  • 前期准备
  • 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 Options

class 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 = driver
        pass
        
    def 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 = driver
	        pass

(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 = driver



    def 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 = driver
            driver.implicitly_wait(10)
        self.opened_windows_dict = None
        pass

    def get_all_opened_windows(self):
        driver = self.driver
        cw = driver.current_window_handle
        res = {}
        # 获取已打开的标签页的信息
        tabs = driver.window_handles
        for t in tabs:
            driver.switch_to.window(t)
            res[str(driver.title)] = str(t)
        self.opened_windows_dict = res
        driver.switch_to.window(cw)
        print('已打开的标签页的信息:',)
        for k in res: print(f"\t{k}: {res[k]}")
        return res

    def switch_window(self, key):
        driver = self.driver
        cw = driver.current_window_handle
        # 获取已打开的标签页的信息
        tabs = driver.window_handles
        for t in tabs:
            driver.switch_to.window(t)
            if key in str(driver.title): cw = t
            break
        # driver.switch_to.window(cw)
        self.driver = driver
        pass


    def open_new_window(self, driver=None, url=None, delay_t=0.6):
        '''# 打开新标签页'''
        driver = self.driver if not driver else driver
        old_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 True
        driver.execute_script(f"window.open('{url if url else ''}');")
        time.sleep(delay_t)
        if len(driver.window_handles) >len(old_handle): return True
        return False

    def func1(self, xlsx):
        """ 学术网 """
        for p in range(50):
            # self.switch_window('故障诊断')
            driver = self.driver
            web = 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 = 0
            for 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').text
                    try:
                        b = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[3]/p[2]').text
                        school = str(b).split(',')
                        for s in school:
                            if 'university' in s.lower(): b = s[1:]
                    except: b = None
                    c = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[3]/p[1]').text
                    d = None
                    e = None
                    f = None
                    try:
                        h_index = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[1]/span[3]').text
                        paper = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[2]/span[3]').text
                        cite = w.find_element(by=By.XPATH, value=f'//div[{1 + i}]/div/div[2]/div[2]/div/span[3]/span[3]').text
                        f = f"H-index: {h_index},  papers: {paper}, cites: {cite}"
                    except: pass

                    g = None
                    h = 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 += 1
                except: pass
            print('记录:', 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: pass
            time.sleep(5)
        pass

    def func2(self, xlsx=None):
        for p in range(50):
            self.switch_window('青塔')
            driver = self.driver
            web = 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 = 0
            for 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.text
                print('b=', b)
                a = w.find_element(by=By.XPATH, value=f'//div[2]/div[2]/div[1]/div[2]').text
                print('a=', a)
                c = None
                d = None
                e = w.find_element(by=By.XPATH, value=f'//div[1]/div[1]').text
                print('e=', e)
                year = w.find_element(by=By.XPATH, value=f'//div[2]/div[2]/div[2]/div[2]').text
                money = w.find_element(by=By.XPATH, value=f'//div[2]/div[1]/div[2]/div[2]').text
                print('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]').text
                domain = w.find_element(by=By.XPATH, value=f'//div[2]/div[3]/div[2]/div[2]').text
                print('jijin=',jijin, 'domain=', domain)
                f = f"{jijin}, 领域: {domain}"
                g = None
                h = None
                print(i, '-----------', i)
                print(a, b, c, d, e, f)
                xlsx.input_data(a, b, c, d, e, f, g, h)
                num += 1
                break
                # except: pass
            print('记录:', num)
            break
            aa = 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:
                pass
            time.sleep(5)
        pass

    def func3(self, xlsx=None):
        for p in range(50):
            self.switch_window('大数据知识管理服务门户')
            driver = self.driver
            d = 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 = 0
            for i, w2 in enumerate(range(6)):
                w = web
                try:
                    # //*[@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 = None
                    d = None
                    e = 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]').text
                    money = 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]').text
                    domain = 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 = None
                    h = None
                    print(i+1, '-----------', i+1)
                    print(a, b, c, d, e, f)
                    xlsx.input_data(a, b, c, d, e, f, g, h)
                    num += 1
                # break
                except: pass
            print('记录:', 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:
                pass
            break
            # time.sleep(5)
        pass


    def func4(self, xlsx=None, key='Google2'):
        if key == 'Google': self.switch_window('Google')
        else: self.switch_window('必应')
        driver = self.driver
        data = 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: pass
            time.sleep(5)
        num = 0


if __name__ == '__main__':
    from temp import Make_Excel, input_data_list, input_data
    xlsx = 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.coloradmin.cn/o/1520828.html

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

相关文章

前端和后端权限控制【笔记】

前端权限设置【笔记】 前言版权推荐前端权限设置需求效果实现资源 后端权限控制1.给所有前端请求都携带token2.添加拦截器3.配置到WebMvcConfiguration4.更多的权限验证 最后 前言 2024-3-15 18:27:26 以下内容源自《【笔记】》 仅供学习交流使用 版权 禁止其他平台发布时删…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:FormLink)

提供静态卡片交互组件,用于静态卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件。 说明: 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 该组件仅可…

Gitlab CI/CD 自动化打包部署前端(vue)项目

一、虚拟机安装 1.vmware下载 2.镜像下载 3.Ubuntu 4.新建虚拟机 一直点下一步,直到点击完成。 5.分配镜像 二、Gitlab CI/CD 自动化部署项目 1.配置GitLab CI/CD: A.在你的Vue.js项目中,创建一个名为.gitlab-ci.yml的文件&#xff0…

Javaweb--CSS

一:概述 CSS (Cascading Style Sheet(层叠样式表))是一门语言,用于控制网页表现。 W3C标准规定了网页是由以下组成: 结构:HTML 表现:CSS 行为:JavaScrip…

【计算机网络】UDP/TCP 协议

TCP 协议 一、传输层1. 再谈端口号2. 端口号范围划分3. 进程和端口号4. netstat5. pidof 二、UDP 协议1. UDP 协议端格式(报文)2. UDP 的特点3. 面向数据报4. UDP 的缓冲区 三、TCP 协议1. 认识 TCP2. TCP 协议段格式(1)4 位首部长度(2&#…

(三)丶RabbitMQ的四种类型交换机

前言:四大交换机工作原理及实战应用 1.交换机的概念 交换机可以理解成具有路由表的路由程序,仅此而已。每个消息都有一个称为路由键(routing key)的属性,就是一个简单的字符串。最新版本的RabbitMQ有四种交换机类型&a…

用真值表、逻辑表达式和卡诺图来表示数字电路中的逻辑关系

真值表(Truth Table) 真值表是一种直观的方式,通过列出所有可能的输入值及其对应的输出值来表示逻辑关系。以下是使用真值表表示逻辑关系的步骤: 1. 确定输入变量:列出数字电路中所有的输入变量。 2. 定…

CART决策树暴力生成风控规则(Python代码)

上一篇我们介绍了决策树节点信息更新的方法风控规则的决策树可视化(升级版),以辅助我们制定风控规则,可视化的方法比较直观,适合做报告展示,但分析的时候效果没那么高。 本篇我们介绍一种通过决策树自动挖…

基于openresty构建运维工具链实践

本文字数:4591字 预计阅读时间:25 01 导读 如今OpenResty已广泛被各个互联网公司在实际生产环境中应用,在保留Nginx高并发、高稳定等特性基础上,通过嵌入Lua来提升在负载均衡层的开发效率并保证其高性能。本文主要介绍接口鉴权、流…

【Java】容器|Set、List、Map及常用API

目录 一、概述 二、List 1、List的常用API 2、ArrayList 3、List遍历 三、Set 1、Set的常用方法: 2、HashSet 3、遍历集合: 四、Map 1、Map常用API 2、HashMap 3、遍历Map 五、迭代器 一、概述 在Java中所有的容器都属于Collection接口下的内容 1…

D-泛醇(右泛醇)应用领域广泛 我国市场参与者众多

D-泛醇(右泛醇)应用领域广泛 我国市场参与者众多 D-泛醇又称右泛醇、原维生素B5,化学式为C9H19NO4,为泛醇的右旋异构体。D-泛醇外观呈无色粘稠或透明液体,微含臭味,可溶于甲醇、乙醇、水和丙二醇。D-泛醇综…

react native 实现自定义底部导航与路由文件配置

首先先把需要的一些库引入 yarn install react-navigation/native yarn install react-native-screens react-native-safe-area-context yarn install react-navigation/native-stack yarn add react-navigation/bottom-tabs 创建路由文件及四个底部导航页面 router文件下的bot…

MATLAB:一些杂例

a 2; b 5; x 0:pi/40:pi/2; %增量为pi/40 y b*exp(-a*x).*sin(b*x).*(0.012*x.^4-0.15*x.^30.075*x.^22.5*x); %点乘的意义 z y.^2; %点乘的意义 w(:,1) x; %组成w,第一列为x w(:,2) y; %组成w,第二列为y w(:,3) z; %组成w,第三列为z…

大规模C++程序设计 -- 基本规则

文章目录 基本规则概述成员数据访问全局命名空间全局数据自由函数枚举类型、typedef和常量数据预处理宏头文件中的名称 包含卫哨包含冗余卫哨文档标识符命名规则 基本规则 概述 任何精美的艺术不仅来源于创造,而且来自于规范。编程也是如此。C是易总大型语言&…

【New Release】PostgreSQL小版本(16.2, 15.6, 14.11, 13.14,12.18) 发布了

前言 PostgreSQL遵循小版本的发布规律,这一个季度的小版本又发布了。可以算作是2024年第一个季度的版本发布。如果总结其规律:大概就是2月、5月、8月、11月的样子。通常因为11月配合大版本的发布,它是起点,也有可能就是终点。起点…

【Docker篇】自定义Dockerfile的操作

文章目录 🍔镜像结构🛸什么是Dockerfile⭐基于Ubuntu镜像构建一个新镜像,运行一个java项目🔎使用 java:8-alpine 🍔镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。 我们以MySQL为例&am…

Vintage账龄分析表计算底层逻辑(Python实操)

大家好,我是东哥。 信贷风控领域中,经常用到账龄Vintage报表,这是入门初学者的难点之一,因为它涉及到用户还款、逾期等多种行为以及业务上的多种统计口径,因此很多朋友一直无法将逻辑梳理清楚。本次来给大家详细介绍V…

Java:多态

目录 1.向上转型2.动态绑定3.方法重写4.理解多态5.多态的优缺点 1.向上转型 把子类对象给到父类,代码如下 class Animal{public String name;public int age;public void eat(){System.out.println(this.name"正在吃饭!");} } class Dog ext…

力扣映射思辨题:赎金信

思路很简单&#xff1a;查到就改 bool canConstruct(char* ransomNote, char* magazine) {for(long x0;x<strlen(ransomNote);x){for(long y0;y<strlen(magazine);y){if(magazine[y]ransomNote[x]){ransomNote[x]1;magazine[y]1;break;}}}for(long x0;x<strlen(ranso…

【ArcGIS 脚本工具】批量导出布局为图片

文章开始前要介绍一下ArcMap与ArcPro在布局上的区别。 ArcMap10.x版本的mxd文件默认只有一个布局&#xff0c;所以如果一个项目需要出几张图&#xff0c;做好的办法就是建几个mxd文件。 但是ArcPro在这方面更加整合了&#xff0c;一个aprx文件内可以新建任意多的布局&#xff…