当前位置: 首页 > news >正文

python网络爬虫(二)基本库的使用urllib/requests

使用urllib

了解一下 urllib 库,它是 Python 内置的 HTTP 请求库,也就是说不需要额外安装即可使用。它包含如下 4 个模块。

  • request:它是最基本的 HTTP 请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入 URL 以及额外的参数,就可以模拟实现这个过程了。

  • error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。

  • parse:一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、合并等。

  • robotparser:主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少。

发送请求

  • urlopen:

response = urllib.request.urlopen(‘https://www.python.org’)

可选参数:
data 参数如果要添加该参数,需要使用 bytes 方法将参数转化为字节流编码格式的内容,即 bytes 类型。另外,如果传递了这个参数,则它的请求方式就不再是 GET 方式,而是 POST 方式。

timeout 参数timeout 参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持 HTTP、HTTPS、FTP 请求。

  • Request:

request = urllib.request.Request(‘https://python.org’)

response = urllib.request.urlopen(request)

参数:

url 用于请求 URL,这是必传参数,其他都是可选参数

data 如果要传,必须传 bytes(字节流)类型的。

headers 是一个字典,它就是请求头

unverifiable 表示这个请求是否是无法验证的,默认是 False,意思就是说用户没有足够权限来选择接收这个请求的结果

method 是一个字符串,用来指示请求使用的方法

各种 Handler 子类继承这个 BaseHandler 类,举例如下。

  • HTTPDefaultErrorHandler 用于处理 HTTP 响应错误,错误都会抛出 HTTPError 类型的异常。

  • HTTPRedirectHandler 用于处理重定向。

  • HTTPCookieProcessor 用于处理 Cookies。

  • ProxyHandler 用于设置代理,默认代理为空。

  • HTTPPasswordMgr 用于管理密码,它维护了用户名密码的表。

  • HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。

处理异常

  • URLError:

URLError 类来自 urllib 库的 error 模块,它继承自 OSError 类,是 error 异常模块的基类,由 request 模块产生的异常都可以通过捕获这个类来处理。

它具有一个属性 reason,即返回错误的原因。

  • HTTPError:

它是 URLError 的子类,专门用来处理 HTTP 请求错误,比如认证请求失败等。它有如下 3 个属性。

  • code:返回 HTTP 状态码,比如 404 表示网页不存在,500 表示服务器内部错误等。

  • reason:同父类一样,用于返回错误的原因。

  • headers:返回请求头。

解析链接

  • urlparse:实现 URL 的识别和分段

  • urlunparse:将分段合并为url

  • urlsplit:这个方法和 urlparse 方法非常相似,只不过它不再单独解析 params 这一部分,只返回 5 个结果

  • urlunsplit:与 urlunparse 方法类似,它也是将链接各个部分组合成完整链接的方法,传入的参数也是一个可迭代对象,例如列表、元组等,唯一的区别是长度必须为 5

  • urljoin:我们可以提供一个 base_url(基础链接)作为第一个参数,将新的链接作为第二个参数

  • urlencode:为了更加方便地构造参数,我们会事先用字典来表示。要转化为 URL 的参数时,只需要调用该方法即可。

  • parse_qs:有一串 GET 请求参数,利用 parse_qs 方法,就可以将它转回字典

  • parse_qsl:用于将参数转化为元组组成的列表

  • unquote:进行 URL 解码

  • quote:该方法可以将内容转化为 URL 编码的格式。URL 中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将中文字符转化为 URL 编码

使用requests

抓取网页

import requests
import reheaders = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
r = requests.get("https://www.zhihu.com/explore", headers=headers)
pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S)
titles = re.findall(pattern, r.text)
print(titles)

目前可以使用的’User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36’

对于网页的内容这里使用正则表达式进行匹配

抓取二进制数据

图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制码。

以 GitHub 的站点图标为例来看一下:

import requestsr = requests.get("https://github.com/favicon.ico")
print(r.text)
print(r.content)

运行结果

在这里插入图片描述

可以注意到,前者出现了乱码,后者结果前带有一个 b,这代表是 bytes 类型的数据。由于图片是二进制数据,所以前者在打印时转化为 str 类型,也就是图片直接转化为字符串,这理所当然会出现乱码。

接着,我们将刚才提取到的图片保存下来:

r = requests.get("https://github.com/favicon.ico")
with open('favicon.ico', 'wb') as f:f.write(r.content)

同样地,音频和视频文件也可以用这种方法获取。

添加headers

与 urllib.request 一样,我们也可以通过 headers 参数来传递头信息。

POST请求

data = {'name': 'germey', 'age': '22'}
r = requests.post("http://httpbin.org/post", data=data)

响应

发送请求后,得到的自然就是响应。在上面的实例中,我们使用 text 和 content 获取了响应的内容。此外,还有很多属性和方法可以用来获取其他信息,比如状态码、响应头、Cookies 等

输出 status_code 属性得到状态码,输出 headers 属性得到响应头,输出 cookies 属性得到 Cookies,输出 url 属性得到 URL,输出 history 属性得到请求历史。

requests 还提供了一个内置的状态码查询对象 requests.codes

下面列出了返回码和相应的查询条件,方便编程时使用:

# 信息性状态码  
100: ('continue',),  
101: ('switching_protocols',),  
102: ('processing',),  
103: ('checkpoint',),  
122: ('uri_too_long', 'request_uri_too_long'),  # 成功状态码  
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),  
201: ('created',),  
202: ('accepted',),  
203: ('non_authoritative_info', 'non_authoritative_information'),  
204: ('no_content',),  
205: ('reset_content', 'reset'),  
206: ('partial_content', 'partial'),  
207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),  
208: ('already_reported',),  
226: ('im_used',),  # 重定向状态码  
300: ('multiple_choices',),  
301: ('moved_permanently', 'moved', '\\o-'),  
302: ('found',),  
303: ('see_other', 'other'),  
304: ('not_modified',),  
305: ('use_proxy',),  
306: ('switch_proxy',),  
307: ('temporary_redirect', 'temporary_moved', 'temporary'),  
308: ('permanent_redirect',  'resume_incomplete', 'resume',), # These 2 to be removed in 3.0  # 客户端错误状态码  
400: ('bad_request', 'bad'),  
401: ('unauthorized',),  
402: ('payment_required', 'payment'),  
403: ('forbidden',),  
404: ('not_found', '-o-'),  
405: ('method_not_allowed', 'not_allowed'),  
406: ('not_acceptable',),  
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),  
408: ('request_timeout', 'timeout'),  
409: ('conflict',),  
410: ('gone',),  
411: ('length_required',),  
412: ('precondition_failed', 'precondition'),  
413: ('request_entity_too_large',),  
414: ('request_uri_too_large',),  
415: ('unsupported_media_type', 'unsupported_media', 'media_type'),  
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),  
417: ('expectation_failed',),  
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),  
421: ('misdirected_request',),  
422: ('unprocessable_entity', 'unprocessable'),  
423: ('locked',),  
424: ('failed_dependency', 'dependency'),  
425: ('unordered_collection', 'unordered'),  
426: ('upgrade_required', 'upgrade'),  
428: ('precondition_required', 'precondition'),  
429: ('too_many_requests', 'too_many'),  
431: ('header_fields_too_large', 'fields_too_large'),  
444: ('no_response', 'none'),  
449: ('retry_with', 'retry'),  
450: ('blocked_by_windows_parental_controls', 'parental_controls'),  
451: ('unavailable_for_legal_reasons', 'legal_reasons'),  
499: ('client_closed_request',),  # 服务端错误状态码  
500: ('internal_server_error', 'server_error', '/o\\', '✗'),  
501: ('not_implemented',),  
502: ('bad_gateway',),  
503: ('service_unavailable', 'unavailable'),  
504: ('gateway_timeout',),  
505: ('http_version_not_supported', 'http_version'),  
506: ('variant_also_negotiates',),  
507: ('insufficient_storage',),  
509: ('bandwidth_limit_exceeded', 'bandwidth'),  
510: ('not_extended',),  
511: ('network_authentication_required', 'network_auth', 'network_authentication')

