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

IP伪装、代理池与分布式爬虫

一、动态代理IP应用:代理池的获取、选择与使用

代理池技术的核心是通过动态切换IP地址,让爬虫看起来像不同用户在访问网站,从而规避封禁。

(一)代理池的获取途径

1. 免费代理:低成本但高风险

免费代理可从公开网站(如西刺代理、快代理)获取,或通过API接口抓取。虽然免费,但存在诸多弊端:

  • 存活周期短:平均仅4-6小时

  • 可用率低:通常不足15%

  • 安全隐患:可能被监听流量

Python代码示例(抓取并验证免费代理)

import requests
from bs4 import BeautifulSoupdef get_free_proxies():url = "https://www.example-proxy-list.net/"  # 替换为有效URLtry:response = requests.get(url, timeout=10)if response.status_code == 200:soup = BeautifulSoup(response.text, 'html.parser')# 假设代理信息在表格的tbody中,每行有IP和端口两个tdproxy_rows = soup.select('tbody tr')proxies = []for row in proxy_rows:ip = row.select_one('td').textport = row.select_one('td + td').textproxies.append(f"{ip}:{port}")return proxieselse:print(f"获取免费代理失败,状态码:{response.status_code}")return []except Exception as e:print(f"获取免费代理时出错:{e}")return []

注意:由于网络原因,代码中的示例URL无法正常访问,请替换为有效的代理列表网站URL。

2. 付费代理:稳定性与定制化的选择

付费代理服务商(如神龙HTTP、ipipgo)提供高匿住宅IP,支持按需切换地理位置,响应速度快(0.3秒以内)。其核心优势在于:

  • 稳定性高:请求成功率比免费代理高78%

  • 定制化服务:可指定城市IP、切换频率等

付费代理使用示例

import requestsdef use_paid_proxy(url, proxy_ip, proxy_port, proxy_user, proxy_pass):proxies = {"http": f"http://{proxy_user}:{proxy_pass}@{proxy_ip}:{proxy_port}","https": f"http://{proxy_user}:{proxy_pass}@{proxy_ip}:{proxy_port}"}try:response = requests.get(url, proxies=proxies, timeout=10)return response.textexcept Exception as e:print(f"使用付费代理失败:{e}")return None

(二)代理池的选择标准

1. 匿名性验证:确保真实IP不暴露

通过访问httpbin.org/ip检查代理是否隐藏真实IP:

def check_anonymity(proxy):try:response = requests.get("https://httpbin.org/ip", proxies={"http": proxy, "https": proxy}, timeout=10)return response.json()["origin"] != "真实IP地址"except:return False
2. 稳定性监控:波动控制在15%以内
import timedef monitor_stability(proxy, test_url, duration=600):  # 默认监测10分钟response_times = []end_time = time.time() + durationwhile time.time() < end_time:try:start = time.time()requests.get(test_url, proxies={"http": proxy, "https": proxy}, timeout=10)response_times.append(time.time() - start)except:response_times.append(None)time.sleep(30)  # 每30秒测试一次valid_times = [t for t in response_times if t is not None]if len(valid_times) < len(response_times) * 0.8:return False  # 失败率超过20%则不稳定avg_time = sum(valid_times) / len(valid_times)variance = sum([(t - avg_time)**2 for t in valid_times]) / len(valid_times)return variance / avg_time**2 < 0.15  # 波动系数小于15%
3. 协议兼容性检测
def check_protocol_compatibility(proxy):http_test_url = "http://httpbin.org/get"https_test_url = "https://httpbin.org/get"try:requests.get(http_test_url, proxies={"http": proxy}, timeout=10)http_supported = Trueexcept:http_supported = Falsetry:requests.get(https_test_url, proxies={"https": proxy}, timeout=10)https_supported = Trueexcept:https_supported = Falsereturn http_supported and https_supported

(三)动态IP轮换方法

1. 随机选择策略
import randomclass SimpleProxyRotator:def __init__(self, proxies):self.proxies = proxiesself.blacklist = set()def get_proxy(self):available_proxies = [p for p in self.proxies if p not in self.blacklist]if not available_proxies:self.blacklist.clear()  # 清空黑名单,重新尝试所有代理available_proxies = self.proxies.copy()return random.choice(available_proxies)def block_proxy(self, proxy):self.blacklist.add(proxy)
2. 轮询选择策略
class RoundRobinProxyRotator:def __init__(self, proxies):self.proxies = proxiesself.current_index = 0self.blacklist = set()def get_proxy(self):available_proxies = [p for p in self.proxies if p not in self.blacklist]if not available_proxies:self.blacklist.clear()available_proxies = self.proxies.copy()proxy = available_proxies[self.current_index % len(available_proxies)]self.current_index += 1return proxydef block_proxy(self, proxy):self.blacklist.add(proxy)
3. 基于权重的选择策略
class WeightedProxyRotator:def __init__(self, proxies_with_weights):# proxies_with_weights格式为[{'proxy': 'ip:port', 'weight': 10}, ...]self.proxies = proxies_with_weightsself.total_weight = sum(p['weight'] for p in proxies_with_weights)self.blacklist = set()def get_proxy(self):available_proxies = [p for p in self.proxies if p['proxy'] not in self.blacklist]if not available_proxies:self.blacklist.clear()available_proxies = self.proxies.copy()# 计算累计权重cumulative_weights = []current_sum = 0for proxy in available_proxies:current_sum += proxy['weight']cumulative_weights.append(current_sum)# 随机选择rand = random.uniform(0, cumulative_weights[-1])selected_index = Nonefor i, weight in enumerate(cumulative_weights):if rand <= weight:selected_index = ibreakreturn available_proxies[selected_index]['proxy']def block_proxy(self, proxy):self.blacklist.add(proxy)def update_weight(self, proxy, new_weight):for p in self.proxies:if p['proxy'] == proxy:p['weight'] = new_weightself.total_weight = sum(p['weight'] for p in self.proxies)break

