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

用PHP异步协程控制python爬虫脚本,实现多协程分布式爬取

背景

公司需要爬取指定网站的产品数据。但是个人对python的多进程和协程不是特别熟悉。所以,想通过php异步协程,发起爬取url请求控制python爬虫脚本,达到分布式爬取的效果。

准备

  • 1.准备一个mongodb数据库用于存放爬取数据
  • 2.引入flask包,方便php通过调用url发起请求控制脚本
  • 3.引入selenium、BeautifulSoup4、webdriver等python包
  • 4.使用php的swoole异步协程发送url请求

python爬虫脚本

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from flask import Flask,jsonify,request
from pymongo import MongoClient
from datetime import datetime
from gevent import pywsgi
import sys
import requests
import re
from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer
from tornado.ioloop import IOLoop#创建一个服务,赋值给APP
app = Flask(__name__)@app.route('/get_ic_product_list',methods=['post']) #指定接口访问的路径,支持什么请求方式get,post
def get_ic_product_list():# url = 'https://www.ic.com/psen/ClassList2.aspx?id=3'# url = 'https://www.ic.com/ClassList2.aspx?id=3'chrome_options = webdriver.ChromeOptions()chrome_options.add_argument('--no-sandbox')chrome_options.add_argument('--headless')chrome_options.add_argument('--disable-gpu')chrome_options.add_argument('--ignore-certificate-errors')browser = webdriver.Chrome()conn = MongoClient('192.168.0.143', 27017)try:uri = request.form.get('url')# 是否按照零库存处理 yes-是 no-否isContinue = request.form.get('is_continue_stock', 'yes')# uri = sys.argv[1]# isContinue = sys.argv[2]if uri == '':return jsonify({'status': 0, 'msg': 'uri is null'})browser.get(uri)browser.implicitly_wait(3)time.sleep(2)# 连接mongodatabase = conn.iccollection = database.ic_product# 时间格式化nowtime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')spiderTime = datetime.now().strftime('%Y%m%d')spidertime = int(spiderTime)# 总页数pageTag = browser.find_element(By.CLASS_NAME, 'P_Page')total_page = pageTag.text.strip().split('/')[1]# 分类列表,不按照stock=0处理cateMap = ['21', '43', '175','179','184','241','250','268','306','317','325','343','397','394','409','467','547','556','606','638','657','678','1150','1158','2315','2383']if total_page:t_page = int(total_page)if t_page > 20:totalPage = 55else:totalPage = t_pageelse:totalPage = 20stop = 0soup = BeautifulSoup(browser.page_source, 'html.parser')tables = soup.findAll(name="table", attrs={"class": "prilist"})if len(tables) > 0:for table in tables:# 阶梯价price_tb = table.findAll('tr')price = [tb.text.strip() for tb in price_tb]# 行数据cols = table.parent.parentitem = [col.text.strip() for col in cols]time.sleep(2)print('==========item==========')print(item)# 库存为0,终止程序stock = item[11]if stock == '-':stop += 1continuepos = item[3].find('Promotion')if pos != -1:sku = str(item[3].replace('(Promotion)', ''))else:sku = item[3]# 格式化数据collection.insert_one({'datasheet': str(item[0]),'img_url': str(item[1]),'productDescEn': str(item[2]),'part': sku,'manufacturer': str(item[5]),'description': str(item[7]),'pdfLinkUrl': str(item[10]),'availability': str(item[11]),'price': price,'created_at': nowtime,'spider_time': spidertime,'sync_time': 20010101,'updated_at': '2001-01-01 00:00:00',})# 接口请求在clickfor i in range(totalPage):print('==========i==========')print(i)browser.find_element(By.XPATH, './/div[@id="Pager1"]/a[9]').click()soup = BeautifulSoup(browser.page_source, 'html.parser')tables = soup.findAll(name="table", attrs={"class": "prilist"})print('==========stop==========')print(stop)if stop>10 and isContinue=='yes':breakif len(tables) < 1:return jsonify({'status': 0, 'msg': 'product list empty'})print('==========tables==========')print(tables)mongoData = []for table in tables:# 阶梯价price_tb = table.findAll('tr')price = [tb.text.strip() for tb in price_tb]# 行数据cols = table.parent.parentitem = [col.text.strip() for col in cols]time.sleep(2)print('==========item==========')print(item)# 库存为0,终止程序stock = item[11]if stock == '-':stop += 1continuepos = item[3].find('Promotion')if pos != -1:sku = str(item[3].replace('(Promotion)', ''))else:sku = item[3]# 格式化数据mongoData.append({'datasheet': str(item[0]),'img_url': str(item[1]),'productDescEn': str(item[2]),'part': sku,'manufacturer': str(item[5]),'description': str(item[7]),'pdfLinkUrl': str(item[10]),'availability': str(item[11]),'price': price,'created_at': nowtime,'spider_time': spidertime,'sync_time': 20010101,'updated_at': '2001-01-01 00:00:00',})# 插入mongomongoData and collection.insert_many(mongoData)print('================mongoData================')print(mongoData)del price, tablestime.sleep(5)return jsonify({'status': 1,'msg': 'ok'})except Exception as error:return jsonify({'status':0,'msg':error})finally:conn.close()browser.close()if __name__ == '__main__':app.run(host='0.0.0.0',port=8005,debug=True)          # 启动服务器# Tornado启动服务
# s = HTTPServer(WSGIContainer(app))
# s.listen(8005) # 监听 8080 端口
# IOLoop.current().start()