高级用法

再来了解下 requests 的一些高级用法,如文件上传、Cookies 设置、代理设置等

文件上传

假设上传刚才的图标文件

files = {'file': open('favicon.ico', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)

http://httpbin.org/post可用来进行文件上传的测试,会返回相应的数据

在这里插入图片描述

Cookies

获取 Cookies 的过程:

r = requests.get('https://www.baidu.com')
print(r.cookies)
for key, value in r.cookies.items():print(key + '=' + value)

首先调用 cookies 属性即可成功得到 Cookies,可以发现它是 RequestCookieJar 类型。然后用 items 方法将其转化为元组组成的列表,遍历输出每一个 Cookie 的名称和值,实现 Cookie 的遍历解析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将自己的cookie添加到请求头中,即可登陆自己的账号。

会话维持

在 requests 中,如果直接利用 get 或 post 等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。

第一个请求利用 post 方法登录了某个网站,第二次想获取成功登录后的自己的个人信息,你又用了一次 get 方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的会话,能成功获取个人信息吗?那当然不能。

Session 对象可以方便地维护一个会话,而且不用担心 cookies 的问题,它会帮我们自动处理好

requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')

这里我们请求了一个测试网址 http://httpbin.org/cookies/set/number/123456789。请求这个网址时,可以设置一个 cookie,名称叫作 number,内容是 123456789,随后又请求了 http://httpbin.org/cookies,此网址可以获取当前的 Cookies。

运行结果如下:

{“cookies”: {} }

并没有获取到cookie,Cookie 保存在客户端(浏览器),Session 保存在服务器端。

使用session:

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

运行结果:

{
“cookies”: {“number”: “123456789”}
}

SSL证书验证

requests 还提供了证书验证的功能。当发送 HTTP 请求的时候,它会检查 SSL 证书,我们可以使用 verify 参数控制是否检查此证书。其实如果不加 verify 参数的话,默认是 True,会自动验证。

如果请求一个 HTTPS 站点,但是证书验证错误的页面时,就会报SSL错误,将参数设置为False即可:

response = requests.get('https://www.12306.cn', verify=False)

代理设置

对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的 IP,导致一定时间段内无法访问。

那么,为了防止这种情况发生,我们需要设置代理来解决这个问题,这就需要用到 proxies 参数。可以用这样的方式设置:

import requestsproxies = {'http': 'http://10.10.1.10:3128','https': 'http://10.10.1.10:1080',
}requests.get('https://www.taobao.com', proxies=proxies)

超时设置

在本机网络状况不好或者服务器网络响应太慢甚至无响应时,我们可能会等待特别久的时间才可能收到响应,甚至到最后收不到响应而报错。使用timeout参数计算发出请求到服务器返回响应的时间。请求分为连接读取两个阶段,timeout为这两者的总和。

身份认证

在配置服务器设置或进入一些管理页面,如rabbitmq的管理页面,会需要我们进行身份验证,即输入用户名和密码才能进行配置。此时可以使用 requests 自带的身份认证功能,示例如下:

import requests  
from requests.auth import HTTPBasicAuth  r = requests.get('http://localhost:5000', auth=HTTPBasicAuth('username', 'password'))  
print(r.status_code)

requests 提供了一个更简单的写法,可以直接传一个元组,它会默认使用 HTTPBasicAuth 这个类来认证

r = requests.get('http://localhost:5000', auth=('username', 'password'))

Prepared Request

可以将请求表示为数据结构,其中各个参数都可以通过一个 Request 对象来表示

from requests import Request, Sessionurl = 'http://httpbin.org/post'
data = {'name': 'germey'}
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
}
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)

