Selenium 的使用

news2024/11/25 4:56:06

selenium 是一个自动化测试工具,利用它可以驱动浏览器完成特定的操作,例如点击,下拉等,还可以获取浏览器当前呈现的页面的源代码,做到所见即所爬,对于一些 JavaScript 动态渲染的界面来说,这种爬取方法非常有效

准备工作:

1. Chrome 浏览器

2. 在Chrome 浏览器上配置好 ChromeDriver 

3. 需要安装好 python 的 Selenium 库

基本用法

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    input = browser.find_element(by=By.ID, value='kw')
    input.send_keys('python')
    input.send_keys(Keys.ENTER)
    wait = WebDriverWait(browser, 10)
    wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
    print(browser.current_url)
    print(browser.get_cookies())
    print(browser.page_source)
finally:
    browser.close()

 输出结果一部分

m:4px solid #626675;position:absolute;left:50%;top:-8px;margin-left:-4px}.head_wrapper .sam_search .sam_search_rec_hover{right:29px}.head_wrapper .sam_search .sam_search_soutu_hover{display:none;right:-12px}.c-frame{margin-bottom:18px}.c-offset{padding-left:10px}.c-gray{color:#666}.c-gap-top-small{margin-top:5px}.c-gap-top{margin-top:10px}.c-gap-bottom-small{margin-bottom:5px}.c-gap-bottom{margin-bottom:10px}.c-gap-left{margin-left:12px}.c-gap-left-small{margin-left:6px}.c-gap-right{margin-right:12px} 

运行代码后,会弹出一个 Chrome 浏览器。浏览器会自动跳到百度页面,然后在搜索框中输入 python ,就会跳转到搜索结果页面,并且输出了浏览器可以看到的真实内容

初始化浏览器对象

Selenium 支持的浏览器非常多, 既有 Chrome , Firefox, Edge, Safari 等电脑端的浏览器, 也有 Aadroid , BlackBerry 等手机端的浏览器

我们可以用如下方式初始化浏览器

from selenium import webdriver

browser = webdriver.Chrome()

browser = webdriver.Firefox()

browser = webdriver.Edge()

browser = webdriver.Safari()

这样就完成浏览器的初始化,并将其赋值给了 browser。

访问页面

我们可以使用 get 方法请求页面,其参数传入要请求网页的 URL 即可

例如访问 淘宝

from selenium import webdriver

browser = webdriver.Chrome()

browser.get('https://taobao.com')
print(browser.page_source)
browser.close()

查找节点

Selenium 可以驱动浏览器完成各种操作,比如填充表单,模拟点击等。 比如想要往某个输入框中输入文字,总得知道输入框在哪? 对此, Selenium 为我们提供了一系列用来查找节点的方法,我们可以使用这些方法获取想要的节点,以便执行下一步操作或提取信息

单个节点

例如我们想要从淘宝页面提取搜素框这个节点,首先要观察这个页面的源代码 如:

可以发现,淘宝页面的 id 属性值是 q  name 的属性值也是 q ,  此外还有许多其他属性,我们可以用多种方式获取它们。 例如 find_element, 此外还有根据 XPaht , CSS 选择器等的获取方式

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first = browser.find_element(by=By.ID, value='q')
input_second = browser.find_element(by=By.CSS_SELECTOR, value='#q')
input_third = browser.find_element(by=By.XPATH, value='//*[@id="q"]')
print(input_first)
print(input_second)
print(input_third)
browser.close()

<selenium.webdriver.remote.webelement.WebElement (session="c5c118afb490f60e84bed2b2f4611e42", element="f.C53AC604CB64324F54B40B7E43A6D38B.d.1C93D5A409EEB94B333BC42260C5A292.e.76")>
<selenium.webdriver.remote.webelement.WebElement (session="c5c118afb490f60e84bed2b2f4611e42", element="f.C53AC604CB64324F54B40B7E43A6D38B.d.1C93D5A409EEB94B333BC42260C5A292.e.76")>
<selenium.webdriver.remote.webelement.WebElement (session="c5c118afb490f60e84bed2b2f4611e42", element="f.C53AC604CB64324F54B40B7E43A6D38B.d.1C93D5A409EEB94B333BC42260C5A292.e.76")>

