python爬虫之selenium知识点记录

news2024/11/14 19:00:26

selenium

一、前期准备

1、概述

selenium本身是一个自动化测试工具。它可以让python代码调用浏览器。并获取到浏览器中加载的各种资源。 我们可以利用selenium提供的各项功能。 帮助我们完成数据的抓取。

2、学习目标

  1. 掌握 selenium发送请求,加载网页的方法

  2. 掌握 selenium简单的元素定位的方法

  3. 掌握 selenium的基础属性和方法

  4. 掌握 selenium退出的方法

3、安装

安装:pip install selenium

它与其他库不同的地方是他要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助.

这里推荐用chrome浏览器

chrome驱动地址:http://chromedriver.storage.googleapis.com/index.html

 

根据你电脑的不同自行选择吧. win64选win32即可.

然后关键的来了. 把你下载的浏览器驱动放在python解释器所在的文件夹

Windwos: py -0p 查看Python路径

Mac: open + 路径

例如:open /usr/local/bin/

前期准备工作完毕. 上代码看看 感受一下selenium

from selenium.webdriver import Chrome  # 导入谷歌浏览器的类
​
​
# 创建浏览器对象
web = Chrome()  # 如果你的浏览器驱动放在了解释器文件夹
​
web.get("http://www.baidu.com")  # 输入网址
print(web.title)  # 打印title

运行一下你会发现神奇的事情发生了. 浏览器自动打开了. 并且输入了网址. 也能拿到网页上的title标题.

二、selenium的基本使用

1、加载网页:

selenium通过控制浏览器,所以对应的获取的数据都是elements中的内容

from selenium import webdriver
from selenium.webdriver.common.by import By
​
driver = webdriver.Chrome()
# 访问百度
driver.get("http://www.baidu.com/")
# 截图
driver.save_screenshot("baidu.png")

2、定位和操作:

# 搜索关键字 杜卡迪
driver.find_element(By.ID, "kw").send_keys("杜卡迪")
# 点击id为su的搜索按钮
driver.find_element(By.ID, "su").click()

3、查看请求信息:

driver.page_source   # 获取页面内容
driver.get_cookies()
driver.current_url

4、退出

driver.close()  # 退出当前页面
driver.quit()   # 退出浏览器

小结

  1. selenium的导包:from selenium import webdriver

  2. selenium创建driver对象:webdriver.Chrome()

  3. selenium请求数据:driver.get("http://www.baidu.com/")

  4. selenium查看数据: driver.page_source

  5. 关闭浏览器: driver.quit()

  6. 根据id定位元素: driver.find_element_by_id("kw")/driver.find_element(By.ID, "kw")

  7. 操作点击事件: click()

  8. 给输入框赋值:send_keys()

三、元素定位的方法

学习目标

  1. 掌握 selenium定位元素的方法

  2. 掌握 selenium从元素中获取文本和属性的方法

通过selenium的基本使用可以简单定位元素和获取对应的数据,接下来我们再来学习下 定位元素的其他方法

1、selenium的定位操作

  1. 元素定位的两种写法:

    • 直接调用型

       el = driver.find_element_by_xxx(value)
       # xxx是定位方式,后面我们会讲,value为该方式对应的值
    • 使用By类型(需要导入By) 建议使用这种方式

       # 直接掉用的方式会在底层翻译成这种方式
      from selenium.webdriver.common.by import By
      driver.find_element(By.xxx,value)
  2. 元素定位的两种方式:

    • 精确定位一个元素,返回结果为一个element对象,定位不到则报错

      driver.find_element(By.xx, value)  # 建议使用
      driver.find_element_by_xxx(value)
    • 定位一组元素,返回结果为element对象列表,定位不到返回空列表

      driver.find_elements(By.xx, value)  # 建议使用
      driver.find_elements_by_xxx(value)
  3. 元素定位的八种方法:

    以下方法在element之后添加s就变成能够获取一组元素的方法

    • By.ID 使用id值定位

      el = driver.find_element(By.ID, '')
      el = driver.find_element_by_id()   
    • By.XPATH 使用xpath定位

      el = driver.find_element(By.XPATH, '')
      el = driver.find_element_by_xpath()       
    • By.TAG_NAME. 使用标签名定位

      el = driver.find_element(By.TAG_NAME, '')
      el = driver.find_element_by_tag_name()    
    • By.LINK_TEXT使用超链接文本定位

      el = driver.find_element(By.LINK_TEXT, '')
      el = driver.find_element_by_link_text() 
    • By.PARTIAL_LINK_TEXT 使用部分超链接文本定位

      el = driver.find_element(By.PARTIAL_LINK_TEXT  , '')
      el = driver.find_element_by_partial_link_text()
    • By.NAME 使用name属性值定位

      el = driver.find_element(By.NAME, '')
      el = driver.find_element_by_name()
    • By.CLASS_NAME 使用class属性值定位

      el = driver.find_element(By.CLASS_NAME, '')   
      el = driver.find_element_by_class_name()
    • By.CSS_SELECTOR 使用css选择器定位

      el = driver.find_element(By.CSS_SELECTOR, '')  
      el = driver.find_element_by_css_selector()