相关文章:

python网络爬虫(二)基本库的使用urllib/requests

使用urllib 了解一下 urllib 库&#xff0c;它是 Python 内置的 HTTP 请求库&#xff0c;也就是说不需要额外安装即可使用。它包含如下 4 个模块。 request&#xff1a;它是最基本的 HTTP 请求模块&#xff0c;可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样&…...

Kafka快速入门(最新版3.6.0)

文章目录 一、初识MQ1.1 什么是MQ1.2 同步和异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.3 技术对比1.4 MQ的两种模式 二、初识Kafka2.1 Kafka的使用场景2.2 Kafka基本概念2.3 Topic与Partition 三、Kafka基本使用3.1 部署前的准备3.2 启动kafka服务器3.3 Kafka核心概念之Topic3.4…...

CTF/AWD竞赛标准参考书+实战指南:《AWD特训营》

作者简介&#xff1a; 懒大王敲代码&#xff0c;正在学习嵌入式方向有关课程stm32&#xff0c;网络编程&#xff0c;数据结构C/C等 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 《AWD特训营》 前言 内容简介 读者对象 本书目录 前言…...

从零开始 Spring Cloud 15:多级缓存

从零开始 Spring Cloud 15&#xff1a;多级缓存 多级缓存架构 传统的缓存使用 Redis&#xff0c;大致架构如下&#xff1a; 这个架构存在一些问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈 Redis缓存失效时&#xff0c;会对数据库产生冲…...