使用示例

proxies_with_weights = [{'proxy': '192.168.1.1:8080', 'weight': 10},{'proxy': '192.168.1.2:8080', 'weight': 5},{'proxy': '192.168.1.3:8080', 'weight': 8}
]rotator = WeightedProxyRotator(proxies_with_weights)for _ in range(5):proxy = rotator.get_proxy()print(f"使用代理:{proxy}")# 模拟请求# ...# 如果代理失败,则加入黑名单# rotator.block_proxy(proxy)# 或者调整权重# rotator.update_weight(proxy, new_weight=3)

二、分布式爬虫实践:Scrapy-Redis多节点协作

分布式爬虫通过多节点分散请求压力,结合代理池技术可有效提升抗封禁能力。

(一)Scrapy-Redis核心原理

1. 任务队列

Redis存储待抓取URL,所有节点共享同一队列,实现任务分发。

2. 去重机制

基于Redis Set存储URL指纹,避免重复抓取:

def url_to_fingerprint(url):return hashlib.sha256(url.encode('utf-8')).hexdigest()# Redis中存储指纹
redis_conn.sadd('seen_urls', url_to_fingerprint(url))
3. 动态调度

主节点分配任务,从节点并行执行,支持负载均衡:

class MasterScheduler:def __init__(self, redis_url):self.redis = redis.from_url(redis_url)def add_task(self, url):fingerprint = url_to_fingerprint(url)if self.redis.sismember('seen_urls', fingerprint):return False  # 已存在self.redis.rpush('task_queue', url)self.redis.sadd('seen_urls', fingerprint)return Truedef get_task(self):return self.redis.blpop('task_queue', timeout=30)class WorkerNode:def __init__(self, redis_url):self.redis = redis.from_url(redis_url)def fetch_task(self):task = self.redis.blpop('task_queue', timeout=30)if task:return task[1].decode('utf-8')return Nonedef mark_task_done(self, url):self.redis.sadd('completed_tasks', url)

(二)部署步骤

1. 环境配置

settings.py中添加:

# settings.py
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
REDIS_URL = 'redis://user:pass@master_ip:6379'
SCHEDULER_PERSIST = True  # 持久化任务队列
2. 爬虫代码示例
from scrapy_redis.spiders import RedisSpiderclass MyDistributedSpider(RedisSpider):name = 'my_distributed_crawler'redis_key = 'crawler:start_urls'  # Redis中存储任务的键def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.proxy_rotator = SimpleProxyRotator(available_proxies)def parse(self, response):# 解析逻辑yield {'data': response.text}# 提取下一页链接next_page = response.css('a.next-page::attr(href)').get()if next_page:yield response.follow(next_page, self.parse, meta={'proxy': self.proxy_rotator.get_proxy()})

(三)实际应用案例:电商数据采集

1. 架构设计
  • 主节点:管理Redis队列

  • 从节点:部署50+爬虫实例,每个实例绑定独立代理池

2. 反爬策略
  • 动态UA池(200+真实浏览器标识)降低30%封禁率

    user_agents = ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",# 更多UA...
    ]class UserAgentMiddleware:def process_request(self, request, spider):request.headers['User-Agent'] = random.choice(user_agents)
  • 请求间隔随机化(0.5-5秒),模拟人工操作:

    class RandomDelayMiddleware:def __init__(self, min_delay, max_delay):self.min_delay = min_delayself.max_delay = max_delay@classmethoddef from_crawler(cls, crawler):return cls(min_delay=crawler.settings.get('RANDOM_DELAY_MIN', 0.5),max_delay=crawler.settings.get('RANDOM_DELAY_MAX', 5))def process_request(self, request, spider):delay = random.uniform(self.min_delay, self.max_delay)time.sleep(delay)
3. 实际效果
  • 日均采集10万页面

  • 封禁率低于2%

三、完整实践案例:搭建高效爬虫系统

(一)系统架构图

                            +-------------------+|  主节点(Redis)  |+--------+----------+|v
+----------+------------------+  +----------+------------------+
|          |                  |  |          |                  |
|  从节点1  |    从节点2        |  | 从节点50  |   从节点N         |
| (爬虫实例)|   (爬虫实例)       |  | (爬虫实例)|   (爬虫实例)       |
|          |                  |  |          |                  |
+----------+------------------+  +----------+------------------+

(二)核心代码整合