注意:

  • 建议使用find_element/find_elements

  • find_elementfind_elements的区别

  • by_link_textby_partial_link_text的区别: 全部文本和包含某个文本

  • 使用: 以豆瓣为例

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    ​
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)  # 等待节点加载完成
    driver.get("https://www.douban.com/search?q=%E6%9D%B0%E6%A3%AE%E6%96%AF%E5%9D%A6%E6%A3%AE")
    time.sleep(2)
    # 使用id的方式获取右上角的搜索框
    # ret1 = driver.find_element(By.ID, 'inp-query')
    # ret1 = driver.find_element(By.ID, 'inp-query').send_keys("杰森斯坦森")
    # ret1 = driver.find_element_by_id("inp-query")
    # print(ret1)
    ​
    # 输出为:<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>
    ​
    # 搜索输入框  使用find_elements进行获取
    # ret2 = driver.find_elements(By.ID, "inp-query")
    # ret2 = driver.find_elements_by_id("inp-query")
    # print(ret2)
    #输出为:[<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>]
    ​
    # 搜索按钮  使用xpath进行获取
    # ret3 = driver.find_elements(By.XPATH, '//*[@id="inp-query"]')
    # ret3 = driver.find_elements_by_xpath("//*[@id="inp-query"]")
    # print(len(ret3))
    # print(ret3)
    ​
    # 匹配图片标签
    ret4 = driver.find_elements(By.TAG_NAME, 'img')
    for url in ret4:
        print(url.get_attribute('src'))
    ​
     #ret4 = driver.find_elements_by_tag_name("img")
    print(len(ret4))
    ​
    ret5 = driver.find_elements(By.LINK_TEXT, "浏览发现")
    # ret5 = driver.find_elements_by_link_text("浏览发现")
    print(len(ret5))
    print(ret5)
    ​
    ret6 = driver.find_elements(By.PARTIAL_LINK_TEXT, "浏览发现")
    # ret6 = driver.find_elements_by_partial_link_text("浏览发现")
    print(len(ret6))
    # 使用class名称查找
    ret7 = driver.find_elements(By.CLASS_NAME, 'nbg')
    print(ret7)
    driver.close()

注意:

find_element与find_elements区别

  1. 只查找一个元素的时候:可以使用find_element(),find_elements() find_element()会返回一个WebElement节点对象,但是没找到会报错,而find_elements()不会,之后返回一个空列表

  2. 查找多个元素的时候:只能用find_elements(),返回一个列表,列表里的元素全是WebElement节点对象

  3. 找到都是节点(标签)

  4. 如果想要获取相关内容(只对find_element()有效,列表对象没有这个属性) 使用 .text

  5. 如果想要获取相关属性的值(如href对应的链接等,只对find_element()有效,列表对象没有这个属性):使用 .get_attribute("href")

2、元素的操作

find_element_by_xxx方法仅仅能够获取元素对象,接下来就可以对元素执行以下操作 从定位到的元素中提取数据的方法

  1. 从定位到的元素中获取数据