Adobe产品2024

一、软件下载&#xff1a; 二、软件介绍&#xff1a; Adobe公司旗下的产品在影视后期、平面设计等领域有着无可取代的地位。在创意和设计领域中&#xff0c;产品有多达 21 个&#xff0c;包括 Photoshop、Illustrator、InDesign、Premiere Pro、After Effects 和 Acrobat Pro …...

【MySQL】8.0新特性、窗口函数和公用表表达式

文章目录 1. 新增特性2. 移除旧特性2.1 优点2.2 缺点 3. 新特性1&#xff1a;窗口函数3.1 使用窗口函数前后对比3.2 窗口函数分类3.3 语法结构3.4 分类讲解3.4.1 序号函数3.4.1.1 ROW_NUMBER()函数3.4.1.2 RANK()函数3.4.1.3 DENSE_RANK()函数 3.4.2 分布函数3.4.2.1 PERCENT_R…...

华为云云耀云服务器L实例评测|使用clickhouse-benchmark工具对ClickHouse的性能测试

目录 引言 1 ClickHouse简介 2 利用docker安装ClickHouse 2.1 安装Docker 2.2 下载ClickHouse Docker镜像 2.3 创建ClickHouse容器 2.4 访问ClickHouse 3 创建测试表 4 运行 clickhouse-benchmark 5 分析结果 结语 引言 利用华为云的云耀云服务器L实例&#xff0c…...

枚举最大值+ds:1887D

https://codeforces.com/problemset/problem/1887/D 左边区间最大值小于右边区间最小值 肯定要离线 感觉分治&#xff1f; 枚举左边区间最大值 求出其影响范围&#xff0c;推出左端点可取范围 然后可取右端点就是一段连续大于此值得区间 也就是左端点在一段区间时右端点可…...

模拟最终成绩计算过程

首先输入大于2的整数作为评委人数,然后依次输入每个评委的打分,要求每个分数介于0~100.输入完所有评委打分之后,去掉一个最高分,去掉一个最低分,剩余分数的平均分即为该选手的最终得分 (1) while True:try:n int(input(请输入评委人数:))assert n > 2# 跳出循环breakexce…...

Android10 修改开发者选项中动画缩放默认值

Android 10 修改开发者选项中动画因子默认值 开发者选项中有三个动画因子 “Window animation scale” :窗口动画缩放“Transition animation scale” :过渡动画缩放“Animator duration scale” :动画程序时长缩放 修改默然值 默认3个因子都是1.0&#xff0c;现在修改为默认0.…...

【2023年11月第四版教材】软考高项极限冲刺篇笔记(3)

8 成本管理 成本类型:可变成本、固定成本、直接成本、间接成本、机会成本、沉没成本 应急储备:成本基准内 管理成本:成本基准外 进度偏差:SV,SPI 成本管理主要是规划和控制 成本估算 类比估算 参数估算 自上而下估算 三点估算 备选方案分析 储备分析 质量成本 总资…...