可以看到三种返回的结果完全一致

find_element 接收两个参数, 分别是 查找方式, 方式的值,

多个节点

如果查找单个节点, find_element 方法完全可以了,如果是多个值则需要用到 find_elements ,如果目标包含多个,再用 find_element 就只能得到第一个节点了

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
lis = browser.find_elements(by=By.CSS_SELECTOR,value='.service-bd li')
print(lis)
browser.close()

结果的一部分 

[<selenium.webdriver.remote.webelement.WebElement (session="804653dd16ca3dbb0201b350a6329d0d", element="f.429C48601A80CCAAF703BB10CB090BC9.d.6DF9DEBC64815721F7B71806DF4182E6.e.2749")>, <selenium.webdriver.remote.webelement.WebElement (session="804653dd16ca3dbb0201b350a6329d0d", element="f.429C48601A80CCAAF703BB10CB090BC9.d.6DF9DEBC64815721F7B71806DF4182E6.e.2933")>,  element="f.429C48601A80CCAAF703BB10CB090BC9.d.6DF9DEBC64815721F7B71806DF4182E6.e.4787")>]
 

这里简化了输出的结果,可以看到内容变成了列表类型, 列表中的每个节点都属于 WebElement 类型。

节点交互

Selenium 可以驱动浏览器执行一些操作。比较常见的有: 用 send_keys 方法输入文字, 用 clear 方法清空文字, 用 click 方法点击按钮

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element(by=By.ID, value='q')
input.send_keys('iPhone')
time.sleep(1)
input.clear()
input.send_keys('iPad')
button = browser.find_element(by=By.CLASS_NAME, value='btn-search')
button.click()
browser.close()

动作链

在上面的实例中,交互操作都是针对某个节点执行的。例如输入框, 调用它的输入文字方法 send_keys 和清空文字方法 clear, 对于搜索按钮,调用了它的点击方法 click , 其实还有一些操作,它们没有特定的执行对象,比如鼠标拖拽, 键盘按键等,这些操作需要另一中方式执行,那就是操作链

例如拖拽

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()

url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')
soure = browser.find_element(by=By.CSS_SELECTOR, value='#draggable')
target = browser.find_element(by=By.CSS_SELECTOR, value='#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(soure, target)
actions.perform()

这里首先打开网页中的一个拖拽实例, 然后以此选中要拖拽的节点和拖拽至的目标点,接着声明一个 ActionChains 对象并赋值给 actions 的变量, 再后调用 actions 变量的 drag_and_drop 方法声明拖拽对象和拖拽目标, 最后调用 perform 方法执行动作, 就完成了拖拽操作

更多动作链参考: http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

运行 JavaScript

还有一些操作, Selenium 没有提供 API ,例如下拉进度条,面对这种情况可以模拟运行 JavaScript 此时使用 execute_script 方法即可实现

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")')

获取属性信息

前面我们已经通过 page_source 属性获取了网页源代码, 下面就可以说使用解析库如正则, Beautiful Soup 等来直接提取节点信息了,

不过既然 Selenium 已经提供了选择节点的方法, 返回的结果是 WebElement 类型,那么它肯定也有相关的方法和属性来直接提取节点信息,例如属性,文本值等

获取属性

可以用 get_attribute 方法获取节点的属性,但前提是的先选中这个节点

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
url = 'https://spa2.scrape.center/'
browser.get(url)
logo = browser.find_element(by=By.CLASS_NAME, value='logo-image')
print(logo)
print(logo.get_attribute('src'))

<selenium.webdriver.remote.webelement.WebElement (session="9efa96a5c4b7c383a14bcc90510e469d", element="f.A62ECDF1059CBBEEB80C6FE1F3D9718E.d.1BFFD3C28B378C45F85177DC773F9A08.e.11")>
https://spa2.scrape.center/img/logo.a508a8f0.png

向 get_attribute 方法的参数传入想要获取的属性名,就可以得到该属性的值了

获取文本值

每个 webElement 节点都有 text 属性, 直接调用这个属性就可以得到节点内部的文本信息

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://spa2.scrape.center/')
input = browser.find_element(by=By.CLASS_NAME, value='logo-title')
print(input.text)

Scrape

获取ID ,位置, 标签名和大小

id 属性获取节点 ID , location 属性获取节点在页面中的相对位置,tag_name 属性用于获取标签名称, size 属性获取节点的大小,也就是宽高

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://spa2.scrape.center/')
input = browser.find_element(by=By.CLASS_NAME, value='logo-title')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)