el.get_attribute(key)           # 获取key属性名对应的属性值
el.text                         # 获取开闭标签之间的文本内容
  1. 对定位到的元素的操作

el.click()                      # 对元素执行点击操作
​
el.submit()                     # 对元素执行提交操作
​
el.clear()                      # 清空可输入元素中的数据
​
el.send_keys(data)              # 向可输入元素输入数据

使用示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
​
driver =webdriver.Chrome()
​
driver.get("https://www.douban.com/")
# 打印页面内容 (获取到以后可以进行后续的xpath,bs4 或者存储等)
print(driver.page_source)
​
ret4 = driver.find_elements(By.TAG_NAME, "h1")
print(ret4[0].text)
#输出:豆瓣
​
ret5 = driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")
print(ret5[0].get_attribute("href"))
#输出:https://www.douban.com/doubanapp/app?channel=nimingye
​
driver.close()

小结

  1. 根据xpath定位元素:driver.find_elements(By.XPATH,"//*[@id='s']/h1/a")

  2. 根据class定位元素:driver.find_elements(By.CLASS_NAME, "box")

  3. 根据link_text定位元素:driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")

  4. 根据tag_name定位元素:driver.find_elements(By.TAG_NAME, "h1")

  5. 获取元素文本内容:element.text

  6. 获取元素标签属性: element.get_attribute("href")

  7. 向输入框输入数据: element.send_keys(data)

四、selenium的其他操作

学习目标

  1. 掌握 selenium处理cookie等方法

  2. 掌握 selenium中switch的使用

  3. 掌握selenium中无头浏览器的设置

1、无头浏览器

我们已经基本了解了selenium的基本使用了. 但是呢, 不知各位有没有发现, 每次打开浏览器的时间都比较长. 这就比较耗时了. 我们写的是爬虫程序. 目的是数据. 并不是想看网页. 那能不能让浏览器在后台跑呢? 答案是可以的

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
​
opt = Options()
opt.add_argument("--headless")
opt.add_argument('--disable-gpu')
opt.add_argument("--window-size=4000,1600")  # 设置窗口大小
​
web = Chrome(options=opt)

1、selenium 处理cookie

通过driver.get_cookies()能够获取所有的cookie

  • 获取cookie

    dictCookies = driver.get_cookies()
  • 设置cookie

    driver.add_cookie(dictCookies)
  • 删除cookue

    #删除一条cookie
    driver.delete_cookie("CookieName")
    # 删除所有的cookie
    driver.delete_all_cookies()