c语言进阶部分详解(详细解析自定义类型——结构体,内存对齐,位段)

上篇文章介绍了一些常用的字符串函数&#xff0c;大家可以去我的主页进行浏览。 各种源码大家可以去我的github主页进行查找&#xff1a;Nerosts/just-a-try: 学习c语言的过程、真 (github.com) 今天要介绍的是&#xff1a;结构体的相关内容 目录 一.结构体类型的声明 1.…...

Mysql第三篇---响应太慢?数据库卡顿?如何优化?

Mysql第三篇—响应太慢&#xff1f;数据库卡顿&#xff1f;如何优化&#xff1f; 统计SQL的查询成本&#xff1a;last_query_cost 一条SQL查询语句在执行前需要确定查询执行计划&#xff0c;如果存在多种执行计划的话&#xff0c;MySQL会计算每个执行计划所需要的成本&#x…...

【计算机网络】HTTP 协议的基本格式以及 fiddler 的用法

HTTP协议的基本格式如下&#xff1a; 1.请求行&#xff1a; 包括请求THHP协议的版本、请求URI&#xff08;资源路径&#xff09;和HTTP方法&#xff08;如GET、POST、PUT、DELETE等&#xff09; GET/example.html HTTP/1.1 GET表示请求方法&#xff0c;/example.html表示请求的…...

人大金仓与哪吒科技达成战略合作,加快推动智慧港口建设

近日&#xff0c;人大金仓与哪吒港航智慧科技&#xff08;上海&#xff09;有限公司&#xff08;以下简称“哪吒科技”&#xff09;达成战略合作。双方旨在共享优势资源&#xff0c;联合为港口企业转型升级提供完备的技术支撑与行业解决方案。人大金仓总裁杜胜、哪吒科技总经理…...

FFmpeg工具使用集

FFmpeg工具使用集 About FFmpeg Java调用FFmpeg FFmpeg 工具&#xff1a; FFMPEG 用于转换多媒体文件的 命令行工具 格式之间&#xff08; ffmpeg\bin\ffmpeg.exe &#xff09; ffplay 基于 SDL 和 FFmpeg 库的简单媒体播放器 &#xff08; ffmpeg\bin\ffplay.exe &#xff0…...

2024级199管理类联考之英语二2200核心词汇(第一天)

define 下定义,定范围definition 定义,清晰度identify 鉴定,识别,确认identifiable 可识别的,可辨认的identity 身份,一致determine 决心,确定determinism 宿命论,决定论judge 判断,法官/裁判behavior 举止,表现behavioral 行为的conduct v-实施,引导,指挥; n-实施方式,行为,举…...

webGL编程指南 第三章 平移三角形 TranslatedTriangle.js

我会持续更新关于wegl的编程指南中的代码。 当前的代码不会使用书中的缩写&#xff0c;每一步都是会展开写。希望能给后来学习的一些帮助 git代码地址 接着 上一节 接着做平移的转化。在本次的案例案例中主要是xy的坐标变量相加&#xff0c;同时传递个给相关变量 <!DOCTY…...

推荐一款支持异步批量下载图片的chrome插件——图片助手(ImageAssistant) 批量图片下载器

https://chrome.google.com/webstore/detail/imageassistant-batch-imag/dbjbempljhcmhlfpfacalomonjpalpko/related?hlzh-CNhttps://chrome.google.com/webstore/detail/imageassistant-batch-imag/dbjbempljhcmhlfpfacalomonjpalpko/related?hlzh-CN 安装后直接点击 会根据…...

vue 动态数字效果 vue-animate-number

安装 vue-animate-number 插件 npm install vue-animate-number &#xff08;注&#xff1a;是npm、cnpm还是yarn根据具体项目要求&#xff09; 在 main.js 中引入 import Vue from vue import VueAnimateNumber from vue-animate-number Vue.use(VueAnimateNumber)动态使用…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...