f.316EC4AAC7943F0D609F3E843A7C31C7.d.43965F4D937A16BDC6D13509A61B3948.e.13
{'x': 211, 'y': 13}
span
{'height': 40, 'width': 77}
 

切换Frame 

我们知道网页中有一种节点叫做 iframe , 也就是子 Frame, 相当于页面的子页面,它的结构和外部网页的结构完全一致, Selenium 打开一个页面后,默认实在父 Frame 里操作, 此时这个页面如果还有子 Frame , 它是不能获取子 Frame 里的节点的, 这时就需要用到 switch_to.frame 方法切换 Frame

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException

browser = webdriver.Chrome()
browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframeResult')
try:
    logo = browser.find_element(by=By.CLASS_NAME, value='logo')
except NoSuchElementException:
    print('NO LOGO')

browser.switch_to.parent_frame()
logo = browser.find_element(by=By.CLASS_NAME, value='logo')
print(logo)
print(logo.text)

NO LOGO
<selenium.webdriver.remote.webelement.WebElement (session="7aa6a87f145168d7f4421d65f1362c6d", element="f.8F10A1ECDF6EAF6BE779BC6F0E41584C.d.51D4DDAA62F2FB4E3CD2E3B57E996B4F.e.12")>
 

首先通过 switch_to.frame 方法切换到子 Frame 里,然后尝试获取其中的 logo 节点(子Frame 里并没有 logo 节点),如果找不到, 就会抛出NoSuchElementException 异常,异常被捕捉后, 会输出 NO LOGO ,接着切回父 Frame ,重新获取 logo节点, 发现此时可以获取成功了

所以当页面中包含子 Frame 时,如果想获取子 Frame 中的节点,需要首先调用 switch_to.frame 方法,切换到对应的 Frame 中,再进行操作

这里的 logo.text 并没有内容,教程里是有内容的

延时等待

在 Selenium 中, get 方法在网页框架加载结束后才会结束执行,如果我们尝试在 get 反复执行完毕时获取网页源代码,其结果可能并不是浏览器完全加载完成的页面,因为某些页面有额外的 Ajax 请求,页面还会经由 JavaScript 渲染。 所以在必要的时候,我们需要设置浏览器延时等待一定的时间,确保节点已经加载出来

隐式等待

使用隐式等待进行测试时, 如果 Selenium 没有在 DOM 上找到节点, 将继续等待,在超出设定时间后,抛出找不到节点的异常。换句话说,在查找节点而节点没有立即出现时,隐式等待会先等一会再查找MOD , 默认的等待时间是 9 

from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get('https://spa2.scrape.center/')
input = browser.find_element(by=By.CLASS_NAME, value='logo-image')
print(input)

显示等待

隐式等待并不好,因为我们只规定了一个固定时间, 而页面的加载时间会受网络条件的影响。

还有一种更合适的等待方式----显示等待, 这种方式会指定要查找的节点和最长等待时间, 如果在规定时间加载出了要查找的节点,就返回这个节点,如果到了规定时间依然没有加载出节点,就抛出超时异常

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get('https://www.taobao.com/')
wait = WebDriverWait(browser, 10)
input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
print(input)
print(button)

<selenium.webdriver.remote.webelement.WebElement (session="865015d53af99060b436be643a8cd6d3", element="f.C06F497BF8676D64692A5EAC4C119D26.d.7FC8C51621189FF01A23489903B4288A.e.76")>
<selenium.webdriver.remote.webelement.WebElement (session="865015d53af99060b436be643a8cd6d3", element="f.C06F497BF8676D64692A5EAC4C119D26.d.7FC8C51621189FF01A23489903B4288A.e.68")>
 