php协程调用curl请求封装

在laravel 框架下创建command服务
此处有用到redis队列的,有不熟悉的请阅读redis相关资料

<?php
/*** 爬取IC任务*/
namespace App\Console\Commands;use App\Models\IcProductCategoryModel;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use Swoole\Timer;class SpiderIcProductList extends Command
{/*** The name and signature of the console command.** @var string*/protected $signature = 'spider:ic_product';/*** The console command description.** @var string*/protected $description = '每天定时爬取IC网站数据';/*** Create a new command instance.** @return void*/public function __construct(){parent::__construct();}/*** Execute the console command.** @return int*/public function handle(){$this->getProduct();return 0;}public function getProduct(){/*** ic product_num> 0, 分类约345个* 目前15min【900 * 1000】爬取10个分类,一天能爬取960个分类,一天能爬2次*/Timer::tick(60 * 15 * 1000,function (){$categoryModel = new IcProductCategoryModel();$key = $categoryModel::getCategoryQueue();echo 'time:' .date('H:i:s') .space();if (Redis::lLen($key) > 0) {$data = Redis::lRange($key,0,9);foreach ($data as $categoryId){go(function () use ($categoryId){$client = new \Swoole\Client(SWOOLE_SOCK_TCP);// 尝试与指定 TCP 服务端建立连接(IP和端口号需要与服务端保持一致,超时时间为0.5秒)if ($client->connect("127.0.0.1", 9505, 0.5)) {// 建立连接后发送内容$data = ['service' => 'RemoteApiSpider','method' => 'getProduct','param' =>  ['category_id' => $categoryId,'platform' => PLATFORM_IC,],];$sendData = jsonE($data);echo  'send=' .$sendData  .' ,'. date('H:i:s')   .space();$client->send($sendData);// 打印接收到的消息echo $client->recv();// 关闭连接$client->close();} else {echo "connect failed.";}});}Redis::lTrim($categoryModel::getCategoryQueue(),10,-1);unset($data);}});echo 'spider product end time:' .date('H:i:s') .space();}
}

创建服务端Server

<?phpnamespace App\Console\Commands;use App\Services\RemoteApiSpider;
use App\Services\TcpService;
use App\Services\TestService;
use Swoole\Database\MysqliConfig;
use Swoole\Database\MysqliPool;
use Swoole\Server;class Swoole extends Base
{protected $ws;/*** The name and signature of the console command.** @var string*/protected $signature = 'swoole {action} {--d}';/*** The console command description.** @var string*/protected $description = 'swoole service command';/*** Create a new command instance.** @return void*/public function __construct(){parent::__construct();}/*** Execute the console command.** @return int*/public function handle(){global $argv;$action = $this->argument('action');$argv[0] = 'wk';$argv[1] = $action;$argv[2] = $this->option('d') ? '-d' : '';$this->startServer();return 0;}public function startServer(){$server = new \Swoole\Server("127.0.0.1", 9505);// 设置异步任务的工作进程数量$log_path = storage_path() . '/logs/server.log';$server->set(['daemonize' => true,'log_file' =>  $log_path,'task_worker_num' => 50,]);//收到请求时触发$server->on('receive', function(\Swoole\Server $server, $fd, $from_id, $data) {//投递异步任务$task_id = $server->task($data);echo "异步任务投递成功: id=$task_id , recv={$data} " .his() . space();$server->send($fd, "task_id[{$task_id}],recv={$data},数据已接收,处理中... " .his() . space());});// 处理异步任务$server->on('Task', array($this, 'onTask'));//        $server->on('task', function (\Swoole\Server $server, $task_id, $from_id, $data) {
//            echo "新的待处理异步任务[id=$task_id] ".his() . space();
//            /**
//             $data = ['data' => [],'code' => '200','msg' => 'false']
//             */
//            $service = new RemoteApiSpider();
//            $service->setDebug(true);
//            if($data && is_string($data)){
//                $data = jsonD($data);
//            }
//            $ret = false;
//            if($data['code']==200 && $data['msg'] == 'ok'){
//                if(isset($data['data']['category_id']) && $data['data']['category_id']){
//                    $categoryId = $data['data']['category_id'];
//                    $ret = $service->getProduct($categoryId);
//                }
//            }
//            // todo 处理异步任务
//            // 返回任务执行的结果
//            $msg = "task_id[{$task_id}] ,category_id:" .$data . " ,ret:".$ret . " ," . his() . space();
//            $server->finish($msg);
//        });// 处理异步任务的结果$server->on('finish', function (\Swoole\Server $server, $task_id, $data) {echo "异步任务[$task_id] 处理完成: $data ". his() . space();});$server->start();}public function process(){$server = new TcpService();// 定义连接建立回调函数$server->onConnect = function ($conn) {echo "onConnect -- accepted " . stream_socket_get_name($conn, true) . "\n";};// 定义收到消息回调函数$server->onMessage = function ($conn, $msg) {echo "onMessage --" . $msg . "\n";$service = new RemoteApiSpider();$service->setDebug(true);$content = $service->getProduct($msg);fwrite($conn, "received " . $msg . "\n");};// 定义连接关闭回调函数$server->onClose = function ($conn) {echo "onClose --" . stream_socket_get_name($conn, true) . "\n";};// 启动服务器主进程$server->run();}public function onTask($serv, $task_id, $from_id, $data){//传类名、方法、参数实现公共使用try {if (!$data) {throw new \Exception(' task_id=' . $task_id . ',暂无需要处理的task任务', 400);}if (is_string($data)) {$data = jsonD($data);}echo 'recv: ' . jsonE($data) . space();$className = "App\Services\\{$data['service']}";if (!class_exists($className)) {throw new \Exception(' task_id=' . $task_id . ',未找到服务类名', 401);}$class = new $className;$func = $data['method'];if(isset($data['param'])){$ret = $class->$func($data['param']);}else{$ret = $class->$func();}return jsonE($ret);} catch (\Exception $e) {$msg = ' task_id=' . $task_id . ' ,error: ' . $e->getMessage();echo jsonE($msg) . space();}$serv->finish($msg);//每分钟执行一下service下的start方法,发送二维数组请求给tcp服务端,服务端调用service下的process方法实现业务逻辑//服务端拿到数据后,处理后结果格式:['code'=> 200,'msg'=> 'ok','data' => maxid]
//        $data = [
//            'service' => 'TestService',
//            'method' => 'process',
//            'param' => ['debug'=> true,'send' =>'sucess'],
//        ];//暂时留空 2.3部分会完善}}

curl发送异步请求调用python脚本

<?php
/*** 爬取接口封装*/
namespace App\Services;use App\Library\Oneyac\Oneyac;
use App\Models\HqchipProductCategoryModel;
use App\Models\HqchipProductMongoModel;
use App\Models\IcProductCategoryModel;
use App\Models\IcProductMongoModel;
use App\Models\LcscProductCategoryModel;
use App\Models\LcscProductMongoModel;
use App\Models\OneyacProductCategoryModel;
use App\Models\OneyacProductMongoModel;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;class RemoteApiSpider extends Base
{/*** 根据分类循环分页爬取产品列表* @param $data* @return int* @throws \GuzzleHttp\Exception\GuzzleException*/public function getProduct($data){$cateId = 0;$categoryId = $data['category_id'] ?? $cateId;$platform = $data['platform'] ?? PLATFORM_LCSC;$platform = strtolower(trim($platform));$categoryId = (int)$categoryId;switch ($platform) {case PLATFORM_IC:$cateModel = new IcProductCategoryModel();Redis::hDel($cateModel::getCategoryListKey(),$categoryId);//TODO 调用python API接口爬取产品数据//s2 20分钟处理4个 与 s1 20分钟处理6个 $header = [];$header['Content-Type'] = 'application/json;charset=UTF-8';$query_param['page'] = 1;$res = $this->getIcProduct($categoryId, $platform,$query_param, $header);$res && $cateId = $categoryId;break;}return $cateId;}/*** 获取ic产品信息* @param $categoryId* @param $platform* @param $query_param* @param $header* @return bool* @throws \GuzzleHttp\Exception\GuzzleException*/public function getIcProduct($categoryId, $platform, $query_param, $header){$module =  'product_list';$this->getPlatformConf(PLATFORM_IC,$module);$msg = ' ' . $platform . '_' . $module . ' ';echo $msg. ' ,category_id:' . $categoryId . ' spidering' .space();try {//$uri = 'https://www.ic.com/psen/ClassList2.aspx?id=3';$uri = $this->base_uri . $this->uri . '?id=' . $categoryId;# todo 3的倍数推入s2,其他推入s1$config = config('ic');# 重点:此处可以部署到不同服务器进行爬取,我这里只部署了2台服务,s1与s2if(($categoryId%3)===0){//s2$curl = $config['spider_uri']['s2'] ?: 'http://192.168.0.124:8005/get_ic_product_list';}else{//s1$curl = $config['spider_uri']['s1'] ?: 'http://192.168.0.127:8005/get_ic_product_list';}$response = curlPost($curl,['url' => $uri,'is_continue_stock' => 'yes']);$flag = false;if(isset($response) && !empty($response)){$response = is_array($response) ? $response : jsonD($response);$flag = ($response['msg']=='ok' && $response['status']==1);}if ($flag) {$this->debug && Log::info($msg . 'category_id:' . $categoryId . ' ,mongo-batch-insert:' . $flag);} else {throw new \Exception($msg.'ic爬虫异常,请检查python爬虫');}unset($response);return  $flag;}catch (\Exception $e){Log::error($msg .'爬取产品异常,异常原因:'.$e->getMessage());return false;}}

nginx配置

server {listen 8080;server_name spidertest.test *.spidertest.test;root "D:/WWW/spidertest/";location / {proxy_pass http://127.0.0.1:8005;}charset utf-8;
}
  • 注:
    1.在不同服务器上部署python爬虫脚本,并配置nginx服务。配置完成后安装下面命令启动脚本。接下来开启异步多线程执行python爬虫脚本即可。
    2.记得启动swoole服务。命令如下:
php artisan swoole start

运行

python脚本启动
在这里插入图片描述

postman测试:
![在这里插入图片描述](https://img-blog.csdnimg.cn/c24295c2a30c4f79a377856df4bb9767.png

php启动协程命令:
在这里插入图片描述

爬取回来的数据结果:在这里插入图片描述

相关文章:

用PHP异步协程控制python爬虫脚本,实现多协程分布式爬取

背景 公司需要爬取指定网站的产品数据。但是个人对python的多进程和协程不是特别熟悉。所以&#xff0c;想通过php异步协程&#xff0c;发起爬取url请求控制python爬虫脚本&#xff0c;达到分布式爬取的效果。 准备 1.准备一个mongodb数据库用于存放爬取数据2.引入flask包&a…...

VUE3写后台管理(3)

VUE3写后台管理&#xff08;3&#xff09; 1.环境1.node2.vite3.Element-plus4.vue-router5.element icon6.less7.vuex8.vue-demi9.mockjs10.axios11.echarts 2.首页1.布局Main2.头部导航栏CommonHeader3.左侧菜单栏CommonLeft4.首页Home1.从后端获取数据显示到前端table的三种…...

机器学习笔记之最优化理论与算法(十二)无约束优化问题——共轭梯度法

机器学习笔记之最优化理论与方法——共轭梯度法 引言回顾&#xff1a;共轭方向法的重要特征线性共轭梯度法共轭方向公式的证明过程 关于线搜索公式中参数的化简关于线搜索公式中步长部分的化简关于线搜索公式中共轭方向系数的化简参数化简的目的 非线性共轭梯度法(FR,PRP方法)关…...

JVM中的java同步互斥工具应用演示及设计分析

1.火车站售票系统仿真 某火车站目前正在出售火车票&#xff0c;共有50张票&#xff0c;而它有3个售票窗口同时售票&#xff0c;下面设计了一个程序模拟该火车站售票&#xff0c;通过实现Runnable接口实现&#xff08;模拟网络延迟&#xff09;。 伪代码&#xff1a; Ticket类…...

数据治理-数据质量

实现数据质量的前提就是数据本身是可靠和可信的。 导致数据质量低下的因素 组织缺乏对低质量数据影响的理解&#xff0c;缺乏规划、孤岛式系统设计、不一致的开发过程、不完整的文档、缺乏标准或缺乏治理等。 所有组织都会遇到与数据质量有关的问题。数据质量需要跨职能的承诺…...

[sqoop]hive3.1.2 hadoop3.1.1安装sqoop1.4.7

参考: Hadoop3.2.4Hive3.1.2sqoop1.4.7安装部署_hadoop sqoop安装_alicely07的博客-CSDN博客 一、安装 1、解压 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /home/data_warehouse/module mv sqoop-1.4.7.bin__hadoop-2.6.0 sqoop-1.4.72、配置文件 sqoop-env.s…...

js事件的详细介绍

11.事件 1.什么是事件 js属于事件驱动编程,把驱动,执行,调用通过一些交互,触发一些函数事件:发起-->执行绑定事件-->触发事件on 绑定 emit触发 off解绑2.事件分类 鼠标事件 点击事件 onclick 双击事件 ondblclick 按下事件 onmousedown 抬起事件 onmouseup 鼠标进…...

虚幻4学习笔记(12)操控导入的角色、动画蓝图、播放蒙太奇和打包、角色重定向

虚幻4学习笔记 操控导入的角色设置鼠标旋转关掉动态模糊 动画蓝图、播放蒙太奇和打包角色走路奔跑动画shift 奔跑F 跳舞移动打断 跳舞 打包角色重定向姿势调整解决跑步 腿分太开隐藏剑 B站UP谌嘉诚课程&#xff1a;https://www.bilibili.com/video/BV164411Y732 操控导入的角色…...

hive with tez:无法从链中的任何提供者加载aws凭据

环境信息 hadoop 3.1.0 hive-3.1.3 tez 0.9.1 问题描述 可以从hadoop命令行正确地访问s3a uri。我可以创建外部表和如下命令&#xff1a; create external table mytable(a string, b string) location s3a://mybucket/myfolder/; select * from mytable limit 20; 执行正…...

Ubuntu修改静态IP、网关和DNS的方法总结

Ubuntu修改静态IP、网关和DNS的方法总结 ubuntu系统&#xff08;其他debian的衍生版本好像也可以&#xff09;修改静态IP有以下几种方法。&#xff08;搜索总结&#xff0c;可能也不太对&#xff09; /etc/netplan (use) Ubuntu 18.04开始可以使用netplan配置网络&#xff0…...

Eureka服务器注册

一。Eureka服务器注册 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…...

Windows安装GPU版本的pytorch详细教程

文章目录 chatGLM2-6B安装教程正式安装 chatGLM2-6B ChatGLM2-6B版本要装pytorch2.0&#xff0c;而且要2.0.1 &#xff0c;因此CUDA不能用12.0 &#xff0c;也不能用10.0&#xff0c;只能用11.x 版本。 安装教程 pip install直接下载安装 官网&#xff1a; https://pytorch.…...

理解Kruskal算法的前提----深入理解并查集【超简单~】

并查集的实现思路 并查集主要分为两个部分&#xff1a;第一部分就是需要找到点对应的祖宗节点&#xff0c;第二部分&#xff0c;是要将属于同一个集合节点的祖宗节点进行统一&#xff0c;也就是结合操作。 Find函数实现 // parent数组用来存储下标值所对应的父节点值 // 比如…...

Jenkins+Gitee+Docker+Ruoyi项目前后端分离部署

前言 描述&#xff1a;本文主要是用来记录 如何用标题上的技术&#xff0c;部署到云服务器上通过ip正常访问。 一、总览 1.1、Docker做的事 拉取 mysql 镜像拉取 redis 镜像拉取 jdk 镜像拉取 nginx 镜像 解释说明&#xff1a;前端项目的打包文件放在 nginx容器运行。后端…...

笙默考试管理系统-MyExamTest----codemirror(23)

笙默考试管理系统-MyExamTest----codemirror&#xff08;23&#xff09; 目录 笙默考试管理系统-MyExamTest----codemirror&#xff08;23&#xff09; 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙…...

重学Java (一) 泛型

1. 前言 泛型编程自从 Java 5.0 中引入后已经超过15个年头了。对于现在的 Java 码农来说熟练使用泛型编程已经是家常便饭的事情了。所以本文就在不对泛型的基础使用在做说明了。 如果你还不会使用泛型的话&#xff0c;可以参考下面两个链接 Java 泛型详解The Java™ Tutorial…...

Docker 部署 Redis 服务

拉取最新版本的 Redis 镜像: $ sudo docker pull redis:latest在本地预先创建好 data 目录和 conf/redis.conf 文件。 使用以下命令来运行 Redis 容器: $ sudo docker run -itd --name redis --privilegedtrue -p 6379:6379 -v /home/ubuntu/docker/redis/data:/data -v /ho…...

阿里云产品试用系列-负载均衡 SLB

阿里云负载均衡&#xff08;Server Load Balancer&#xff0c;简称SLB&#xff09;是云原生时代应用高可用的基本要素。通过将流量分发到不同的后端服务来扩展应用系统的服务吞吐能力&#xff0c;消除单点故障并提升应用系统的可用性。阿里云SLB包含面向4层的网络型负载均衡NLB…...

drf 对象级权限

drf 对象级权限 Django REST Framework&#xff08;DRF&#xff09;提供了对象级别权限&#xff08;Object-level permissions&#xff09;来控制特定对象的访问权限。 简单来说&#xff1a;通过视图类中的self.get_object(pk)得到一个obj对象(视图对象)&#xff0c;在与requ…...

八大排序(二)--------冒泡排序

本专栏内容为&#xff1a;八大排序汇总 通过本专栏的深入学习&#xff0c;你可以了解并掌握八大排序以及相关的排序算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;八大排序汇总 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库…...

SmartSQL 一款开源的数据库文档管理工具

建议直接蓝奏云下载安装 蓝奏云下载&#xff1a;https://wwoc.lanzoum.com/b04dpvcxe 蓝奏云密码&#xff1a;123 项目介绍 SmartSQL 是一款方便、快捷的数据库文档查询、导出工具&#xff01;从最初仅支持 数据库、CHM文档格式开始&#xff0c;通过不断地探索开发、集思广…...

代码随想录算法训练营第56天 | ● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 动态规划之编辑距离总结篇

文章目录 前言一、583. 两个字符串的删除操作二、72. 编辑距离三、动态规划之编辑距离总结篇总结 前言 一、583. 两个字符串的删除操作 两种思路&#xff1a;1.直接动态规划&#xff0c;求两个字符串需要删除的最小次数 2.采用子序列的和-最长公共子序列。思路一分析如下&#…...

矩阵 m * M = c

文章目录 题1题2 题1 (2023江苏领航杯-prng) 题目来源&#xff1a;https://dexterjie.github.io/2023/09/12/%E8%B5%9B%E9%A2%98%E5%A4%8D%E7%8E%B0/2023%E9%A2%86%E8%88%AA%E6%9D%AF/ 题目描述&#xff1a; (没有原数据&#xff0c;自己生成的数据) from Crypto.Util.number…...

Linux——IO

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——文件系统 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;是不是只有C/C有文件操作呢&#xff1f;python&#xff0c;java&…...

svn(乌龟svn)和SVN-VS2022插件(visualsvn) 下载

下载地址: https://www.visualsvn.com/visualsvn/download/...

开源日报 0824 | 构建UI组件和页面的前端工作坊

Storybook 是一个用于构建 UI 组件和页面的前端工作坊&#xff0c;支持多种主流框架&#xff0c;提供丰富的插件&#xff0c;具有可配置性强和扩展性好的特点。 storybookjs/storybook Stars: 79.9k License: MIT Storybook 是一个用于构建 UI 组件和页面的前端工作坊&#x…...

福建三明大型工程机械3D扫描工程零件三维建模逆向抄数-CASAIM中科广电

高精度3D扫描技术已经在大型工件制造领域发挥着重要作用&#xff0c;可以高精度高效率实现全尺寸三维测量&#xff0c;本期&#xff0c;我们要分享的应用是大型工程机械3D扫描案例。 铣轮是深基础施工领域内工法先进、技术复杂程度高、高附加值的地连墙设备&#xff0c;具有成…...

使用香橙派学习 Linux的守护进程

Q&#xff1a;什么是守护进程 A&#xff1a;Linux Daemon&#xff08;守护进程&#xff09;是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务&#xff0c;不是对整个系统就是对某个…...

数据治理-数据仓库和商务智能

数据仓库的作用 减少数据冗余&#xff0c;提高信息一致性&#xff0c;让企业能够利用数据做出更优决策的方法&#xff0c;数据仓库是企业数据管理的核心。 业务驱动因素 运营支持职能、合规需求&#xff08;历史数据响应&#xff09;和商务智能活动&#xff08;主因&#xff1…...

CH2--x86系统架构概览

2.1 OVERVIEW OF THE SYSTEM-LEVEL ARCHITECTURE 图中的实线箭头表示线性地址&#xff0c;虚线表示段选择器&#xff0c;虚线箭头表示物理地址 2.1.1 Global and Local Descriptor Tables 全局描述符表 (GDT) GDT是一个全局的段描述符表&#xff0c;它存储在系统内存中的一个固…...

做二手房的端口网站/下载百度网盘app

前言 在项目中频繁遇到数组、集合和泛型&#xff0c;在使用vue时&#xff0c;用到最多的是数组&#xff1b;在后台时使用最多的是泛型&#xff0c;有时还用到IList&#xff0c;下面来学习一下它们之间的关系。 正文 数组 概念 一组类型相同的有序数据&#xff0c;它是…...

wordpress 网站图标设置方法/网络推广如何收费

注&#xff1a;可以通过 yum grouplist 来查看可能批量安装哪些列表从Windows转到Linux下面&#xff0c;一个不习惯的地方就是在图形界面下安装和删除软件的时候非常缓慢。但是如果你掌握了用yum的命令行模式进行 配置程序&#xff0c;你肯定会从心底喜欢上这个强大的工具。因为…...

厦门网站建设求职简历/温州seo结算

背景 近几年&#xff0c;前端应用&#xff08;WebApp&#xff09;正朝着大规模方向发展&#xff0c;在这个过程中我们会对项目拆解成多个模块/组件来组合使用&#xff0c;以此提高我们代码的复用性&#xff0c;最终提高研发效率。 在编写一个复杂组件的时候&#xff0c;总会依…...

网站的外链是怎么做的/桂平seo关键词优化

从计算机到手机&#xff0c;计算平台的发展不断将人类文明推向新的高峰&#xff0c;但随着移动互联网领域的开发潜力逐渐殆尽&#xff0c;越来越多的科技爱好者和开发者将目光投向了下一代计算平台——机器人。作为蕴含重大机会的领域&#xff0c;机器人产业发展却没有理想中迅…...

厦门建设局局长李德才/庆云网站seo

这次需要做一个把2个iphone游戏合成一个的事情&#xff0c;一开始还没有头绪&#xff0c;所以去论坛上求助高手。 回顾下其他平台的做法&#xff1a; Brew平台&#xff1a;可以多个应用程序&#xff08;app&#xff09;在一起的&#xff0c;每个app有一个单独的classiD&#xf…...

免费域名怎么做网站/网站seo推广优化

1 今天自动添加了一些主机&#xff0c;发现有一个是红色的&#xff0c;而且是网络是可以通的&#xff0c;其他机器都很好&#xff0c;重启了还是问题依旧2 于是想用zabbix_get试一下[rootZabbix-Server ~]# zabbix_get -s 90.90.90.118 -k system.cpu.switches zabbix_get [100…...