2、页面等待

  • 为什么需要等待 如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,这个时候就可以设置一个等待时间,强制等待指定时间,等待结束之后进行元素定位,如果还是无法定位到则报错

  • 页面等待的三种方法

    • 强制等待

      import time
      time.sleep(n)      # 阻塞等待设定的秒数之后再继续往下执行
    • 显式等待(自动化web测试使用,爬虫基本不用)

      from selenium.webdriver.common.keys import Keys
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      ​
      WebDriverWait(driver, 10,0.5).until( EC.presence_of_element_located((By.ID, "myDynamicElement"))
      # 显式等待指定某个条件,然后设置最长等待时间10,在10秒内每隔0.5秒使用指定条件去定位元素,如果定位到元素则直接结束等待,如果在10秒结束之后仍未定位到元素则报错
    • 隐式等待 隐式等待设置之后代码中的所有元素定位都会做隐式等待

      driver.implicitly_wait(10)    # 在指定的n秒内每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错

注意:

Selenium显示等待和隐式等待的区别 1、selenium的显示等待 原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception

(简而言之,就是直到元素出现才去操作,如果超时则报异常)

2、selenium的隐式等待

原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。 注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素

3、switch方法切换的操作

3.1 一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
# 1. 获取当前所有的窗口
current_windows = driver.window_handles
​
# 2. 根据窗口索引进行切换
driver.switch_to.window(current_windows[1])
​
driver.switch_to.window(web.window_handles[-1])  # 跳转到最后一个窗口
driver.switch_to.window(current_windows[0])  # 回到第一个窗口
3.2 iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是
driver.switch_to.frame(name/el/id)     传入的参数可以使iframe对应的id值,也可以是用元素定位之后的元素对象

动手:qq邮箱

在使用selenium登录qq邮箱的过程中,我们会发现,无法在邮箱的登录input标签中输入内容,通过观察源码可以发现,form表单在一个frame中,所以需要切换到frame中

3.3 当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()
4. 页面前进和后退
driver.forward()     # 前进
driver.back()        # 后退
driver.refresh()         # 刷新
driver.close()       # 关闭当前窗口
5、设置浏览器最大窗口
driver.maximize_window()  #最大化浏览器窗口

4、selenium的优缺点

  • 优点

    • selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易

    • 使用难度简单

    • 爬取速度慢,爬取频率更像人的行为,天生能够应对一些反爬措施

  • 缺点

    • 由于selenium操作浏览器,因此会将发送所有的请求,因此占用网络带宽

    • 由于操作浏览器,因此占用的内存非常大(相比较之前的爬虫)

    • 速度慢,对于效率要求高的话不建议使用

小结

  1. 获取cookie: get_cookies()

  2. 删除cookie: delete_all_cookies()

  3. 切换窗口:switch_to.window()

  4. 切换iframe: switch_to.frame()

5、selenium的配置

selenium启动谷歌浏览器的参数设置
通知、位置、摄像头和麦克风权限控制的配置
	options = webdriver.ChromeOptions()
	options.add_experimental_option("prefs", { \
	    "profile.default_content_setting_values.media_stream_mic": 1,     # 麦克风 1:allow, 2:block 
	    "profile.default_content_setting_values.media_stream_camera": 1,  # 摄像头 1:allow, 2:block 
	    "profile.default_content_setting_values.geolocation": 1,          # 地理位置 1:allow, 2:block 
	    "profile.default_content_setting_values.notifications": 1,         # 通知 1:allow, 2:block 
	    'download.default_directory': download_path  # 下载路径
	  })
	driver = webdriver.Chrome(chrome_options=options)

其他参数
options.add_argument(‘headless’) # 无头模式
options.add_argument(‘window-size={}x{}’.format(width, height)) # 直接配置大小和set_window_size一样
options.add_argument(‘disable-gpu’) # 禁用GPU加速
options.add_argument(‘proxy-server={}’.format(self.proxy_server)) # 配置代理
options.add_argument(’–no-sandbox’) # 沙盒模式运行
options.add_argument(’–disable-setuid-sandbox’) # 禁用沙盒
options.add_argument(’–disable-dev-shm-usage’) # 大量渲染时候写入/tmp而非/dev/shm
options.add_argument(’–user-data-dir={profile_path}’.format(profile_path)) # 用户数据存入指定文件
options.add_argument(‘no-default-browser-check) # 不做浏览器默认检查
options.add_argument(“–disable-popup-blocking”) # 允许弹窗
options.add_argument(“–disable-extensions”) # 禁用扩展
options.add_argument(“–ignore-certificate-errors”) # 忽略不信任证书
options.add_argument(“–no-first-run”) # 初始化时为空白页面
options.add_argument(’–start-maximized’) # 最大化启动
options.add_argument(’–disable-notifications’) # 禁用通知警告
options.add_argument(’–enable-automation’) # 通知(通知用户其浏览器正由自动化测试控制)
options.add_argument(’–disable-xss-auditor’) # 禁止xss防护
options.add_argument(’–disable-web-security’) # 关闭安全策略
options.add_argument(’–allow-running-insecure-content’) # 允许运行不安全的内容
options.add_argument(’–disable-webgl’) # 禁用webgl
options.add_argument(’–homedir={}’) # 指定主目录存放位置
options.add_argument(’–disk-cache-dir={临时文件目录}’) # 指定临时文件目录
options.add_argument(‘disable-cache’) # 禁用缓存
options.add_argument(‘excludeSwitches’, [‘enable-automation’]) # 开发者模式
options.add_argument(’–disable-infobars’) # 禁止策略化
options.add_argument(‘–incognito’) # 隐身模式(无痕模式)
options.add_argument(‘–disable-javascript’) # 禁用javascript
options.add_argument(‘–hide-scrollbars’) # 隐藏滚动条, 应对一些特殊页面
options.add_argument(‘blink-settings=imagesEnabled=false’) # 不加载图片, 提升速度
options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" # 手动指定使用的浏览器位置
options.add_argument(‘lang=en_US’) # 设置语言
prefs = {“”:“”}

prefs[“credentials_enable_service”] = False

prefs[“profile.password_manager_enabled”] = False

chrome_option_set.add_experimental_option(“prefs”, prefs) # 屏蔽’保存密码’提示框
更多flags参数请参考:[https://blog.alanwei.com/blog/2021/03/15/chrome-flags/]

其他配置方式
可以自己复制谷歌浏览器的配置文件夹修改,并在启动时指定使用的文件夹

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\username\\AppData\\Local\\Google\\Chrome\\User Data\\Default")
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://ceshiren.com")

使用同一个浏览器进行多次操作

首先用cmd从谷歌浏览器目录以指定端口启动浏览器:
chrome.exe --remote-debugging-port=12306
再在脚本中使用参数来获取连接,这样就可以一直使用命令行打开的谷歌浏览器进行操作

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:12306")
driver = webdriver.Chrome(options=options)

 上面的参数很多不是经常用到或者在selenium操作过程中使用,所以这里并没有验证,供大家参考。

数据采集高级动态页面Selenium

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

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

相关文章

新一代电话机器人开源PHP源代码

使用easyswoole 框架开发的 新一代电话机器人开源PHP源码 项目地址&#xff1a;https://gitee.com/ddrjcode/robotphp 代理商页面演示地址 http://119.23.229.15:8080 用户名&#xff1a;c0508 密码&#xff1a;123456 包含 AI外呼管理&#xff0c;话术管理&#xff0c;CR…

简易内存池2 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 请实现一个简易内存池,根据请求命令完成内存分配和释放。 内存池支持两种操作命令&#xff0c;REQUEST和RELEASE&#xff0c;其格式为: REQUEST请求的内存大小 …

golang学习5,glang的web的restful接口

1. //返回json r.GET("/getJson", controller.GetUserInfo) package mainimport (/*"net/http"*/"gin/src/main/controller""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/get", func(ctx *…

【研发日记】Matlab/Simulink技能解锁(三)——在Stateflow编辑窗口Debug

文章目录 前言 State断点 Transition断点 条件断点 按State步进 Watch Data Value Sequence Viewer 分析和应用 总结 前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 见《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑…

数据结构开篇

目录 一. 如何学好数据结构二. 基本概念和术语2.1 区分数据、数据元素、数据项、数据对象2.2 数据结构2.2.1 逻辑结构2.2.2 存储结构 2.3 数据类型和抽象数据类型2.4 抽象数据类型的实现 \quad 一. 如何学好数据结构 勤于思考;多做练习;多上机;善于寻求帮助;不怕困难&#xff…

NLP算法实战项目:使用 BERT 进行文本多分类

大多数研究人员将他们的研究论文提交给学术会议&#xff0c;因为这是更快地使研究结果可用的途径。寻找和选择合适的会议一直是一项具有挑战性的任务&#xff0c;特别是对于年轻的研究人员来说。基于先前会议论文集的数据&#xff0c;研究人员可以增加其论文被接受和发表的机会…

基于协同过滤算法的图书推荐系统

目录 一、功能介绍 二、开发环境 三、安装部署说明 一、功能介绍 本系统是一个采用协同过滤算法的图书推荐系统。 数据集&#xff1a;数据集来自亚马逊开源的Book-Crossings数据集。Book-Crossings数据集包含 278,858 个用户的 271,379 本书的 1,149,780 个评分。评分范围从1…

FL Studio选购指南:新手小白应该选择哪个版本FL Studio?

很多打算入手正版FL Studio的新手朋友都会纠结一个问题&#xff1a;哪个版本的FL Studio更适合我&#xff0c;到底应该入手哪一款FL Studio&#xff1f;本文会介绍每个版本之间的差异点&#xff0c;并带大家选择适合自己的FL Sudio版本。 FL Studio全版本 在选购前有一些小知识…

25高数考研张宇 -- 公式总结(更新中)

1. 两个重要极限 (1) lim ⁡ x → 0 sin ⁡ x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0​xsinx​1, 推广形式 lim ⁡ f ( x ) → 0 sin ⁡ f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0​f(x)sinf(x)​1. (2) lim ⁡…

小项目:2024/3/2

一、TCP机械臂测试 代码&#xff1a; #include <myhead.h> #define SER_IP "192.168.125.254" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.199.131" //客户端IP #define CLI_P…

Linux线程【互斥与同步】

目录 1.资源共享问题 1.1多线程并发访问 1.2临界区和临界资源 1.3互斥锁 2.多线程抢票 2.1并发抢票 2.2 引发问题 3.线程互斥 3.1互斥锁相关操作 3.1.1互斥锁创建与销毁 3.1.2、加锁操作 3.1.3 解锁操作 3.2.解决抢票问题 3.2.1互斥锁细节 3.3互斥…

[NSSCTF 2nd] web复现

1.php签到 <?phpfunction waf($filename){$black_list array("ph", "htaccess", "ini");$ext pathinfo($filename, PATHINFO_EXTENSION);foreach ($black_list as $value) {if (stristr($ext, $value)){return false;}}return true; }if(i…

【Spring IoC】实验四:特殊值处理

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

【NDK系列】Android tombstone文件分析

文件位置 data/tombstone/tombstone_xx.txt 获取tombstone文件命令&#xff1a; adb shell cp /data/tombstones ./tombstones 触发时机 NDK程序在发生崩溃时&#xff0c;它会在路径/data/tombstones/下产生导致程序crash的文件tombstone_xx&#xff0c;记录了死亡了进程的…

electron nsis 安装包 window下任务栏无法正常固定与取消固定 Pin to taskbar

问题 win10系统下&#xff0c;程序任务栏在固定后取消固定&#xff0c;展示的程序内容异常。 排查 1.通过论坛查询&#xff0c;应该是与app的api setAppUserModelId 相关 https://github.com/electron/electron/issues/3303 2.electron-builder脚本 electron-builder…

ABAP - SALV教程04 添加状态栏

CL_SALV_TABLE中提供了 GET_FUNCTIONS方法.GET_FUNCTIONS方法返回的是一个CL_SALV_FUNCTIONS_LIST类型的实例对象. 类CL_SALV_FUNCTIONS_LIST两个方法(SET_ALL、SET_DEFAULT)可以添加标准状态栏 实现步骤: 定义SET_STATUS私有方法. PRIVATE SECTION.METHODS:set_status CHA…

qt 基于百度API的人脸识别

百度云官网&#xff1a;点击跳转 一、创建应用 跳转进去&#xff0c;可以看到以下界面&#xff1a; 点击红色圈内的“去创建”&#xff0c;创建自己的项目。可以看到以下界面&#xff1a; 输入“应用名称”&#xff0c;并勾选“人脸对比”&#xff0c;还要到页面的最后输入“应…

董兆祥出席工业废水资源化,开创变废为宝新途径演讲

演讲嘉宾&#xff1a;董兆祥 董事长 河北奥博水处理有限公司 演讲题目&#xff1a;工业废水资源化&#xff0c;开创变废为宝新途径 会议简介 “十四五”规划中提出&#xff0c;提高工业、能源领城智能化与信息化融合&#xff0c;明确“低碳经济”新的战略目标&#xff0c;热…

C++之stack

1、stack简介 stack是实现的一个先进后出&#xff0c;后进先出的容器。它只有一个出口&#xff0c;只能操作最顶端元素。 2、stack库函数 &#xff08;1&#xff09;push() //向栈压入一个元素 &#xff08;2&#xff09;pop() //移除栈顶元素 &#xff08;3…

‘conda‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

如果你在运行 conda 命令时收到了 ‘conda’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 的错误消息&#xff0c;这可能意味着 Anaconda 并没有正确地添加到你的系统路径中。 1.你可以尝试手动添加 Anaconda 到系统路径中。以下是在 Windows 系统上添加…