1. 代理管理模块
class ProxyManager:def __init__(self, free_proxy_urls=None, paid_proxy_urls=None):self.free_proxy_urls = free_proxy_urls or ["https://www.example-proxy-list.net/"]self.paid_proxy_urls = paid_proxy_urls or []self.proxies = []self.blacklist = set()self.last_refresh_time = 0self.refresh_interval = 30 * 60  # 30分钟刷新一次def _fetch_free_proxies(self):all_proxies = []for url in self.free_proxy_urls:try:response = requests.get(url, timeout=10)if response.status_code == 200:soup = BeautifulSoup(response.text, 'html.parser')proxy_rows = soup.select('tbody tr')for row in proxy_rows:ip = row.select_one('td').textport = row.select_one('td + td').textall_proxies.append(f"{ip}:{port}")except:continuereturn all_proxiesdef _fetch_paid_proxies(self):paid_proxies = []for proxy_info in self.paid_proxy_urls:# 假设paid_proxy_urls是包含IP、端口、用户名、密码的字典列表proxy_str = f"{proxy_info['user']}:{proxy_info['pass']}@{proxy_info['ip']}:{proxy_info['port']}"paid_proxies.append(f"http://{proxy_str}")return paid_proxiesdef refresh_proxies(self):if time.time() - self.last_refresh_time < self.refresh_interval and self.proxies:returnself.proxies = []self.proxies.extend(self._fetch_free_proxies())self.proxies.extend(self._fetch_paid_proxies())# 验证代理有效性并过滤validated_proxies = []for proxy in self.proxies:if self._validate_proxy(proxy):validated_proxies.append(proxy)self.proxies = validated_proxiesself.last_refresh_time = time.time()def _validate_proxy(self, proxy):try:# 检查HTTP支持response = requests.get("http://httpbin.org/ip", proxies={"http": proxy}, timeout=10)if response.status_code != 200:return False# 检查HTTPS支持response = requests.get("https://httpbin.org/ip", proxies={"https": proxy}, timeout=10)if response.status_code != 200:return False# 检查匿名性if response.json().get("origin") == "真实IP地址":return Falsereturn Trueexcept:return Falsedef get_proxy(self):if not self.proxies:self.refresh_proxies()available_proxies = [p for p in self.proxies if p not in self.blacklist]if not available_proxies:self.blacklist.clear()available_proxies = self.proxies.copy()return random.choice(available_proxies) if available_proxies else Nonedef block_proxy(self, proxy):self.blacklist.add(proxy)
2. 爬虫模块(基于Scrapy-Redis)
from scrapy_redis.spiders import RedisSpider
from myproject.items import MyItem
from myproject.middlewares import ProxyManagerclass MyDistributedSpider(RedisSpider):name = 'my_distributed_crawler'redis_key = 'crawler:start_urls'custom_settings = {'REDIS_URL': 'redis://user:pass@master_ip:6379','SCHEDULER_PERSIST': True,'DOWNLOAD_DELAY': 0,  # 由中间件控制延迟'DOWNLOADER_MIDDLEWARES': {'myproject.middlewares.RandomDelayMiddleware': 543,'myproject.middlewares.ProxyMiddleware': 750,'myproject.middlewares.UserAgentMiddleware': 500,}}def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.proxy_manager = ProxyManager()def parse(self, response):# 提取数据item = MyItem()item['title'] = response.css('h1::text').get()item['content'] = response.css('div.content::text').get()yield item# 提取下一页链接next_page = response.css('a.next-page::attr(href)').get()if next_page:yield response.follow(next_page, self.parse)
3. 中间件模块
import random
import time
import requests
from scrapy import signals
from scrapy.downloadermiddlewares.retry import RetryMiddleware
from scrapy.exceptions import NotConfiguredclass RandomDelayMiddleware:def __init__(self, min_delay, max_delay):self.min_delay = min_delayself.max_delay = max_delay@classmethoddef from_crawler(cls, crawler):settings = crawler.settingsmin_delay = settings.getfloat('RANDOM_DELAY_MIN', 0.5)max_delay = settings.getfloat('RANDOM_DELAY_MAX', 5)if min_delay >= max_delay:raise NotConfigured("RANDOM_DELAY_MIN should be less than RANDOM_DELAY_MAX")return cls(min_delay, max_delay)def process_request(self, request, spider):delay = random.uniform(self.min_delay, self.max_delay)time.sleep(delay)class ProxyMiddleware:def __init__(self):self.proxy_manager = ProxyManager()def process_request(self, request, spider):proxy = self.proxy_manager.get_proxy()if proxy:request.meta['proxy'] = proxyelse:spider.logger.warning("No valid proxies available")def process_exception(self, request, exception, spider):if 'proxy' in request.meta:self.proxy_manager.block_proxy(request.meta['proxy'])spider.logger.info(f"Blocked proxy: {request.meta['proxy']}")# 重新调度请求return request.copy()class UserAgentMiddleware:def __init__(self):self.user_agents = ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",# 更多UA...]def process_request(self, request, spider):request.headers['User-Agent'] = random.choice(self.user_agents)class RetryProxyMiddleware(RetryMiddleware):def process_exception(self, request, exception, spider):if 'proxy' in request.meta:proxy = request.meta['proxy']spider.logger.info(f"Retrying via proxy {proxy}: caught exception {exception}")self.proxy_manager.block_proxy(proxy)retryreq = request.copy()retryreq.dont_filter = Trueretryreq.priority = request.priority + self.priority_adjustreturn retryreq

(三)部署与运行

1. 环境准备

确保所有节点安装以下组件:

pip install scrapy scrapy-redis redis pymongo requests beautifulsoup4
2. 主节点启动
# 启动Redis服务器
redis-server# 向Redis添加初始任务
python add_initial_tasks.py
3. 从节点启动
# 在每个从节点上运行
scrapy crawl my_distributed_crawler
4. 监控与维护
  • 定期检查代理池状态

  • 监控爬虫日志,分析被封禁原因

  • 根据网站反爬策略调整请求频率和UA池

四、常见问题与解决方案

(一)代理频繁失效

  • 原因:免费代理质量不稳定,或目标网站加强了反爬措施

  • 解决方案

    1. 缩短代理刷新间隔

    proxy_manager = ProxyManager(refresh_interval=15 * 60)  # 15分钟刷新一次
    1. 增加付费代理比例

    2. 实现代理健康检查

    def check_proxy_health(proxy):try:response = requests.get("http://httpbin.org/ip", proxies={"http": proxy}, timeout=5)return response.status_code == 200except:return False

(二)数据重复采集

  • 原因:Redis去重机制失效,或爬虫逻辑存在漏洞

  • 解决方案

    1. 确保URL指纹计算正确

    def url_to_fingerprint(url):return hashlib.sha256(url.encode('utf-8')).hexdigest()
    1. 在爬虫中添加本地去重

    class MySpider(scrapy.Spider):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.seen_urls = set()def parse(self, response):if response.url in self.seen_urls:returnself.seen_urls.add(response.url)# 正常解析逻辑...

(三)爬虫速度过慢

  • 原因:代理速度慢、请求间隔过大或节点资源不足

  • 解决方案

    1. 优化代理选择策略,优先使用高速代理

    class WeightedProxyRotator:# 优先选择权重高的代理def get_fast_proxy(self):weights = [p['weight'] for p in self.proxies]total = sum(weights)rand = random.uniform(0, total)current = 0for proxy in self.proxies:current += proxy['weight']if current >= rand:return proxy['proxy']return random.choice(self.proxies)['proxy']
    1. 动态调整请求间隔

    class AdaptiveDelayMiddleware:def __init__(self):self.delay = 1.0  # 初始延迟self.min_delay = 0.5self.max_delay = 5.0self.success_count = 0def process_response(self, request, response, spider):if response.status == 200:self.success_count += 1if self.success_count >= 5:  # 连续5次成功减少延迟self.delay = max(self.min_delay, self.delay * 0.8)self.success_count = 0else:self.success_count = 0self.delay = min(self.max_delay, self.delay * 1.5)return responsedef process_request(self, request, spider):time.sleep(self.delay)
    1. 增加从节点数量,提高并发能力

五、进阶优化技巧

(一)代理自动切换与故障恢复

class SmartProxyMiddleware:def __init__(self):self.proxy_manager = ProxyManager()self.retry_times = {}def process_request(self, request, spider):if 'proxy' in request.meta:current_proxy = request.meta['proxy']if self.proxy_manager.is_proxy_available(current_proxy):return None  # 继续使用当前代理else:# 切换代理new_proxy = self.proxy_manager.get_proxy()request.meta['proxy'] = new_proxyspider.logger.info(f"Switched proxy from {current_proxy} to {new_proxy}")else:# 初始请求分配代理new_proxy = self.proxy_manager.get_proxy()request.meta['proxy'] = new_proxyreturn Nonedef process_exception(self, request, exception, spider):proxy = request.meta.get('proxy')if proxy:self.proxy_manager.block_proxy(proxy)spider.logger.warning(f"Proxy {proxy} failed, exception: {exception}")# 重试请求retry_request = request.copy()retry_request.dont_filter = Trueretry_request.priority = request.priority + 1# 更新重试次数self.retry_times[retry_request.url] = self.retry_times.get(retry_request.url, 0) + 1# 最多重试3次if self.retry_times[retry_request.url] <= 3:return retry_requestelse:spider.logger.warning(f"Abandoning {retry_request.url} after 3 failed attempts")return None

(二)基于行为分析的反爬规避

class BehaviorAntiCrawlMiddleware:def __init__(self):self.mouse_movements = []self.keyboard_events = []self.last_action_time = time.time()def simulate_mouse_movement(self):# 模拟鼠标随机移动x = random.randint(0, 1920)y = random.randint(0, 1080)self.mouse_movements.append((x, y, time.time()))# 保持鼠标轨迹自然if len(self.mouse_movements) > 10:self.mouse_movements.pop(0)def simulate_keyboard_event(self):# 模拟随机键盘事件keys = ['a', 'b', 'c', ' ', '\n', '\t']key = random.choice(keys)self.keyboard_events.append((key, time.time()))# 保持键盘事件记录合理if len(self.keyboard_events) > 20:self.keyboard_events.pop(0)def process_request(self, request, spider):# 模拟人类行为if random.random() < 0.3:  # 30%概率触发鼠标移动self.simulate_mouse_movement()if random.random() < 0.1:  # 10%概率触发键盘事件self.simulate_keyboard_event()# 添加行为数据到请求头(如果网站支持)behavior_data = {"mouse_movements": self.mouse_movements[-5:],  # 最近5次鼠标移动"keyboard_events": self.keyboard_events[-10:],  # 最近10次键盘事件"session_duration": time.time() - self.last_action_time}request.headers['X-Behavior-Data'] = json.dumps(behavior_data)self.last_action_time = time.time()return None

(三)分布式任务调度优化

class IntelligentScheduler:def __init__(self, redis_url):self.redis = redis.from_url(redis_url)self.node_heartbeats = {}self.task_priorities = {}def register_node(self, node_id):self.node_heartbeats[node_id] = time.time()self.redis.sadd('active_nodes', node_id)def update_node_heartbeat(self, node_id):self.node_heartbeats[node_id] = time.time()def distribute_task(self, task):# 根据节点活跃度和负载分配任务active_nodes = self.redis.smembers('active_nodes')if not active_nodes:return None# 计算节点权重(基于心跳和历史表现)node_weights = {}current_time = time.time()for node_id in active_nodes:node_id = node_id.decode('utf-8')heartbeat_age = current_time - self.node_heartbeats.get(node_id, 0)task_completion_rate = self.redis.get(f'node:{node_id}:completion_rate') or 0.8node_weights[node_id] = max(0.1, min(1.0, (60 - heartbeat_age)/60 * task_completion_rate))# 选择权重最高的节点selected_node = max(node_weights.items(), key=lambda x: x[1])[0]# 发送任务到选中的节点self.redis.rpush(f'node:{selected_node}:task_queue', task)return selected_nodedef monitor_tasks(self):# 定期检查任务状态pending_tasks = self.redis.llen('pending_tasks')completed_tasks = self.redis.llen('completed_tasks')error_tasks = self.redis.llen('error_tasks')# 计算任务成功率total_tasks = pending_tasks + completed_tasks + error_tasksif total_tasks > 0:success_rate = completed_tasks / total_tasksself.redis.set('scheduler:success_rate', success_rate)# 检测并恢复卡住的任务stuck_tasks = self.redis.zrange('stuck_tasks', 0, -1)for task_id in stuck_tasks:task_id = task_id.decode('utf-8')task_info = self.redis.hgetall(f'task:{task_id}')if task_info:self.redis.rpush('pending_tasks', task_id)self.redis.zrem('stuck_tasks', task_id)

通过以上详细指南和示例代码,您可以构建一个高效、稳定的分布式爬虫系统,有效应对各类反爬措施。

相关文章:

IP伪装、代理池与分布式爬虫

一、动态代理IP应用&#xff1a;代理池的获取、选择与使用 代理池技术的核心是通过动态切换IP地址&#xff0c;让爬虫看起来像不同用户在访问网站&#xff0c;从而规避封禁。 &#xff08;一&#xff09;代理池的获取途径 1. 免费代理&#xff1a;低成本但高风险 免费代理可…...

【Arthas】火焰图优化应用CPU(问题原因:获取调用栈)

优化场景总结归纳 1. 问题背景 现象&#xff1a;在公共搜索功能中&#xff0c;火焰图分析发现 获取Java调用栈&#xff08;StackTrace&#xff09; 占用了约 6%的CPU&#xff08;日常流量下&#xff09;&#xff0c;系统高负载时占比更高。原因&#xff1a; 每次外部API调用时…...

回溯算法详解(Java实现):从组合到排列的全面解析

引言 回溯算法是一种强大的算法思想&#xff0c;广泛应用于解决各种组合优化问题。它通过系统性地尝试所有可能的解&#xff0c;并在发现当前路径无法得到解时立即回溯&#xff0c;从而高效地找到问题的解。在本文中&#xff0c;我们将深入探讨回溯算法的核心思想、三要素、通…...

【BLE】【nRF Connect】 精讲nRF Connect自动化测试套件(宏录制、XML脚本)

目录 前言 1. nRF Connect自动化测试介绍 1.1. nRF connect宏录制功能介绍 1.2. 电脑端XML方式 1.3 实际应用案例 1.3.1 BLE 稳定性测试 1.3.2 设备固件更新(DFU)测试 1.3.3 批量设备配置 1.4 操作步骤 1.5 注意事项 2. nRF Connect日志记录 2.1. 日志记录功能 …...

springboot war包tomcat中运行报错,启动过滤器异常,一个或多个筛选器启动失败。

错误信息&#xff1a; "level": "ERROR", "thread": "localhost-startStop-1", "class": "o.a.c.c.C.[.[localhost].[/Crmeb-admin]", …...

基于开源AI大模型与AI智能名片S2B2C商城小程序的线上活动执行优化研究

摘要&#xff1a;本文以开源AI大模型、AI智能名片及S2B2C商城小程序为技术载体&#xff0c;探讨线上活动执行阶段的效能提升路径。通过分析某科技展会案例&#xff0c;发现AI智能名片可将参会者信息采集效率提升60%&#xff0c;S2B2C商城小程序的21链动模式使活动裂变传播速度提…...

解决奥壹oelove婚恋原生小程序上架问题,彻底解决解对问题增强版旗舰版通用

现在很多客户还不了解OElove小程序上架流程&#xff01;因为很多用户对技术无感&#xff01;随意上架工作都是要靠官方来辅助&#xff01;这样在在二开性就会失去很多主动权&#xff01;本人商业用户有全新原生态小程序源码&#xff08;注意&#xff1a;这是原生非Uniapp&#…...

Java SE(7)——类和对象(二)

1.包(package) 1.1 包的定义 在Java中&#xff0c;包是一种用于组织和管理类&#xff0c;接口和其他包的机制。主要作用是防止命名冲突&#xff0c;并提供一种访问控制机制 1.2 package关键字 package关键字的主要作用是声明当前类在哪个包里面。 当然&#xff0c;用户也可以…...

Python 装饰器优化策略模式:电商促销折扣的优雅解法

问题背景&#xff1a;促销策略的重复陷阱 在电商促销系统中&#xff0c;我们曾面临这样的痛点&#xff1a; promos [fidelity_promo, bulk_item_promo, large_order_promo] # 6.1节原始方案 def best_promo(order):return max(promo(order) for promo in promos)当新增new…...

redis延时队列详细介绍

Redis延时队列是一种利用Redis数据结构的功能来实现延时任务调度的方法。在Redis中&#xff0c;常用的数据结构包括List&#xff08;列表&#xff09;和Sorted Set&#xff08;有序集合&#xff09;。延时队列通常是通过有序集合来实现的。 具体实现步骤如下&#xff1a; 将延…...

PHP 开发工程师如何借助 DeepSeek 提升工作效率

在当今数字化时代&#xff0c;PHP 开发工程师面临着不断提高工作效率和应对复杂项目需求的挑战。DeepSeek 作为一款先进的人工智能工具&#xff0c;为 PHP 开发工程师提供了一系列强大的功能&#xff0c;能够显著助力其日常工作。从代码生成与优化&#xff0c;到文档撰写和知识…...

Vibe Coding 新时代:AI 辅助编程完全指南

第一章:什么是 Vibe Coding?AI 编程的新范式 在传统编程的世界里,程序员需要掌握语法、算法和框架,一行一行地编写代码。但随着人工智能的快速发展,一种全新的编程方式正在兴起——这就是 Vibe Coding(氛围编程)。 Vibe Coding 的定义 Vibe Coding 是由 AI 研究者 An…...

Oracle RAC ‘Metrics Global Cache Blocks Lost‘告警解决处理

1. 引言&#xff1a; 前段时间鄙人检查处理过Oracle RAC Metrics Global Cache Blocks Lost’告警&#xff0c;在此总结分享下针对该报警的原因分析及处理办法。 2. 具体事件 通过排查发现造成该告警的原因是共享存储控制器损坏导致的。由于发生已经有段时间了&#xff0c;没…...

Go语言入门基础:协程

第21章 协程 目录 21.1 启动Go协程 协程的概念与特点启动协程的方法及示例协程执行顺序的控制 21.2 通道 通道类型及表示方式21.2.1 实例化通道21.2.2 数据缓冲21.2.3 单向通道21.2.4 通道与select语句 21.3 互斥锁 协程并发访问的逻辑问题互斥锁的使用示例 21.4 WaitGroup类…...

Servlet+tomcat

serverlet 定义&#xff1a;是一个接口&#xff0c;定义了java类被浏览器&#xff08;tomcat识别&#xff09;的规则 所以我们需要自定义一个类&#xff0c;实现severlet接口复写方法 通过配置类实现路径和servlet的对应关系 执行原理 当用户在浏览器输入路径&#xff0c;会…...

中间件和组件

文章目录 1. 前言2. 中间件介绍3. 组件介绍4. 区别对比5. 简单类比6. 总结 中间件和组件 1. 前言 中间件和组件是软件开发中两个重要的概念&#xff0c;但它们的定位和作用完全不同。中间件解决的事通信、跨系统、安全等问题&#xff0c;组件是解决具体业务模块&#xff0c;提高…...

piccolo-large-zh-v2 和 bge-m3哪个效果好?

环境&#xff1a; piccolo-large-zh-v2 bge-m3 问题描述&#xff1a; piccolo-large-zh-v2 和 bge-m3哪个效果好&#xff1f; 解决方案&#xff1a; 比较Piccolo-large-zh-v2&#xff08;商汤&#xff09;与BGE-M3&#xff08;智源&#xff09;的效果时&#xff0c;需结合…...

《告别试错式开发:TDD的精准质量锻造术》

深度解锁TDD&#xff1a;应用开发的创新密钥 在应用开发的复杂版图中&#xff0c;如何雕琢出高质量、高可靠性的应用&#xff0c;始终是开发者们不懈探索的核心命题。测试驱动开发&#xff08;TDD&#xff09;&#xff0c;作为一种颠覆性的开发理念与方法&#xff0c;正逐渐成…...

哈希函数详解(SHA-2系列、SHA-3系列、SM3国密)案例:构建简单的区块链——密码学基础

文章目录 一、密码哈希函数概述1.1 哈希函数的基本概念1.2 哈希函数在数据安全中的应用 二、SHA-2系列算法详解2.1 SHA-2的起源与发展2.2 SHA-256技术细节与实现2.3 SHA-384和SHA-512的特点2.4 SHA-2系列算法的安全性评估 三、SHA-3系列算法详解3.1 SHA-3的起源与设计理念3.2 K…...

CUDA输出“hello world”

在我们学习任何一门编程语言的时候, 无疑当我们真正用其输出“hello world”的时候, 我们已经成功入门, 接下来要做的就是从入门到放弃了&#x1f606; 接下来我们通过对比C和CUDA来学习CUDA的运行逻辑: C中的hello worldCUDA中的hello world文本编辑器编写源代码, 比如vscod…...

计算机视觉与深度学习 | 视觉里程计算法综述(传统+深度)

视觉里程计算法综述 1. 算法分类与原理1.1 传统几何方法1.2 深度学习方法2. 关键公式与模型2.1 本征矩阵分解2.2 深度学习模型架构3. 代码实现与开源项目3.1 传统方法实现3.2 深度学习方法实现4. 挑战与未来方向总结传统视觉里程计算法综述1. 算法分类与核心原理1.1 特征点法1.…...

c++ 函数参数传递

C 中的值传递和地址传递 在 C 中&#xff0c;函数参数传递主要有两种方式&#xff1a;值传递和地址传递&#xff08;指针传递和引用传递都属于地址传递的变体&#xff09;。 1. 值传递 特点 函数接收的是实参的副本对形参的修改不会影响原始变量适用于小型数据&#xff08;…...

计算机视觉与深度学习 | 什么是图像金字塔?

图像金字塔详解 图像金字塔 图像金字塔详解1. **定义**2. **原理与公式****2.1 高斯金字塔****2.2 拉普拉斯金字塔**3. **代码示例****3.1 使用OpenCV实现****3.2 手动实现高斯模糊与降采样**4. **应用场景**5. **关键点总结**1. 定义 图像金字塔是一种多尺度图像表示方法,将…...

AI超级智能体教程(五)---自定义advisor扩展+结构化json输出

文章目录 1.自定义拦截器1.2自定义Advisor1.2打断点调试过程1.3Re-reading Advisor自定义实现 2.恋爱报告开发--json结构化输出2.1原理介绍2.1代码实现2.3编写测试用例2.4结构化输出效果 1.自定义拦截器 1.2自定义Advisor spring里面的这个默认的是SimpleloggerAdvisor&#…...

ActiveMQ 集群搭建与高可用方案设计(一)

一、引言 在当今分布式系统盛行的时代&#xff0c;消息中间件扮演着至关重要的角色&#xff0c;而 ActiveMQ 作为一款开源的、功能强大的消息中间件&#xff0c;在众多项目中得到了广泛应用。它支持多种消息传输协议&#xff0c;如 JMS、AMQP、MQTT 等 &#xff0c;能够方便地实…...

MySQL数据操作全攻略:DML增删改与DQL高级查询实战指南

知识点4【MySQL的DDL】 DDL&#xff1a;主要管理数据库、表、列等操作。 库→表&#xff08;二维&#xff09;→列&#xff08;一维&#xff09; 数据表的第一行是 列名称 数据库是由一张或多张表组成 我们先学习在数据库中创建数据表 0、常见的数据类型&#xff1a; 1、…...

RabbitMQ 中的六大工作模式介绍与使用

文章目录 简单队列&#xff08;Simple Queue&#xff09;模式配置类定义消费者定义发送消息测试消费 工作队列&#xff08;Work Queues&#xff09;模式配置类定义消费者定义发送消息测试消费负载均衡调优 发布/订阅&#xff08;Publish/Subscribe&#xff09;模式配置类定义消…...

一种基于重建前检测的实孔径雷达实时角超分辨方法——论文阅读

一种基于重建前检测的实孔径雷达实时角超分辨方法 1. 专利的研究目标与实际问题意义2. 专利提出的新方法、模型与公式2.1 重建前检测(DBR)与数据裁剪2.1.1 回波模型与检测准则2.1.2 数据裁剪效果2.2 数据自适应迭代更新2.2.1 代价函数与迭代公式2.2.2 矩阵递归更新2.3 正则化…...

代购平台如何“说本地话,穿本地衣”

当海外消费者点开一个代购商城&#xff0c;看到满屏机械翻译的中式文案&#xff0c;他们大概率会默默关闭页面。还有数据显示&#xff0c;不符合本地审美的页面设计会导致70%的潜在客户流失&#xff0c;而专业的本地化改造能让订单转化率提升3倍以上。 01 AI翻译&#xff1a;让…...

C++调试(叁):编译qBreakpad并使用其生成Dump文件

目录 1.前言 2.生成Dump文件的第三方库 3.第三方库下载链接 4.编译qBreakpad 5.VS中使用qBreakpad 6.qBreakpad测试程序 前言 在第二篇文章中&#xff0c;我主要讲解了如何使用SetUnhandledExceptionFilter函数设置程序的异常回调&#xff0c;在设置的回调函数中调用MiniDumpWr…...

0基础 | STM32 | TB6612电机驱动使用

TB6612介绍及使用 单片机通过驱动板连接至电机 原因&#xff1a;单品机I/O口输出电流I小 驱动板&#xff1a;从外部引入高电压&#xff0c;控制电机驱动 电源部分 VM&#xff1a;电机驱动电源输入&#xff0c;输入电压范围建议为3.7&#xff5e;12V GND&#xff1a;逻辑电…...

Cycleresearcher:通过自动化评审改进自动化研究

1、引言 迄今为止&#xff0c;整个科学发现过程自动化的挑战在很大程度上仍未解决&#xff0c;特别是在生成和改进符合同行评审工作高标准的研究成果方面。此外&#xff0c;很少有工作涉及迭代反馈的整合&#xff0c;这对保持学术的健全性和新奇至关重要。当前的模型往往难以适…...

深入理解Redis SDS:高性能字符串的终极设计指南

&#x1f4cd; 文章提示 10分钟掌握Redis核心字符串设计 | 从底层结构到源码实现&#xff0c;揭秘SDS如何解决C字符串七大缺陷&#xff0c;通过20手绘图示与可运行的C代码案例&#xff0c;助你彻底理解二进制安全、自动扩容等核心机制&#xff0c;文末附实战优化技巧&#xff…...

【tcp连接windows redis】

tcp连接windows redis 修改redis.conf 修改redis.conf bind * -::*表示禁用保护模式&#xff0c;允许外部网络连接 protected-mode no...

【AI平台】n8n入门6:调用MCP服务(非社区节点)

前言 前边用n8n搭建一个MCP服务&#xff0c;现在&#xff0c;用n8n调用其他服务商提供的MCP服务。本文以高德地图服务为例&#xff0c;记录一下操作过程。 实现案例功能 MCP是啥 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由Anthropi…...

C++负载均衡远程调用学习之 Dns-Route关系构建

目录 1.LARS-DNS-MYSQL环境搭建 2.LARSDNS-系统整体模块的简单说明 3.Lars-Dns-功能说明 4.Lars-Dns-数据表的创建 5.Lars-Dns-整体功能说明 6.Lars-DnsV0.1-Route类的单例实现 7.Lars-DnsV0.1-Route类的链接数据库方法实现 8.Lars-DnsV0.1-定义存放RouteData关系的map数…...

Linux53 百度网盘运行(下载devtoolset11后仍提示stdc++3.0.29缺失 计划用docker容器隔离运行,计划后续再看)

算了 放弃 都用到docker了 计划先看看系统服务后续再研究吧 百度网盘运行(下载devtoolset11后仍提示stdc3.0.29缺失 计划用docker容器隔离运行 但是由于系统服务未扎实&#xff0c;计划后续再看 重新下了el7的版本 刚才已启动成功 单输入xlock不启动 切换用户也不启动 …...

ASP.NET MVC​ 入门与提高指南八

45. 神经形态计算与 MVC 应用性能革新 45.1 神经形态计算概念 神经形态计算是借鉴生物神经系统的结构和工作原理来设计计算系统。它模仿人脑神经元和突触的工作方式&#xff0c;具备低功耗、高并行性和自适应学习等特性&#xff0c;能在处理复杂感知和认知任务时展现出卓越的…...

Python刷题:流程控制(下)

今天刷的是PythonTip的Python 入门挑战中的题&#xff0c;整体难度不高&#xff0c;适合小白练手以及巩固知识点。下面会进行详细讲解。 每日一句 在无人问津的角落里&#xff0c; 默默努力的人独自发光&#xff0c; 孤独是他们奋斗路上的常客&#xff0c; 却也是成就他们的…...

【Bootstrap V4系列】学习入门教程之 组件-徽章(Badge)和面包屑导航(Breadcrumb)

Bootstrap V4系列 学习入门教程之 组件-徽章&#xff08;Badge&#xff09;和面包屑导航&#xff08;Breadcrumb&#xff09; 徽章&#xff08;Badge&#xff09;一、示例二、根据情境改变外观三、胶囊式徽章&#xff08;Pill badges&#xff09;四、链接 面包屑导航&#xff0…...

结合强化学习RL和SFT各自训练优势,让模型边学边练,从而平衡Zero-RL训练中的模仿和探索!!

摘要&#xff1a;最近在大型推理模型&#xff08;LRMs&#xff09;方面的进展表明&#xff0c;通过简单的基于规则的奖励进行强化学习&#xff08;RL&#xff09;&#xff0c;可以涌现出复杂的行为&#xff0c;例如多步推理和自我反思。然而&#xff0c;现有的零强化学习&#…...

ai之paddleOCR 识别PDF python312和paddle版本冲突 GLIBCXX_3.4.30

这里写自定义目录标题 问题一**解决方案****方法 1&#xff1a;使用符号链接将系统库链接到 Conda 环境** **补充说明****验证修复结果** 问题二&#xff1a;**问题根源****解决方案****1. 确认 TensorRT 安装状态****2. 安装 TensorRT 并配置环境变量****3. 验证 TensorRT 与 …...

C++ 单例模式详解

单例模式是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。 概念解析 单例模式的核心思想是&#xff1a; 限制类的实例化次数&#xff0c;确保在整个应用程序中只有一个实例存在 提供对该实例的全局访问点 控制共享…...

生成器模式(Builder Pattern)

好问题&#xff01;生成器模式&#xff08;Builder Pattern&#xff09;在现实生活和程序开发中非常常见&#xff0c;它适合创建**“一步一步搭建起来的复杂对象”**。 &#x1f9e0; 一句话定义 生成器模式&#xff08;Builder Pattern&#xff09;是一种将复杂对象的构建过程…...

计算机网络八股文--day4 --传输层TCP与UDP

这是面试中最常考到的一层&#xff1a;端到端&#xff08;也就是进程之间&#xff09;的透明数据传输服务&#xff0c;差错控制和流量控制 该层呈上启下&#xff0c;像上面的资源子网提高服务&#xff0c;并使用下面通信子网的服务 端口&#xff0c;用于唯一标识主机上进程的&…...

大型语言模型个性化助手实现

大型语言模型个性化助手实现 目录 大型语言模型个性化助手实现PERSONAMEM,以及用户资料和对话模拟管道7种原位用户查询类型关于大语言模型个性化能力评估的研究大型语言模型(LLMs)已经成为用户在各种任务中的个性化助手,从提供写作支持到提供量身定制的建议或咨询。随着时间…...

步进电机中断函数解释

STM32 motor111.c 中 HAL_TIM_PeriodElapsedCallback 函数逐行解释 下面我们对 STM32 项目中 motor111.c 文件里的 HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 函数进行逐行解析&#xff0c;帮助初学者理解每一行代码的作用。此函数是在定时器产生更新中断时被调…...

多把锁以及线程死锁问题

在 Java 中&#xff0c;每一个对象都可以作为一把锁&#xff0c;synchronized 通过获取对象头中的锁标志位来实现同步。当一个线程获取到对象的锁后&#xff0c;其他线程就无法再获取该锁&#xff0c;只能等待获取到锁的线程释放锁之后才能继续执行被 synchronized 修饰的代码块…...

Vue 3 Element Plus 浏览器使用例子

Element Plus 是一个基于 Vue 3 的流行开源 UI 库&#xff0c;提供了一系列的组件&#xff0c;帮助开发者快速构建现代化的用户界面。它的设计简洁、现代&#xff0c;包含了许多可定制的组件&#xff0c;如按钮、表格、表单、对话框等&#xff0c;适合用于开发各种 Web 应用。 …...

NoxLucky:个性化动态桌面,打造独一无二的手机体验

在数字时代&#xff0c;手机桌面的个性化设置已经成为许多人表达自我和展示个性的重要方式。今天&#xff0c;我们要介绍的 NoxLucky&#xff0c;就是这样一款功能强大的动态桌面手机应用。它不仅提供了独家的动态壁纸素材库&#xff0c;还支持将抖音、INS等平台的短视频直接设…...