python数据分析之爬虫基础:scrapy详解
一、爬虫工程化
在之前的爬虫学习中基本已经掌握了爬虫这门技术的大多数技术点,但是我们现在写的代码还很流程化,很难进行商用,想要爬虫达到商用级别,必须要对我们现在编写的爬虫进行大刀阔斧式的重组,以达到工程化的爬虫,所谓工程化,就是让程序更加有体系,有逻辑,更加模块化。
爬虫工程化:对爬虫的功能进行模块化的开发,并达到可以批量生产的效果(不论开发还是数据产出)
二、scrapy简介
scrapy是一个用python编写的开源网络爬虫框架,用于高效地从网站上抓取信息并提取结构化数据。
特点:速度快、简单、可扩展性强。
三、scrapy的工作流程
引擎:scrapy的核心,所有模块的衔接,数据流程处理。
调度器:本质上这东西可以看成是一个队列,里面存放着一堆我们即将要发送的请求。可以看成是一个url的容器,它决定了下一步要爬取哪一个url,在这里可以对url进行去重操作。
下载器:它的本质就是一个发送请求的模块,返回的是response对象。
爬虫:这是我们要写的的一个个部分的内容,负责解析下载器返回的response对象,从中提取我们需要的数据。
管道:这是我们要写的第二部分的内容,主要负责数据的存储和各种持久化操作。
工作流程:
1、爬虫中起始的url构成的request对象,并传递给调度器。
2、引擎从调度器中获取到request对象,然后交给下载器
3、由下载器来获取到网页源代码,并封装成response对象,并回馈给引擎
4、引擎将获取到的response对象传递给spider,由spider对数据进行解析(parse),并回馈给引擎。
5、引擎将将数据传递给pipeline进行数据持久化保存或进一步的数据处理
6、在此期间如果spider中提取到的并不是数据,而是子页面url,可以进一步提交给调度器,进而重复步骤。
四、scrapy的安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scrapy
查看是否安装成,可以在终端输入:
scrapy version
五、scrapy的使用
接下来,我们用scrapy来完成一个超级简单的爬虫,目标:深入理解scrapy的工作流程,以及各个模块之间是如何搭配工作的。
1、创建项目:
scrapy startproject 项目名称
示例:
scrapy startproject spider_test
创建好项目后,我们可以在pycharm中观察到scrapy帮我们创建了一个文件夹,结构如下:
以爬取4399小游戏的名称、类型为例子
# 首先进入项目
cd spider_test
# 创建爬虫项目
scrapy genspider xiao 4399.com # xaio代表名称后面跟的是域名
然后spiders文件夹下会生成一个xiao.py的文件,内容为:
import scrapyclass XiaoSpider(scrapy.Spider):name = "xiao" # 爬虫的名字allowed_domains = ["4399.com"] # 允许抓取的域名start_urls = ["https://www.4399.com/flash/"] # 起始页面urldef parse(self, response):# 该方法是用来处理解析的print(response)
运行该程序:
scrapy crawl xiao
但会发现有相当多的内容日志,我们可以在setting.py加上这段程序:
LOG_LEVEL = "WARNING"
# 日志的级别:DEBUG INFO WARNING ERROR CRITICAL(由低到高)设置成warning代表warning及以上的信息才能被打印
运行程序后,信息如下:
<200 https://www.4399.com/flash/>
(.venv) PS D:python学习python_studypythonProjectspider_test> import scrapyclass XiaoSpider(scrapy.Spider):name = "xiao" # 爬虫的名字allowed_domains = ["4399.com"] # 允许抓取的域名start_urls = ["https://www.4399.com/flash/"] # 起始页面urldef parse(self, response):# 该方法是用来处理解析的# print(response)# 拿到源代码# print(response.text)# 提取数据# text = response.xpath('//ul[@class="n-game cf"]/li/a/b/text()').extract()# print(text)# 分块解析数据li_list= response.xpath('//ul[@class="n-game cf"]/li')for li in li_list:name = li.xpath('a/b/text()').extract_first()category = li.xpath('em/a/text()').extract_first()time = li.xpath('em/text()').extract_first()dic = {"name":name,"category":category,"time":time}
对数据进行解析后,下一步就是对数据进行存储,这一步是在pipeline管道中进行的,需要用到yield将数据传递个管道。
yield dic # 可以节省内存,是因青睐调用的
因为管道默认是不生效的,需要在setting里手动开启管道
ITEM_PIPELINES = {# key就是管道的路径# value是管道的优先级,数值越小,优先级越高"spider_test.pipelines.SpiderTestPipeline": 300,
}
管道pipeline.py文件中打印数据和爬虫的名称:
class SpiderTestPipeline:def process_item(self, item, spider): # 处理数据的专用方法,item;数据,spider:爬虫print(item)print(spider.name)return item
对url进行代理,cookie以及UA等操作可以在爬虫和引擎之间或者引擎和下载器之间处理。
六、scrapy shell
scrapy shell是scrapy终端,是一个交互终端,可以在未启动spider的情况下尝试及调试爬取的代码。其本意是是用来测试提取数据的代码,不过可以将其是为正常的python终端,在上面测试任何的python代码。该终端是用来测试xpath或css表达式,查找他们的工作及爬取的网页中提取的数据,在编写spider时,该终端提供了交互性测试表达式代码的功能,免去了每次修改后运行spider的麻烦。
1、安装ipython
pip install ipython
ipython终端与其他相比更为强大,提供智能的自动补全,高亮输出,及其他特性。
2、应用
在ipython终端直接输入:
scrapy shell www.baidu.com
3、语法
(1)response对象
response.body(二进制文本)
response.text
response.url
response.stayus
(2)response解析
response.xpath()
使用xpath路径查询特定元素,返回selector列表对象
response.css()(bs4语法)
获取内容:response.css(‘#su::text’).extract_first()
获取属性:response.css(‘#su::attr(“value”)’).extract_first()
(3)selector对象
extract()
提取selector对象的值,如果提取不到,则会报错
使用xpath请求到的对象是一个selector对象,需要使用extract()方法拆包
extract_first()
提取selector列表中的第一个值,若提取不到返回空值
以获取百度网页百度一下为例:
scrapy shell www.baidu.com
response.xpath('//input[@id="su"]/@value').extract_first()
直接在终端输入即可,不需要输入ipython。
七、yield
1、带有yeild的函数不再是一个普通函数,而是一个生成器generator,用于迭代。
2、yield是一个类似于return的关键字,迭代一次遇到yield时就返回后面的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码开始执行。
简要理解:yield就是return一个返回值,并记住这个返回的位置,下次迭代就从这个位置后开始。
案例:当当网(1)yield (2)管道封装(3)多条管道下载(4)多页数据下载
首先需要在终端创建项目以及爬虫名称
scrapy startproject scrapy_dangdang
cd scrapy_dangdang
scrapy genspider dangdang www.dangdang.com
因为要爬取书的名称、图片以及价格,可以在items.py中自定义数据结构。
class ScrapyDangdangItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 图名src = scrapy.Field()# 名称name = scrapy.Field()# 价格price = scrapy.Field()
在dangdang.py中去执行解析数据并发送url给引擎
import scrapy
from scrapy_dangdang.items import ScrapyDangdangItemclass DangdangSpider(scrapy.Spider):name = "dangdang"allowed_domains = ["www.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.01.02.00.00.00.html"]def parse(self, response):# src = //ul[@id="component_59"]/li//img/@src# name = //ul[@id="component_59"]/li//img/@alt# price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()# 所有的seletor的对象,都可以再次调用xpath方法li_list = response.xpath('//ul[@id="component_59"]/li')for li in li_list:src = li.xpath('.//img/@data-original').extract_first() # 这里需要注意:除了第一条数据没有懒加载,其它均有懒加载if src:src = srcelse:src = li.xpath('.//img/@src').extract_first()name = li.xpath('.//img/@alt').extract_first()price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()book = ScrapyDangdangItem(src=src, name=name, price=price)yield book # 需要在setting中手动开启pipeline管道
然后就需要保存数据,这个时候就用到了管道pipeline,我们需要在setting中手动打开管道。
ITEM_PIPELINES = {"scrapy_dangdang.pipelines.ScrapyDangdangPipeline": 300,
}
key就是管道的路径,value是管道的优先级,数值越小,优先级越高。
在pipeline中保存数据:
from itemadapter import ItemAdapterclass ScrapyDangdangPipeline:# 在爬虫文件执行之前,就执行的方法:def open_spider(self, spider):self.fp = open("book.json","w",encoding="utf-8") # 打开文件但并未关闭,所以w的模式写入def process_item(self, item, spider):# item就是我们的数据# with open("book.json", "a", encoding="utf-8") as f: # 这里需要采用追加的形式,因为数据是一条条传递来的,每一个对象都打开一次文件,从而导致数据被覆盖# f.write(str(item))# 但上述方法并不是最优解,因为我们对文件的操作过于频繁,,会有频繁的IO操作。这个时候我们通过两个方法来改进代码self.fp.write(str(item) )return item# 爬虫文件执行后,执行的方法。def close_spider(self,spider):self.fp.close()
多条管道下载,实现一边下载图片,一边下载json数据。
# setting文件中需要加上这条管道。因为图片下载慢,因此优先级就低一些
ITEM_PIPELINES = {"scrapy_dangdang.pipelines.ScrapyDangdangPipeline": 300,"scrapy_dangdang.pipelines.DangDangDownloadImg":301
}
# pipelines文件
import urllib.request
class DangDangDownloadImg:def process_item(self, item, spider):url = "http:" + item.get('src') # 这里需要注意的是:下载下来的路径前面无http,需要拼接filename = './books/'+item.get("name")+'.jpg'urllib.request.urlretrieve(url=url,filename=filename)return item
完成当当网的多页数据下载,因为每一页爬取的业务都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法即可。
import scrapy
from scrapy_dangdang.items import ScrapyDangdangItem
from scrapy.http import Request
class DangdangSpider(scrapy.Spider):name = "dangdang"# 如果十多页下载的话,那么必须要调整的是allowed_domins的范围,一般情况只写域名allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/pg1-cp01.01.02.00.00.00.html"]base_url = "https://category.dangdang.com/pg"page = 1def parse(self, response):# src = //ul[@id="component_59"]/li//img/@src# name = //ul[@id="component_59"]/li//img/@alt# price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()# 所有的seletor的对象,都可以再次调用xpath方法li_list = response.xpath('//ul[@id="component_59"]/li')for li in li_list:src = li.xpath('.//img/@data-original').extract_first() # 这里需要注意:除了第一条数据没有懒加载,其它均有懒加载if src:src = srcelse:src = li.xpath('.//img/@src').extract_first()name = li.xpath('.//img/@alt').extract_first()price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()book = ScrapyDangdangItem(src=src, name=name, price=price)yield book # 需要在setting中手动开启pipeline管道if self.page < 100:self.page = self.page + 1url = self.base_url + str(self.page) + "-cp01.01.02.00.00.00.html"# 调用parse方法,callback表示要执行的函数yield scrapy.Request(url=url, callback=self.parse)
八、CrawlSpider
CrawlSpider可以定义规则,在解析html内容的时候,可以根据连接规则提出指定的链接,然后再向这些链接发送请求。所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用CrawlSpider是非常合适的。
1、提取链接
提取链接器,在这里就可以写规则提取指定连接
scrapy.linkectractors.LinkExtractor(
allow = (), # 正则表达式,提取符合正则的链接
dengy = (), # (不用)正则表达式 不提取符合正则的链接
allow_domins = (), # (不用)允许的域名
restrict_xpaths = (), # xpath,提取符合xpath规则的链接
restrict_css = (), # 提取符合选择器规则的链接
2、模拟使用
正则用法:links = LinkExtractor(allow=r"list_23d+.html")
xpath语法:links = LinkExtractor(restrict_xpaths=r"//div[@class=‘x’]")
css语法:links = LinkExtractor(restrict_css=“.x”)
3、提取连接
link.extract_links(response)
案例:以爬取多页读书网数据为例(每一页数据的结构是相似的),并存储到数据库中。
scrapy shell https://www.dushu.com/book/1107.html
# 导包
In [1]: from scrapy.linkextractors import LinkExtractor
# 通过re正则表达式提取数据
In [2]: link = LinkExtractor(allow=r'/book/1107_d+.html')
# 提取连接
In [3]: link.extract_links(response)
注意事项:
1、callback只能写函数名字符串,callback=“parse_item”
2、在基本的spider中,如果重新发送请求,那么callback写的是 callback=self.parse_item follow=true 是否跟进就是按照提取连接规则进行提取
代码复现:
# 在终端创建项目
scrapy stratproject scrapy_readbook
# 进入根目录
scrapy startproject scrapy_readbook
# 创建爬虫文件这里是有所不同的,需要注意
scrapy genspider -t crawl read www.dushu.com/book/1107.html
上面是原始的read爬虫文件,还是有所不同的。
把数据存储在MySQL中,这里可能需要一些MySQL以及pymysql的知识。可以根据情况进行学习。这里我们只需要在pipelines文件中写主要的存储逻辑,并且在settings文件中进行多管道下载:
# settings文件
DB_HOST = "localhost"
DB_PORT = 3306
DB_USER = "root"
DB_PASSWORD = "0219423"
ITEM_PIPELINES = {"scrapy_readbook.pipelines.ScrapyReadbookPipeline": 300,"scrapy_readbook.pipelines.PyMysqlPipeline":301
}
# pipelines文件
# 加载settings文件
from scrapy.utils.project import get_project_settings
from pymysql import Connection
class PyMysqlPipeline:def open_spider(self, spider):settings = get_project_settings()self.host = settings["DB_HOST"]self.port = settings["DB_PORT"]self.user = settings["DB_USER"]self.password = settings["DB_PASSWORD"]self.connect()def connect(self):self.conn = Connection(host=self.host,port=self.port,user=self.user,password=self.password)self.cursor = self.conn.cursor()self.conn.select_db("test")def process_item(self, item, spider):sql = 'insert into spider(name,src) values("{}","{}")'.format(item['name'], item['src'])self.cursor.execute(sql)self.conn.commit()return itemdef close_spider(self, spider):self.cursor.close()self.conn.close()
九、scrapy的post请求
我们还是以百度翻译为例,在这里我就只写出逻辑执行的文件:
import scrapy
import jsonclass PostSpider(scrapy.Spider):name = "post"allowed_domains = ["fanyi.baidu.com"]# post请求 如果没有参数 那么这个请求将没有任何意义,所以start_urls也就没有用了,从而parse方法也无用# start_urls = ["https://fanyi.baidu.com/sug"]# def parse(self, response):# passdef start_requests(self):url = "https://fanyi.baidu.com/sug"data={"kw": "spider"}yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse_second)def parse_second(self, response):content = response.textobj = json.loads(content)print(obj)
相关文章:

python数据分析之爬虫基础:scrapy详解
一、爬虫工程化 在之前的爬虫学习中基本已经掌握了爬虫这门技术的大多数技术点,但是我们现在写的代码还很流程化,很难进行商用,想要爬虫达到商用级别,必须要对我们现在编写的爬虫进行大刀阔斧式的重组,以达到工程化的…...

openwrt 负载均衡方法 openwrt负载均衡本地源接口
openwrt 负载均衡方法 openwrt负载均衡本地源接口_mob6454cc647bdb的技术博客_51CTO博客 本人注重原理分析,要求对其原理掌握,否则按教程操作,你怕是什么都学不会,仔细看,认真记比较好。 首先确认一下基本细节 1、路由…...
Linux高级--3.3.2.6高并发编程之“内存屏障”“CPU屏障”“编译屏障”
一、内存屏障 在 Linux C 语言编程 中,内存屏障(Memory Barrier) 是一种用于控制内存访问顺序的技术。它主要用于多处理器系统中,确保某些操作按预期顺序执行,避免 CPU 和编译器对内存访问进行优化,从而影…...

【含开题报告+文档+PPT+源码】基于SpringBoot的智能安全与急救知识科普系统设计与实现
开题报告 在全球范围内,安全与急救知识的普及已成为提升公众安全素养、减少意外伤害发生率、提高突发事件应对能力的重要举措。尤其是在当今社会,人们面临的生活、工作环境日益复杂,交通事故、火灾、溺水、突发疾病等各种意外事件的发生概率…...

EMQX5.X版本性能配置调优参数
EMQX 主配置文件为 emqx.conf,根据安装方式其所在位置有所不同: 安装方式配置文件所在位置DEB 或 RPM 包安装/etc/emqx/emqx.confDocker 容器/opt/emqx/etc/emqx.conf解压缩包安装./etc/emqx.conf EMQ X 消息服务器默认占用的 TCP 端口包括: 端口 说明…...

电脑配置maven-3.6.1版本
不要使用太高的版本。 apache-maven-3.6.1-bin.zip 下载这个的maven压缩包 使用3.6.1版本。 解压缩放在本地软甲目录下面: 配置系统环境变量 在系统环境下面配置MAVEN_HOME 点击path 新增一条 在cmd中输入 mvn -v 检查maven的版本 配置阿里云镜像和本地的仓库 …...

水电站视频智能监控系统方案设计与技术应用方案
一、背景需求 水电站作为国家重要的能源基地,其安全运行对于保障能源供应和社会稳定具有重要意义。然而,传统的人工监控方式存在着诸多问题,如人力成本高、监控范围有限、反应不及时等。因此,水电站急需引进一种先进的视频智能监控…...
React 组件通信完整指南 以及 自定义事件发布订阅系统
React 组件通信完整指南 1. 父子组件通信 1.1 父组件向子组件传递数据 // 父组件 function ParentComponent() {const [data, setData] useState(Hello from parent);return <ChildComponent message{data} />; }// 子组件 function ChildComponent({ message }) {re…...

华为 AI Agent:企业内部管理的智能变革引擎(11/30)
一、华为 AI Agent 引领企业管理新潮流 在当今数字化飞速发展的时代,企业内部管理的高效性与智能化成为了决定企业竞争力的关键因素。华为,作为全球领先的科技巨头,其 AI Agent 技术在企业内部管理中的应用正掀起一场全新的变革浪潮。 AI Ag…...
【Pandas】pandas Series empty
Pandas2.2 Series Attributes 方法描述Series.index每个数据点的标签或索引Series.array对象底层的数据数组Series.values以NumPy数组的形式访问Series中的数据值Series.dtype用于获取 Pandas Series 中数据的类型(dtype)Series.shape用于获取 Pandas …...

Git如何设置和修改当前分支跟踪的上游分支
目录 前言 背景 设置当前分支跟踪的上游分支 当前分支已有关联,删除其关联,重新设置上游 常用的分支操作 参考资料 前言 仅做学习记录,侵删 背景 在项目开发过程中,从master新建分支时,会出现没有追踪的上游分…...

GitHub新手用法详解【适合新手入门-建议收藏!!!】
目录 什么是Github,为什么使用它? 一、GitHub账号的注册与登录 二、 gitbash安装详解 1.git bash的下载与安装 2.git常用命令 3. Git 和 GitHub 的绑定 1. 获取SSH keys 2.绑定ssh密钥 三、通过Git将代码提交到GitHub 1.克隆仓库 2.测试提交代码…...

游戏开发线性空间下PS工作流程
前言 使用基于物理的渲染,为了保证光照计算的准确,需要使用线性空间; 使用线性空间会带来一个问题,ui 在游戏引擎中的渲染结果与 PS 中的不一致: PS(颜色空间默认是sRGB伽马空间):…...
7-10 最长公共子序列
目录 题目描述 输入格式: 输出格式: 输入样例: 输出样例: 解题思路: 详细代码: 题目描述 给出 1~n 的两个排列 P1 和 P2,求它们的最长公共子序列。 n 在 5~1000 之间。 输入格式: 第一行是一个数 n 接下来两行,每行为 n 个数&…...
亚远景-ISO 21434标准下的汽车网络安全:风险评估与管理的关键实践
ISO 21434标准,全称为ISO/SAE 21434 "Road Vehicles - Cybersecurity Engineering",是国际标准化组织(ISO)发布的针对汽车领域的标准,旨在指导汽车制造商、供应商和相关利益相关方在汽车系统中应用适当的网络安全措施。在ISO 21434…...
C++ 的 source_location
1 __FILE__ 和 __LINE__ 你一定看过这样的代码: printf("Internal error at \"%s\" on line %d.\n", __FILE__, __LINE__); 这行代码的作用就是打印出 printf() 函数调用发生时所在的源代码文件名(包含路径)和这行代…...
[python SQLAlchemy数据库操作入门]-14.实时数据采集 记录股市动态
哈喽,大家好,我是木头左! 要使用 SQLAlchemy 进行实时数据采集,首先需要搭建相应的开发环境。以下是所需的主要步骤: 安装 Python:确保你的系统上已经安装了 Python,推荐使用 Python 3.x 版本。创建虚拟环境:为了隔离项目依赖,建议为每个项目创建一个虚拟环境。可以使…...

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别
文章目录 1、什么是空字符串?2、两个引号之间加上空格 好的,我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别,以及它们在 SQL 查询中的作用: 1. we_chat_union_id IS NOT NULL 含…...

【和春笋一起学C++】文本输入与读取
前言:前面学习了while语句后,下面用while语句实现一个重要的功能,逐字符的读取键盘输入的字符序列,并输出到显示屏上。 准备知识: C的输入输出包含以下3方面的内容: 对系统指定的标准设备的输入和输出。即…...

D类音频应用EMI管理
1、前言 对于EMI,首先需要理解天线。频率和波长之间的关系,如下图所示。 作为有效天线所需的最短长度是λ/4。在空气中,介电常数是1,但是在FR4或玻璃环氧PCB的情况下,介电常数大约4.8。这种效应会导致信号在FR4材…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...