这里首先引入 WebDriverWait 对象, 指定最长等待时间为 10 , 并赋值个 wait 变量,然后调用 wait 的 until 方法,传入等待条件

这里传入了 presence_of_element_located 这个条件代表节点出现,其参数是节点的定位元组 (By.ID, 'q') , 表示节点 ID 为 q 的节点 (即搜索框)。这样做达到的效果是如果节点 ID 为 q 的节点在 10秒内成功加载出来了,就返会改节点,如果超过10秒还没有加载出来,就抛出异常

然后传入等待的条件是 element_to_be_clickable, 代表按钮可点击,所以查找按钮是要查找 CSS 选择器为 .btn-search 的按钮,如果 10 秒内它是可点击的,也就是按钮节点成功加载出来了,就返回该节点,如果超过 10 还是不可点击,也就是节点按钮没有加载出来,就爬出异常

如果没有加载出来

selenium.common.exceptions.TimeoutException: Message:

等待条件有很多,具体参考:

http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions

前进和后退

平常使用浏览器时,都有前进和后退的功能, Selenium 也可以完成这个操作, 它使用 forward 方法实现前进, 使用 back 方法实现后退

import time
from selenium import webdriver


browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
time.sleep(2)
browser.get('https://www.taobao.com')
time.sleep(2)
browser.get('https://www.python.org')
time.sleep(2)
browser.back()
time.sleep(2)
browser.forward()
time.sleep(2)
browser.close()

Cookie

使用 Selenium 还可以方便对 Cookie 进行操作,如获取, 添加,删除等

from selenium import webdriver

browser = webdriver.Edge()
browser.get('https://www.zhihu.com/explore')
print(browser.get_cookies())
browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})
print(browser.get_cookies())
browser.delete_all_cookies()
print('最后一个:', browser.get_cookies())

I:\ANACONDA\python.exe I:\githubCode\mycode\JavaScript动态渲染\Cookie_.py 
[{'domain': '.zhihu.com', 'expiry': 1756542886, 'httpOnly': False, 'name': 'd_c0', 'path': '/', 'sameSite': 'Lax', 'secure': False, 'value': 'ASCSgRSf-xiPTtTRFO8DRJeM7Ee1uaEY6Pw=|1721982887'}, {'domain': '.zhihu.com', 'httpOnly':  '6c4a08c3-8e65-4e80-be84-742c02f9b491'}]
[{'domain': '.zhihu.com', 'httpOnly': False, 'name': 'HMACCOUNT', 'path': '/', 'sameSite': 'Lax',

value': 'germey ': 'Lax', 'secure': False, 'value': '6c4a08c3-8e65-4e80-be84-742c02f9b491'}]
最后一个: []

输出的内容太多,删掉了一部分

这里我们先访问了知乎,知乎页面加载完成后,浏览器其实已经生成 Cookie 了,然后,调用浏览器对象的 get_cookies 方法获取所有的 Cookie , 接着,添加一个 Cookie , 这里传入了一个字典,包含 name , domain 和 value 等键值, 之后,再次获取所有 cookie 会发现结果中多了一项,就是我们新加的 cookie ,最后调用 delete_all_cookies 方法删除所有的 Cookie 并再次获取,会发现此时结果为空

选项卡管理

访问网页时,会开启一个个选项卡,在 Selenium 中, 我们可以对选项卡做操作

import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')
print(browser.window_handles)
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(1)
browser.switch_to.window(browser.window_handles[0])
browser.get('https://www.python.org')

 ['7CC91CF864EF7BCCB720CFA05C53C539', 'BD5AF3B6A876C676AC3FDEA01C7AD7AE']

这里首先访问百度,然后调用 execue_script 方法, 向其参数传入 window.open() 这个 javaScript 语句,表示开启一个新选项卡, 返回值是选项卡的代号列表。要想切换选项卡,只需要调用 switch_to.window 方法即可, 其中参数是目的选项卡的代号,这里我们将新开选项卡的代号传入,就切换到了第 2 个选项卡,然后在这个选项卡下打开一个新页面,再重新调用 switch_to.window 方法切回第 1 个选项卡。

异常处理

使用 Selenium 时难免会遇到一些异常, 例如超时,节点未找到等,一旦出现此类异常,程序便不会再运行了,此时我们可以使用 try except 语句捕获异常

节点未找到异常

from selenium import webdriver
from selenium.webdriver.common.by import By

# 节点未找到异常
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.find_element(by=By.ID, value='hello')

selenium.common.exceptions.NoSuchElementException: Message: no such element

捕获异常

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException

# 异常捕获
browser = webdriver.Chrome()
try:
    browser.get('https://www.baidu.com')
except TimeoutException:
    print('Time Out')

try:
    browser.find_element(by=By.ID, value='hello')
except NoSuchElementException:
    print('No Element')
finally:
    browser.close()

No Element

关于更多异常类参考官方文档: 

http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions

反屏蔽

现在很多网站增加了对 selenium 的检测, 防止一些爬虫恶意爬取,如果检测到有人使用 Selenium 打开浏览器,就直接屏蔽

在大多数情况下,检测的基本原理是检测当前浏览器窗口下的window.navigator 对象是否包含 webdriver 属性, 因为在正常使用浏览器的时候,这个属性是 undefind, 一旦使用了 Selenium ,一旦使用了 Selenium ,它就会给 window.navigator 设置 webdriver 属性。 很多网站通过 JavaScript 语句判断是否存在 webdriver 属性,如果存在就直接屏蔽

一个典型的案例网站 https://antispider1.scrape.center/ 就是使用上述原理, 检测是否存在 webdriver 属性, 如果我们直接使用 Selenium 直接爬取该网站的数据, 就不能得到任何数据

这时会有人说直接使用 JavaScript 语句把 webdriver 属性置空不就行了,例如调用 execute_script 方法执行这行代码

Object.defineProperty(navigator, "webdriver", {get: () => undefined})

这行代码确实可以把 webdriver 属性置空, 但 execute_script 方法是在页面加载完成之后才调用这行 JavaScript 语句,太晚了, 网站早在页面渲染执勤啊就已经检测 webdriver 属性了,所以上述方法并不能达到预期的效果

在 Selenium 中, 可以调用 CDP (即 Chrome Devtools Protocol, Chrome 开发工具协议)解决这个问题,利用它可以实现在每个页面刚加载的时候就执行 JavaScript 语句, 将 webdriber 属性置空。这里执行的 CDP  方法叫做 Page.addScriptToEvaluateOnNewDocument, 将上面的 JavaScript 语句传入其中即可,另外还可以加入几个选项来 隐藏 WebDriver 提示条和自动化信息

正常访问

from selenium import webdriver
import time

# 正常访问
browser = webdriver.Chrome()
browser.get('https://antispider1.scrape.center/')
time.sleep(5)
print(1111)

隐藏 webdriver 

from selenium import webdriver
from selenium.webdriver import ChromeOptions
import time

option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
                        {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
browser.get('https://antispider1.scrape.center/')
time.sleep(3)

在大多数情况下,以上方法可以实现 Selenium 的反屏蔽。 但也存在一些特殊的网站会对 WebDriver 属性设置更多的检测, 这种情况,就需要进行具体排查

无头模式

在上面的案例中,每次爬取都会有窗口弹来弹去,虽然有助于观察爬取状况, 但是也会造成一些干扰

Chrome 浏览器从 60 版本开始,就已经开启了对无头模式的支持, 即 Headless 。 无头模式下,在网站运行的时候不会弹出窗口, 从而减少了干扰, 同时还减少了一些资源(如图片)的加载,所以无头模式在一定程度上节省了资源加载的时间和网络带宽

from selenium import webdriver
from selenium.webdriver import ChromeOptions

options = ChromeOptions()
options.add_argument('--headless')
browser = webdriver.Chrome()
browser.set_window_size(1366, 768)
browser.get('https://www.baidu.com')
browser.get_screenshot_as_file('preview.png')

这里利用 ChromeOptions  对象的 add_argument 方法添加了一个参数 --headless , 从而开启了无头模式,在无头模式下, 最好设置一下窗口大小, 因此这里调用了 set_window_size 方法, 之后打开页面, 并调用 get_screenshot_as_file 方法输出了页面截图

 

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

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

相关文章

WEB攻防-通用漏洞-SQL 读写注入-MYSQLMSSQLPostgreSQL

什么是高权限注入 高权限注入指的是攻击者通过SQL注入漏洞&#xff0c;利用具有高级权限的数据库账户&#xff08;如MYSQL的root用户、MSSQL的sa用户、PostgreSQL的dba用户&#xff09;执行恶意SQL语句。这些高级权限账户能够访问和修改数据库中的所有数据&#xff0c;甚至执行…

WEB集群-Tomact集群

linux云计算中小企业规模集群架构设计图----总结 在写今天内容前&#xff0c;小编绘制一个图&#xff1a;我设计了linux云计算中小企业规模集群架构设计图&#xff08;也可根据业务需求&#xff0c;增加业务变成大型企业架构设计图&#xff09; 知识补充–故障案例-https no s…

【Golang 面试基础题】每日 5 题(十)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

Python爬虫(6) --深层爬取

深层爬取 在前面几篇的内容中&#xff0c;我们都是爬取网页表面的信息&#xff0c;这次我们通过表层内容&#xff0c;深度爬取内部数据。 接着按照之前的步骤&#xff0c;我们先访问表层页面&#xff1a; 指定url发送请求获取你想要的数据数据解析 我们试着将以下豆瓣读书页…

WPF代办事项应用

目录 一 设计原型 二 后台源码 一 设计原型 添加代办事项页面&#xff1a; 二 后台源码 Model&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 待办事项应用.DataModel {pub…

数据结构(Java):Map集合Set集合哈希表

目录 1、介绍 1.1 Map和Set 1.2 模型 2、Map集合 2.1 Map集合说明 2.2 Map.Entry<K&#xff0c;V> 2.3 Map常用方法 2.4 Map注意事项及实现类 3、Set集合 3.1 Set集合说明 3.2 Set常用方法 3.3 Set注意事项及其实现类 4、TreeMap&TreeSet 4.1 集合类TreeM…

头歌最小生成树 ------习题

一、背包问题 1.理解&#xff1a;背包问题相当于最小生成树&#xff0c;也就是线性规划最优解 2.公式&#xff1a; M: 背包的总重量 w&#xff1a;物品 i 的重量 p: 物品 i 的价值 3.基本背包练习 4.完全背包问题&#xff1a;每种物品有无限件 >>> 开头加一个for…

面试常考Linux指令

文件权限 操作系统中每个文件都拥有特定的权限、所属用户和所属组。权限是操作系统用来限制资源访问的机制&#xff0c;在 Linux 中权限一般分为读(readable)、写(writable)和执行(executable)&#xff0c;分为三组。分别对应文件的属主(owner)&#xff0c;属组(group)和其他用…

SearchGPT 搜索引擎发布:让信息检索变得简单

如今的互联网时代&#xff0c;我们每天都在与海量数据搏斗。无论是学习、工作还是生活&#xff0c;我们都需要快速准确地获取所需信息。然而&#xff0c;传统搜索引擎往往让人感到力不从心&#xff1a;关键词需要精准&#xff0c;结果泛滥成灾&#xff0c;有用信息如大海捞针。…

如何快速抓取小红书帖子评论?两大实战Python技巧揭秘

摘要&#xff1a; 本文将深入探讨两种高效的Python方法&#xff0c;助您迅速获取小红书文章下方的所有评论&#xff0c;提升市场分析与用户洞察力。通过实战示例与详细解析&#xff0c;让您轻松掌握数据抓取技巧&#xff0c;为您的内容营销策略提供有力支持。 如何快速抓取小…

Linxu系统:hwclock命令

1、命令详解&#xff1a; hwclock命令用于显示与设定硬件时钟。它是一种访问硬件时钟的工具&#xff0c;可以显示当前时间&#xff0c;将硬件时钟设置为指定的时间&#xff0c;将硬件时钟设置为系统时间&#xff0c;以及从硬件时钟设置系统时间。您还可以定期运行hwlock以插入或…

raise JSONDecodeError(“Expecting value”, s, err.value) from None

raise JSONDecodeError(“Expecting value”, s, err.value) from None 目录 raise JSONDecodeError(“Expecting value”, s, err.value) from None 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是…

AI在企业招聘中的应用现状调研报告

2023年&#xff0c;ChatGPT一夜走红&#xff0c;个体陷入了被AI轻易替代的恐慌之中&#xff0c;而企业似乎找到了增长的又一踏板&#xff0c;或被搁置很久或在缓慢开展的「AI」行动又被各行各业提上了日程。 拥抱AI&#xff0c;企业动起来了吗? 从当前的数据来看&#xff0c…

tinygrad框架简介;MLX框架简介

目录 tinygrad框架简介 MLX框架简介 LLaMA​编辑 Stable Diffusion​编辑 tinygrad框架简介 极简主义与易扩展性 tinygrad 的设计理念是极简主义。与 XLA 类比,如果 XLA 是复杂指令集计算 (CISC),那么 tinygrad 就是精简指令集计算 (RISC)。这种简约的设计使得它成为添加…

攻坚克难岁月长,自主腾飞世界强——回顾近代中国数据库的发展与飞跃

前言 最近看了《中国数据库前世今生》纪录片&#xff0c;感触颇深&#xff0c;也是一直在思考到底该用何种方式起笔来回顾这段筚路蓝缕却又充满民族自豪感的历程。大概构思了一周左右吧&#xff0c;我想&#xff0c;或许还是应该从那个计算机技术在国内刚刚萌芽的年代开始讲起…

python+barcode快速生成条形码3-PyQt6微界面(电商条形码生成工具)

背景 继续上一片文章的电商测试小工具&#xff0c;进行了优化 需求 生成条形码之后&#xff0c;可以通过界面方式读取条形码的图片 支持当个条形码快速生成&#xff0c;以及批量导入 csv文件导入 添加微界面图像按钮&#xff0c;方便操作&#xff0c;更像是在实现测试工具的…

开放式耳机会成为未来的主流吗?开放式耳机推荐指南

开放式耳机是否会成为未来的主流&#xff0c;是一个值得探讨的问题。 从目前的市场趋势和技术发展来看&#xff0c;有一些因素支持开放式耳机可能成为主流。 一方面&#xff0c;人们对于健康和舒适的关注度不断提高。长时间佩戴传统耳机可能导致耳部不适&#xff0c;而开放式…

Internet Download Manager2024免费流行的下载加速器

1. Internet Download Manager&#xff08;IDM&#xff09;是一款流行的下载加速器&#xff0c;多线程下载使速度更快。 2. 用户界面友好&#xff0c;易于操作&#xff0c;支持多种浏览器集成和自动捕获下载。 3. 恢复中断的下载&#xff0c;动态文件分割技术提高效率。 4. 定…

解决CORS问题的技术点的原理总结

序言-引出问题 本人在毕业之后主要是从事游戏开发的客户端相关工作&#xff0c;由于游戏引擎的跨平台功能&#xff0c;所以在游戏开发完成之后&#xff0c;需要发布的平台经常会包含Web平台&#xff08;包括desktop Web、Mobile Web&#xff09;。 打包出来的项目文件的入口都…

《书生大模型实战营第3期》入门岛 学习笔记与作业:Python 基础知识

文章大纲 Python 简介1 安装Python1.1 什么是conda&#xff1f;1.1.1 功能与作用&#xff1a;1.1.2 常用命令&#xff1a;1.1.3 适用性&#xff1a; 1.2 Python安装与学习环境准备1.2.1 下载miniconda1.2.2 安装miniconda1.2.3 创建一个python练习专属的conda虚拟环境 2: Pytho…