网络爬虫
一、提问
1.用过爬虫吗?以百度为例
2.如果没有百度怎么办?(这一类搜索引擎)
到政府了解、看电视、听广播
3.搜索引擎是如何查找网站的?
百度蜘蛛,爬取数据,然后放到库里,重复的,和不符合的丢弃,然后去百度搜索关键字,然后在库里找,然后例出来,根据索引
二、背景
1.产生:1993年
2.统计ftp站点
3.数据采集——>数据分析——>应用反馈
三、什么是爬虫
结论:网络爬虫,又称为网页蜘蛛、网络机器人,是一种按照一定规则,自动请求万维网站并提取网络数据(公开的)的程序或脚本
五、爬虫的分类
1.按照使用场景分类
(1)通用爬虫、全网爬虫:将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。搜索引擎,条件
(2)聚焦爬虫:又称主题网络爬虫,是指选择性地爬行那些与预先定义好的主题相关的页面的网络爬虫。条件要求一般比较底,更新的频率比较底
2.按照爬去形式分类
(1)累计是爬虫:从某一个时间点开始,通过遍历的方式抓取系统所能允许存储和处理的所有网页。页面多,硬件高,更新快
(2)增量式爬虫:在具有一定量规模的网络页面集合的基础上,采用更新数据的方式选取已有集合中的过时网页进行抓取,以保证所抓取到的数据与真实网络数据足够接近。页面少,硬件不高,更新快
3.按照爬取数据的存在方式进行分类
(1)表层爬虫:爬取表层网页的爬虫叫做表层爬虫。表层网页是指传统搜索引擎可以索引的页面,以超链接可以到达的静态网页为主构成的Web页面。
(2)深层爬虫:爬取深层网页的爬虫就叫做深层爬虫。深层网页是那些大部分内容不能通过静态链接获取的、隐藏在搜索表单后的,只有用户提交一些关键词才能获得的 Web 页面。(动态、登录)
一、通用爬虫的工作原理
通用爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。
URL:代表网址
一个循环
1.搜索引擎的工作流程
抓取网页
数据存储
预处理
检索和排名
二、聚焦爬虫
聚焦爬虫需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接,并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。
三、聚焦爬虫和通用爬虫的不同点
1.聚焦爬虫确定主题,
2.准备与主题相关的url
3.分析页面,提取主题相关信息url
4.分析页面,提取需要的数据,入库
五、通用爬虫中网页的分类
六、通用爬虫的网页文件
1.robot.txt文件
2.sitemap.xml文件
为了方便网站管理员通知爬虫遍历和更新网站的内容,而无需爬取每个网页,网站提供了Sitemap.xml文件(网站地图)。
七、防爬虫应对策略
1.伪装User-agent
User-agent表示用户代理,是HTTP协议中的一个字段,其作用是描述发出HTTP请求的终端信息。每个正规的爬虫都有固定的User-agent,只要将这个字段设为知名的用户代理,就能够
2.使用代理IP
代理IP就是介于用户和网站之间的第三者,即用户先将请求发送给代理IP,之后代理IP再发送到服务器。服务器会将代理IP视为爬虫的IP,同时用多个代理IP,可以降低单个IP地址的访问量,极有可能逃过一劫。
3.降低访问频率(10s、5s)
如果没有找到既免费又稳定的代理IP,则可以降低访问网站的频率,防止对方从访问量上认出爬虫的身份,不过爬取效率会差很多。为了弥补这个缺点,我们可以基于这个思想适时调整具体的操作。例如,每抓取一个页面就休息若干秒,或者限制每天抓取的页面数量
4.验证码限制
虽然有些网站不登陆就能访问,但是它一检测到某IP的访问量有异常,就会马上提出登陆要求,并随机提供一个验证码。碰到这种情况,大多数情况下需要采取相应的技术识别验证码,只有正确输入验证码,才能够继续爬取网站。不过,识别验证码的技术难度还是比较大的。
八、为什么选择Python做爬虫
1.抓取网页本身的接口
2.网页抓取后的处理
3.开发效率高
4.上手快
cheome->url->DNS->服务器->chrome
一、了解浏览网页过程
1.统一资源定位符URL
(1)URL是互联网上标准资源的地址,它包含了文件的位置以及浏览器处理方式等信息。
(2)URL地址由协议头、服务器地址、文件路径三部分组成。
(3)协议头:使用的传输协议,用于告诉浏览器如何处理将要代开的文件,不同的协议表示不同的资源查找以及传输方式。
(4)服务器地址(ip):存放资源的服务器的主机名或IP地址,其目的在于标识互联网上的唯一一台计算机。
(5)端口号(port):用于标识在一台计算机上运行的程序,每个应用程序都对应
一个或多个特定的端口,http:80 https:443,
2.计算机域名系统DNS
(1)DNS 是计算机域名系统(Domain Name System或Domain Name Service)的缩写,由解析器和域名服务器组成。
(2)一个域名对应一个IP,一个ip可以对应多个域名
二、http网络请求原理
1.分析浏览器显示完整网页的过程
2.HTTP网络请求原理
HTTP是一套计算机通过网络进行通信的规则,它由两部分组成:客户端请求消息和服务器端响应消息。
3.客户端HTTP请求格式
客户端发送一个HTTP请求到服务器的请求消息,由请求行、请求头部、空行、以及请求数据这四个部分组成。
3.客户端HTTP请求格式
最常用的请求方法是GET和POST,两者的区别在于:
(1)GET请求 – 参数都显示在URL上,服务器根据该请求所包含URL中的参数来产生响应内容。 由于请求参数都暴露在外,所以安全性不高。
(2)POST请求 – 参数在请求体当中,消息长度没有限制而且采取隐式发送,通常用来向HTTP服务器提交量比较大的数据。 POST请求的参数不在URL中,而在请求体中,所以安全性也高,使用场合也比GET多。
4.Host(主机和端口号):指定被请求资源的Internet主机和端口号,对应网址URL中的Web名称和端口号,通常属于URL的Host部分。
5.Connection(连接类型):表示客户端与服务器的连接类型。
6.Upgrade-Insecure-Requests(升级为HTTPS请求):表示升级不安全的请求,意思是会在加载 HTTP 资源时自动替换成HTTPS请求,让浏览器不再显示HTTPS页面中的HTTP请求警报。
7.User-Agent(浏览器名称):标识客户端身份的名称,通常页面会根据不同的User-Agent信息自动做出适配,甚至返回不同的响应内容。
8.Accept (传输文件类型):指浏览器或其他客户端可以接受的MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)文件类型,服务器可以根据它判断并返回适当的文件格式。
9.Referer (页面跳转来源):表明产生请求的网页来自于哪个URL,用户是从该 Referer页面访问到当前请求的页面。
10.Accept-Encoding(文件编解码格式):指出浏览器可以接受的编码方式。编码方式不同于文件格式,它的作用是压缩文件并加速文件传递速度。
11.Accept-Language(语言种类):指出浏览器可以接受的语言种类,如en或en-us指英语,zh或者zh-cn指中文,当服务器能够提供一种以上的语言版本时要用到。
12.Accept-Charset(字符编码):指出浏览器可以接受的字符编码。
13.Cookie (Cookie):浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现模拟登陆。
14.Content-Type (POST数据类型):指定POST请求里用来表示的内容类型。
15.服务端HTTP响应格式
HTTP响应由四个部分组成,分别是:状态行、响应报头、空 行、以及响应正文。
16.常用的响应报头和取值
17.响应状态代码由三位数字组成,其中第1位数字定义了响应的类别,有五种可能取值。
| 响应码 | 描述 |
|---|---|
| 100~199 | 表示服务器成功接收部分请求,要求客户端继续提交其余请求才能完成整个处理过程 |
| 200~299 | 表示服务器成功接收请求并已完成整个处理过程。常用状态码为200 |
| 300~399 | 为完成请求,客户需进一步细化请求,请求转换为新的url |
| 400~499 | 客户端的请求有错误,常用状态码包括404和403 |
| 500~599 | 服务器端出现错误,常用状态码为500 |
三、HTTP抓包工具Fiddler
1.如果需要对网络数据进行分析,这就需要将这些数据进行截获,也就是所谓的抓包。
2.HTTP抓包工具很多,Windows平台下最常用的就是Fiddler。
Fiddler是一款强大的Web调试工具(包含了抓包功能),它能记录所有客户端和服务器的HTTP请求和响应,还能模拟HTTP请求的发送。
3.Fiddler特点
(1)监控HTTP和HTTPS的流量
(2)可以查看截获的请求内容。
(3)可以伪造客户端请求发送给服务器
(4)可以伪造一个服务器的响应发送给客户端
(5)可以用于测试网站的性能。
(6)可以解密HTTPS的web会话。
(7)Fiddler提供的第三方插件,可大大提高工作效率。
4.Fiddler工作原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DDLRGLkJ-1653200262301)(C:\Users\31357\AppData\Roaming\Typora\typora-user-images\image-20220306174006232.png)]
Fiddler是以代理网络服务器的形式工作的,它使用的代理地址为127.0.0.1,端口为8888。
1.什么是requests库
requests是Python的一个第三方HTTP(Hypertext Transfer Protocol,超文本传输协议)库,它比Python自带的网络库urllib更加简单、方便和人性化。使用requests可以让Python实现访问网页并获取源代码的功能。
2.requests的作用
作用:发送网络请求,返回响应数据
中文文档 API: http://docs.python-requests.org/zh_CN/latest/index.html
3.使用pip安装requests,代码如下:
pip install requests
4.get方法可以接收多个参数,定义格式如下:
requsts.get(url, headers,params,timeout)
5.response.status_code #响应状态码
6.response.text 和response.content的区别
7.添加特定Headers—请求伪装
如果不是从浏览器发出的请求,我们是不能获得响应内容的。针对这种情况,我们需要将爬虫程序发出的请求伪装成一个从浏览器发出的请求。
8.我们可以使用代理服务器,每隔一段时间换一个代理。如果某个IP被禁止,那么就可以换成其他IP继续爬取数据,从而可以有效解决被网站禁止访问的情况。
9.超时设置
我们可以为HTTP请求设置超时时间,一旦超过这个时间,服务器还没有返回响应内容,那么就会抛出一个超时异常,这个异常需要使用try语句来捕获。
10.URLError异常和捕获
(1)没有连接网络
(2)服务器连接失败
(3)找不到指定服务器
| 模块名称 | 描述 |
|---|---|
| requests.Request | 表示请求对象,用于准备一个请求发送到服务器。 |
| requests.Response | 表示响应对象,其中包含服务器对HTTP请求的响应。 |
| requests.Session | 表示请求会话,提供Cookie持久性、连接池和配置。 |
12.其中,Request类的对象表示一个请求,它的生命周期针对一个客户端请求,一旦请求发送完毕,该请求包含的内容就会被释放掉。而Session类的对象可以跨越多个页面,它的生命周期同样针对的是一个客户端。
| 函数 | 功能****说明 |
|---|---|
| requests.request() | 构造一个请求,支撑以下各方法的基础方法 |
| requests.get() | 获取HTML网页的主要方法,对应于HTTP的GET请求方式 |
| requests.head() | 获取HTML网页头信息的方法,对应于HTTP的HEAD请求方式 |
| requests.post() | 向HTML网页提交POST请求的方法,对应于HTTP的POST请求方式 |
| requests.put() | 向HTML网页提交PUT请求的方法,对应于HTTP的PUT请求方式 |
| requests.patch() | 向HTML网页提交局部修改请求,对应于HTTP的PATCH请求方式 |
| requests.delete() | 向HTML网页提交删除请求,对应于HTTP的DELETE请求方式 |
14.这些函数都会做两件事情,一件是构建一个Request类的对象,该对象将被发送到某个服务器上请求或者查询一些资源;另一件是一旦得到服务器返回的响应,就会产生一个Response对象,该对象包含了服务器返回的所有信息,也包括原来创建的Request对象。
| 属性 | 说明 |
|---|---|
| status_code | HTTP请求的返回状态,200表示连接成功,404表示失败 |
| text | HTTP响应内容的字符串形式,即URL对应的页面内容 |
| encoding | 从HTTP请求头中猜测的响应内容编码方式 |
| apparent_encoding | 从内容中分析出的响应编码的方式(备选编码方式) |
| content | HTTP响应内容的二进制形式 |
1.对于服务器端来说,它返回给客户端的数据格式可分为非结构化和半结构化两种。
2.Python支持一些解析网页的技术,分别为正则表达式、XPath、Beautiful Soup和JSONPath。
3.正则表达式是基于文本的特征来匹配或查找指定的数据,它可以处理任何格式的字符串文档,类似于模糊匹配的效果。
4.XPath和Beautiful Soup 基于HTML/XML文档的层次结构来确定到达指定节点的路径,所以它们更适合处理层级比较明显的数据。
5.JSONPath 专门用于JSON文档的数据解析。
6.正则表达式,又称规则表达式,它是一个用于处理字符串的强大工具,通常被用来检索和替换那些符合规则的文本。
7.re模块的步骤
(1)使用compile()函数将正则表达式以字符串形式编译为一个Pattern类型的对象。(这一步可以省略,可以直接编写正则表达式)
(2)通过Pattern对象提供的一系列方法对文本进行匹配查找,得到一个或多个表示匹配结果的Match对象。
(3)使用Match对象提供的属性和方法获得信息,如匹配到的字符串。
8.使用正则表达式有如下步骤。
(1)寻找规律。
(2)使用正则符号表示规律。
(3)提取信息。
9.正则表达式中包含两个部分:一个是正则语法对应的字符,二个是普通字符。
| 元字符 | 功能说明 |
|---|---|
| . | 匹配除换行符以外的任意单个字符 |
| ***** | 匹配位于*之前的字符或子模式的0次或多次出现 |
| + | 匹配位于**+之前的字符或子模式的1****次或多次出现** |
| - | 在**[]**之内用来表示范围 |
| | | 匹配位于**|**之前或之后的字符 |
| ^ | 匹配行首,匹配以**^**后面的字符开头的字符串 |
| $ | 匹配行尾,匹配以**$**之前的字符结束的字符串 |
| ? | 匹配位于**?之前的0个或1个字符。当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是“非贪心的”。“非贪心的”模式匹配搜索到的、尽可能短的字符串****,而默认的“贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串“****oooo”****中,“****o+?”****只匹配单个“o”,而“****o+”****匹配所有“**o” |
| ** | 表示位于****之后的为转义字符 |
| \num | 此处的num是一个正整数,表示子模式编号。 |
| \f | 换页符匹配 |
| \n | 换行符匹配 |
| 元字符 | 功能说明 |
|---|---|
| \r | 匹配一个回车符 |
| \b | 匹配单词头或单词尾 |
| \B | 与**\b****含义相反** |
| \d | 匹配任何数字,相当于**[0-9]** |
| \D | 与**\d含义相反,等效于[^0-9]** |
| \s | 匹配任何空白字符,包括空格、制表符、换页符,与 [ \f\n\r\t\v] 等效 |
| \S | 与**\s****含义相反** |
| \w | 匹配任何字母、数字以及下划线,相当于**[a-zA-Z0-9_]** |
| \W | 与**\w含义相反\w含义相反,与“[^A-Za-z0-9_]”**等效 |
| () | 将位于**()**内的内容作为一个整体来对待 |
| {m,n} | {}前的字符或子模式重复至少m次,至多n****次 |
| [] | 表示范围,匹配位于**[]**中的任意一个字符 |
| [^xyz] | 反向字符集,匹配除x、y、z之外的任何字符 |
| [a-z] | 字符范围,匹配指定范围内的任何字符 |
| [^a-z] | 反向范围字符,匹配除小写英文字母之外的任何字符 |
| 方法 | 功能说明 |
|---|---|
| compile(pattern[, flags]) | 创建模式对象 |
| escape(string) | 将字符串中所有特殊正则表达式字符转义 |
| findall**(pattern, string[, flags])** | 返回包含字符串中所有与给定模式匹配的项的列表 |
| finditer(pattern, string, flags=0) | 返回包含所有匹配项的迭代对象,其中每个匹配项都是match对象 |
| fullmatch(pattern, string, flags=0) | 尝试把模式作用于整个字符串,返回match对象或****None |
| match(pattern, string[, flags]) | 从字符串的开始处匹配模式,返回match对象或****None |
| purge() | 清空正则表达式缓存 |
| search(pattern, string[, flags]) | 在整个字符串中寻找模式,返回match对象或****None |
| split(pattern, string[, maxsplit=0]) | 根据模式匹配项分隔字符串 |
| sub(pat, repl, string[, count=0]) | 将字符串中所有与pat匹配的项用repl替换,返回新字符串,repl可以是字符串或返回字符串的可调用对象,作用于每个匹配的match对象 |
| subn**(pat,** repl**, string[, count=0])** | 将字符串中所有pat的匹配项用repl替换,返回包含新字符串和替换次数的二元元组repl可以是字符串或返回字符串的可调用对象,作用于每个匹配的match****对象 |
13.flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
re.I 忽略大小写
re.X 为了增加可读性,忽略空格和 # 后面的注释
15.findall
16.什么是xpath
XPath即为XML路径语言,用于确定XML树结构中某一部分的位置。XPath技术基于XML的树结构,能够在树结构中遍历节点(元素、属性等)。
17.XPath使用路径表达式选取XML文档中的节点或者节点集,这些路径表达式代表着从一个节点到另一个或者一组节点的顺序,并以“/”字符进行分隔。
18.选取节点:节点是沿着路径选取的,既可以从根节点开始,也可以从任意位置开始。
| 表达式 | 说明 |
|---|---|
| nodename | 最快 |
| / | 快 |
| // | 慢 |
| . | 选取当前节点 |
| … | 选取当前节点的父节点 |
| @ | 选取属性 |
19.谓语:指路径表达式的附加条件。
元素[表达式]
20.选取未知节点:XPath可以使用通配符来选取未知的节点。例如,使用“*”匹配任何元素节点。
| 通配符 | 说明 |
|---|---|
| * | 匹配任何元素节点。 |
| @* | 匹配任何属性节点。 |
| node() | 匹配任何类型的节点。 |
21.选取若干路径:在路径表达式中可以使用“|”运算符,以选取若干个路径。
//book/title | //book/price
22.在测试表达式时,要查询的路径既可以从根节点开始,也可以从任何位置的节点开始,这个表示路径的语句并不是唯一的。
23.lxml是以Python语言编写的库,主要用于解析和提取HTML或者XML格式的数据,可以利用XPath语法快速地定位特定的元素或节点。
| 类 | 说明 |
|---|---|
| Element | 可以理解为XML的节点 |
| ElementTree | 可以理解为一个完整的XML文档树 |
| ElementPath | 可以理解为XPath,用于搜索和定位节点 |
25.为了能够将XML文件解析为树结构,etree模块中提供了如下三个函数:
(1) fromstring()函数:从字符串中解析XML文档或片段,返回根节点(或解析器目标返回的结果)。
(2)XML()函数:从字符串常量中解析XML文档或片段,返回根节点(或解析器目标返回的结果)。
(3)HTML()函数:从字符串常量中解析HTML文档或片段,返回根节点(或解析器目标返回的结果)。
26.除了上述三个函数之外,还可以调用parse()函数从XML文件中直接解析。
28.什么是Beautiful Soup
官网推荐现在的项目使用BeautifulSoup
(BeautifulSoup 4版本,简称为bs4)开发。bs4是一个HTML/XML的解析器,主要的功能是解析和提取HTML/XML数据。
29.bs4不仅支持CSS选择器,而且支持Python标准库中的HTML解析器,以及lxml的XML解析器。
| 类 | 说明 |
|---|---|
| bs4.element.Tag | 表示HTML中的标签,最基本的信息组织单元。 |
| bs4.element.NavigableString | 表示HTML中标签的文本(非属性字符串) |
| bs4.BeautifulSoup | 表示HTML DOM中的全部内容,支持遍历文档树和搜索文档树的大部分方法。 |
| bs4.element.Comment | 表示标签内字符串的注释部分,是一种特殊的NavigableString对象。 |
31.例如,根据字符串html_doc创建一个BeautifulSoup对象:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, ‘lxml’)
32.目前,bs4支持的解析器包括Python标准库、lxml和html5lib,它们的优势和劣势的比较如下。
| 解析器 | 使用方法 | 优势 | 劣势 |
|---|---|---|---|
| Python标准库 | BeautifulSoup(markup, “html.parser”) | 1)Python的内置标准库2)执行速度适中3)文档容错能力强 | Python 2.7.3或3.2.2之前的版本中文档容错能力差 |
| lxml HTML解析器 | BeautifulSoup(markup, “lxml”) | 1)速度快2)文档容错能力强 | 需要安装C语言库 |
| lxml XML 解析器 | BeautifulSoup(markup, [“lxml-xml”]) | 1)速度快2)唯一支持XML的解析器 | 需要安装C语言库 |
| html5lib | BeautifulSoup(markup, “html5lib”) | 1)最好的容错性2)以浏览器的方式解析文档3)生成HTML5格式的文档 | 1)速度慢2)不依赖外部扩展 |
34.每一条CSS样式定义均由两部分组成,形式如下:
35.BeautifulSoup类中提供了一个select()方法,该方法会将CSS选择器搜索到的结果放到列表中。
通过标签查找
通过组合查找
通过类名查找
通过属性查找
通过id名查找
1.什么是线程
线程是进程一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。
2.多线程爬虫流程分析
多线程爬虫将多线程技术运用在采集网页信息和解析网页内容上。(前面讲的是单进(线)程)
3.多线程爬虫流程如下:
4.Queue类简介
Queue类是Python标准库中的线程安全的队列实现,它提供了一个适用于多线程编程的先进先出的数据结构—队列,用于生产者和消费者线程之间的信息传递。
5.queue(队列)模块简介
queue模块是Python内置的标准模块,可以直接通过import queue引用,在Queue模块中提供了三种同步的、线程安全的队列。
其中,LifoQueue和PriorityQueue都是Queue的子类。这些队列的唯一区别是元素取出的顺序不同。
6.Queue类提供了数据存储和管理的常用方法。
| 方法 | 说明 |
|---|---|
| empty() | 如果队列为空,返回True,否则返回False |
| full() | 如果队列已满则返回True,否则返回False。 |
| get() | 从队头获取并删除第一个元素。 |
| put() | 在队尾添加一个元素。 |
| get_nowait() | 立即取出一个元素,不等待,相当于get(False)。 |
| put_nowait() | 立即放入一个元素,不等待,相当于put(item,False) |
| qsize | 队列中元素的个数 |
put与get方法是两个阻塞方法:put不到值程序夯住,get不到程序也夯住。
put_nowait与get_nowait方法是两个非阻塞方法:put_nowait没有值的话不等,get_nowait取不到值也不等了,程序不会夯住,但是一定要做异常处理!
夯住(Hang)是指程序仍在运行,卡在某个方法调用上,没有返回也没有异常抛出;卡住时间从几秒到几小时不等。
8.Queue类表示一个基本的FIFO(First In First Out)队列,即先进先出。
queue.Queue(maxsize=0)
其中,maxsize参数是个整数,它规定了队列的长度。一旦达到上限,再添加数据会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,表示队列大小没有限制。maxsize的默认值为0,如果不指定就没有限制。
9.LifoQueue类表示后进先出队列(Last in First Out),与栈类似,都是后进入的元素先出来。
queue.LifoQueue(maxsize=0)
其中,maxsize参数的含义与Queue类相同。
10.PriorityQueue类表示优先级队列,按级别顺序取出元素,级别最低的最先取出。优先级队列中的元素一般采取元组(优先级别,数据)的形式来存储。
queue.PriorityQueue(maxsize=0)
其中,maxsize参数的含义与前两个类相同。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQAWcN84-1653200262302)(C:\Users\31357\AppData\Roaming\Typora\typora-user-images\image-20220411183437024.png)]
12.除此之外,在Queue模块中还定义了2个异常类。
13.List,Dict等数据存储类型都是非线程安全的。在多线程中,为了防止共享资源的数据不同步问题,对资源加锁是个重要的环节。Queue类中实现了所有的锁逻辑,能够满足多线程的需求,所以在满足使用条件的情况下,建议使用队列。
14.线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
16.协程爬虫的流程分析
所谓协程,就是同时开启多个任务,但一次只顺序执行一个。等到所执行的任务遭遇阻塞,就切换到下一个任务继续执行,以期节省下阻塞所占用的时间。
17.协程爬虫的流程分析
由于协程的切换不像多线程调度那样耗费资源,所以不用严格限制协程的数量。
18.协程爬虫流程如下:
19.gevent是一个基于协程的Python网络库,是一个第三方库,可使用以下方法对它进行安装:
pip install gevent
20.gevent库的常用方法如下:
21.猴子补丁monkey_patch
1.什么是动态网页?什么又是静态网页呢?
2.AJAX技术介绍
3.获取动态网页数据的手段:
那些便用了AJAX或DHTML技术改变或加载内容的页面,可能有一些采集手段。但是用Python解决这个问题只有两种途径:
1.模拟JavaScript代码发送请求获取的应数据,但是有些数据参数是动态生成或加密后的(费时费力)。
2.用Python的第三方库控制浏览器,通过浏览器采集我们需要的数据(比较符合)。
4.JSON是比XML更简单的一种数据交换格式(前台与后台的数据交换),它采用完全独立于编程语言的文本格式来存储和表示数据。
5.JSON与XML语言比较
josn:
xml:
6.JSON的语法格式简单,层次结构清晰,比XML更易于阅读。另外,由于它占用的字符量少,用于网络数据传输时,能节约带宽,提高了传输效率。
7.JSONPath是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript,Python,PHP和Java。
8.JSONPath的安装方法如下:
pip install jsonpath
| XPath | JSONPath | 描述 |
|---|---|---|
| / | $ | 根节点(最外层的对象或数组) |
| . | @ | 现行节点 |
| / | .or[] | 取子节点 |
| … | n/a(不可以) | 取父节点,JSONPath未支持 |
| // | … | 就是不管位置,选择所有符合条件的节点 |
| * | * | 匹配所有元素节点 |
| @ | n/a(不可以) | 根据属性访问,JSON不支持,因为JSON是个key-value递归结构,不需要属性访问 |
| [] | [](从0开始) | 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
| | | [,] | 支持迭代器中做多选 |
| [] | ?(限定问号) | 支持过滤操作 |
| n/a | () | 支持表达式计算 |
| () | n/a(不可以) | 分组,JSONPath不支持 |
10.JSON数组
数组在JavaScript中是中括号[ ]括起来的内容,数据结构为 [字段1, 字段2, 字段3, …],其中字段值的类型可以是数字、字符串、数组、对象几种。
11.json模块提供了Python对象的序列化和反序列化功能。
12.json模块提供了四个方法:dumps、dump、loads、load,用于字符串和Python数据类型间进行转换。
13.其中,loads和load方法用于Python对象的反序列化,dumps和dump方法用于Python对象的序列化。
15.JSONPath是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript,Python,PHP和Java。
16.安装:
pip install jsonpath
17.JSONPath语法对比
| XPath | JSONPath | 描述 |
|---|---|---|
| / | $ | 根节点(最外层的对象或数组) |
| . | @ | 现行节点 |
| / | .or[] | 取子节点 |
| … | n/a(不可以) | 取父节点,JSONPath未支持 |
| // | … | 就是不管位置,选择所有符合条件的节点 |
| * | * | 匹配所有元素节点 |
| @ | n/a(不可以) | 根据属性访问,JSON不支持,因为JSON是个key-value递归结构,不需要属性访问 |
| [] | [](从0开始) | 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
| | | [,] | 支持迭代器中做多选 |
| [] | ?(限定问号) | 支持过滤操作 |
| n/a | () | 支持表达式计算 |
| () | n/a(不可以) | 分组,JSONPath不支持 |
18.Selenium是一个Web的自动化测试工具,可以按指定的命令自动操作,控制浏览器,支持所有主流的浏览器。
19.Selenium自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用,通过chrome driver 将selenium与chrome结合在一起。
20.PhantomJS 是一个基于Webkit的“无界面”浏览器,它会把网站加载到内存并执行页面上的JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器要高效。
21.Selenium的下载和安装有两种方式,第一种方式是手动从PyPI网站下载Selenium库然后安装。下载地址是:https://pypi.python.org/simple/selenium/。
22.下载最新版的selenium-x.xx.x.tar.gz安装包到本地,然后解压缩。打开终端来到解压后的setup.py文件所在目录,使用如下命令安装即可。
python setup.py install
23.第二种方式是直接使用第三方管理器pip命令自动安装,例如在Windows命令提示符中输入以下命令:
pip install selenium
24.selenium和chrome driver安装配置
(1)输入网址https://bitbucket.org/ariya/phantomjs/downloads/,可以看到PhantomJS的官网下载页面,选择自己电脑对应的版本下载即可。
(2)下载到本地后解压缩即可。点击【计算机】【属性】【高级系统设置】,进入系统属性界面,然后点击【高级】【环境变量】。
(3)在“系统变量”里找到Path,点击“编辑…”按钮。
(4)然后在变量值里添加phantomjs.exe文件所在的目录,例如,本书中将PhantomJS解压到D盘,那么使用的是D:\phantomjs-2.1.1-windows\bin目录。
25.如果不对PhantomJS进行配置,不将它的目录添加到系统路径,其实也可以在代码里使用,只需要显式地指定phantomjs.exe文件所在的目录即可。但是,这种方式使用相对麻烦,我们推荐使用第一种方法。
http://npm.taobao.org/mirrors/chromedriver/
注意 :chromedriver的版本要与你使用的chrome版本对应根据操作系统选择chromedrive文件。将下载好的chromedrive.exe文件,存放至python安装根目录(与python.exe文件同一目录)即可,这是最方便的一种。Selenium:免费的分布式的自动化测试工具
(1)导入webdriver
from selenium import webdriver
WebDriver是什么?它就是一层基础的协议规范,是一个支持浏览器自动化的工具。它包括一组为不同语言提供的类库和“驱动”(drivers)可以使浏览器上的动作自动化,是为作为浏览器与client(language binding)桥梁的作用。
(2)调用环境变量指定的Chrome浏览器创建浏览器对象。(selenium已不支持PhantomJS)
(3)获取页面内容。
driver.get(“http://www.baidu.com/”)
(4)生成当前页面,获取网页源码。
import
timeTime.sleep(5)
print(driver.page_source)
(5)退出驱动。
driver.quit()
28.获取页面名为wrapper的id标签的文本内容。
from selenium.webdriver.common.by import By
data = driver.find_element(By.ID,“wrapper”) .textprint(data)
28.对应关系
CLASS_NAME = 'class name ’
CSS_SELECTOR = ‘css selector’
ID = ‘id’ LINK_TEXT = ‘link text’
NAME = ‘name’
PARTIAL_LINK_TEXT = ‘partial link text’
TAG_NAME = ‘tag name’
XPATH = ‘xpath’
29.通过id="su"定位百度搜索按钮,然后通过click()方法模拟点击页面上的按钮。
driver.find_element (By.ID,“su”) .click()
30.调用键盘按键操作,首先引入Keys包。
from selenium.webdriver.common.keys import Keys
31.通过模拟Control + a 键全选输入框内容。
driver.find_element (By.ID,“kw”) .send_keys(Keys.CONTROL, ‘a’)
32.通过模拟Control + x 键剪切输入框内容,往输入框重新输入搜索关键字“python”:
driver.find_element (By.ID,“kw”).send_keys(Keys.CONTROL, ‘x’)
driver.find_element (By.ID,“kw”).send_keys(“python”)
33.模拟点击“Enter”回车键。
driver.find_element (By.ID,“kw”).send_keys(Keys.RETURN)
34.清除输入框内容,使用clear方法。
driver.find_element (By.ID,“kw”).clear()
35.使用get_cookies方法获取当前页面的Cookie。
print(driver.get_cookies())
36.使用current_url属性获取当前页面的URL。
print(driver.current_url)
37.使用close方法关闭当前页面,如果只有一个页面,会关闭浏览器。当浏览器使用完毕时,应使用quit方法关闭浏览器。
driver.close()
driver.quit()
38.定位UI元素
| 方法 |
|---|
| find_element(By.ID,“kw”) |
| find_elements(By.NAME, “element_name”) |
| find_elements(By.XPATH, "//*[@id=‘search’]“) |
| find_elements(By.LINK_TEXT, “element_link_text”) |
| find_elements(By.PARTIAL_LINK_TEXT, “element_partial_link_text”)(根据链接部分文本查找元素) |
| find_elements(By.TAG_NAME, “element_tag_name”) |
| find_elements(By.CLASS_NAME, “element_class_name”) |
| find_elements(By.CSS_SELECTOR, “element_css_selector”)(根据css选择器查找元素) |
39.keys
40.鼠标动作链
有些时候,我们需要在页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,这些可以通过使用ActionChains类来实现。
from selenium.webdriver import ActionChains
41.例子
#1、创建一个ActionChains(鼠标动作链)对象ActionChains(driver)
#2、将鼠标移动到鼠标的动作链中ActionChains(driver).move_to_element(news)
#3、将鼠标移动的动作添加到鼠标的动作链中ActionChains(driver).move_to_element(news).click(news)
#4、使用perform是执行动作链中的方法ActionChains(driver).move_to_element(news).click(news).perform()#news.click()
42.在selenium中可以设置窗口的大小
driver.set_window_size(水平,垂直)
driver.set_window_size(800,1200)
让窗口最大化driver.maximize_window()
43.例二
拖动滑块
from selenium import webdriverimport time
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
driver = webdriver.Chrome()#拖动某个网站的滑块#访问畅想谷的注册页面
driver.get("http://www.changxianggu.com/teacher/login/index.html")
#让窗口最大化
driver.maximize_window()
#1.定位滑块的位置
slide=driver.find_element(By.CLASS_NAME,'slide-to-unlock-handle')
print(slide.get_attribute('style'))
#2.移动鼠标到新闻'''2.1创建一个ActionChains(鼠标动作链)对象,将鼠标移动的动作添加到鼠标的动作链中,而没有执行perform是执行动作链中的方法#拖拽的偏移量#ActionChains(driver).move_to_element(slide).drag_and_drop_by_offset(开始位置,水平拖动,垂直拖动,).perform()
ActionChains(driver).drag_and_drop_by_offset(slide,330,0).perform()
time.sleep(10)
driver.quit()
44.填充表单
对于下拉框,Selenium专门提供了Select类来处理
from selenium.webdriver.support.ui import Select
45.对于下拉框,Selenium专门提供了Select类来处理,该类提供了三种选择下拉框的方式:根据索引选择、根据值选择以及根据文字选择。
select.select_by_index(1) # 根据索引选择
select.select_by_value(“0”) # 根据值选择
select.select_by_visible_text(u"未审核") # 根据文字选择
46.在选择下拉框的选项时要注意:
47.弹窗处理
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息,可以使用浏览器对象的switch_to_alert()方法。
alert = driver.switch_to_alert()已过时
推荐使用
alert = driver.switch_to.alert ,再用alert.text获取信息
最后关闭弹窗
alert.dismiss()
48.例
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
url =r'file:///C:/Users/Administrator/Desktop/%E6%96%B0%E5%BB%BA%E6%96%87%E6%9C%AC%E6%96%87%E6%A1%A3.html'
driver.get(url)
#1弹出窗框
#1.1 准备弹出窗口
Js="alert('呵呵')"
#1.2执行JS
driver.execute_script(Js)
time.sleep(5)
#2获取弹窗
#已过时
alert=driver.switch_to_alert()
#推介方式
#alert=driver.switch_to.alert
print(alert.text)
#点击取消
alert.dismiss()
#点击确定
alert.accept()
time.sleep(5)
driver.quit()
49.页面切换
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。
driver.switch_to.window(“this is window name”)
50.使用window_handles方法获取每个窗口的操作对象(窗口的name)。
for handle in driver.window_handles:
driver.switch_to_window(handle)
51.操作页面的前进和后退功能,使用forward和back方法。
driver.forward() # 前进
driver.back() # 后退
52.获取页面Cookies
可使用get_cookies方法获取页面上的所有Cookie。
for cookie in driver.get_cookies():
print("%s=%s;" % (cookie['name'], cookie['value']))
53.删除Cookies可以使用delete_cookie(根据Cookie名称删除)和delete_all_cookies(删除该页面的所有Cookie)方法。
# 根据Cookie名称删除
driver.delete_cookie("BAIDUID")
# 删除该页面上所有的Cookie
driver.delete_all_cookies()
54.页面等待
现在的网页越来越多采用了Ajax技术,这样程序便不能确定何时某个元素能被完全加载出来了。如果实际页面响应时间过长,导致某个页面元素还没出来,就被代码引用,那么就会抛出NullPointer的异常。
55.Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。
56.显式等待指定某个条件,然后设置最长等待时间。如果这个时间结束时还没有找到元素,那么便会抛出异常了。
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(driver, timeout, poll_frequency=0.5,ignored_exceptions=None)
#driver参数表示WebDriver的驱动程序;
#timeout表示最长超时时间,可以不指定;
#poll_frequency参数表示休眠时间的间隔(步长)时间;每隔多久判断一下条件
#ignored_exceptions参数表示超时后的异常信息。这个很少用
57.WebDriverWait类的对象一般与unit或until_not方法配合使用
59.隐式等待就是设置一个全局的最大等待时间,单位为秒。在定位元素时,对所有元素设置超时时间,超出了设置时间则抛出异常。
1.OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程;
2.OCR字符识别技术的应用场景OCR字符识别技术广泛应用于银行票据、文献资料录入和处理领域。适合于银行、税务等行业大量票据表格的自动扫描识别及长期存储。在机器视觉领域,OCR同样具有多方面的应用,通过工业相机、工业镜头拍摄文字图像,运用机器视觉软件进行相应处理以获取我们需要的信息,常见的应用有:
3.Tesseract引擎的下载和安装
Tesseract(google开发)是一个开源的OCR库,它是公认最优秀、最精确的开源OCR系统,具有精准度高、灵活性高等特点。通过训练可以识别出任何字符(风格不变),能够识别出任何unicode字符。
(1)打开网址https://github.com/UB-Mannheim/tesseract/wiki,进入下载界面。
(2)下载完成后,双击安装文件,按照默认设置进行安装,安装后设置环境变量。
(3)打开命令行窗口,输入tesseract命令进行验证。如果安装成功,则会输出如下信息。
5.在Tesseract的安装目录下,默认有个tessdata目录,该目录中存放的是语言字库文件。
6.pytesseract库简介
Python提供了一个支持Tesseract-OCR引擎的pytesseract库,可以通过import语句引入使用。
7.image_to_string(image, lang=None, boxes=False, config=None)
参数如下:
8.PIL(python image library)是Python最常用的图像处理库,它不仅提供了广泛的文件格式(jpeg,png,gif,bmp,tiff)支持,而且具有强大的图片处理功能。
| 方法或函数 | 描述 |
|---|---|
| new()函数 | 用于创建一个新图篇 |
| open(fp,mode=“r”)函数 | 可以打开并识别给定的图像文件,mode一般不指定,只有一个参数 |
| save(fp)方法 | 以特定的图片格式保存图片 |
| point()方法 | 可以对图像的像素值进行变换 |
10.new函数:用于创建一个新图像
Image.new(mode, size, color=0)
11.open函数:可以打开并识别给定的图像文件
open(fp, mode=“r”)
12.save方法:以特定的图片格式保存图片
save(self, fp, format=None, **params)
13.point方法:对图像的像素值进行变换(用于对图片进行调色)
point(self, lut, mode=None)
14.读取图像中格式规范的文字
15.验证码分类
验证码是一种区分用户是计算机和人的公共全自动程序,能够有效阻止自动脚本反复提交垃圾数据,成为了很多网站通行的方式。
16.通常情况下,验证码的处理思路为:
1.爬虫的数据存储可分为如下两种方式:
2.MongoDB:一个基于分布式文件存储的数据库,是当前NoSQL(非关系型的数据库)数据库中比较热门的一种。它面向集合存储,易存储对象类型的数据,具有高性能、易部署、易使用等特点。
3.MongoDB是(c++编写的)一款基于分布式文件存储的NoSQL数据库,具有免费、操作简单、面向文档存储等强大特点,旨在为Web应用提供可扩展的高性能数据存储解决方案。
4.Windows平台安装MongoDB数据库
5.当下次打开电脑时,无需再次输入配置和启动命令,可以直接进入MongoDB安装目录下的bin目录下,双击“mongo.exe”打开数据库的交互窗口(mongo shell)即可。
| SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
|---|---|---|
| database | database | 数据库 |
| table | collection | 数据库表/集合 |
| row | document | 数据记录行/文档 |
| column | field | 数据字段/域 |
| index | index | 索引 |
| table joins | 表连接/MongoDB不支持 | |
| primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
7.use mytest 切换数据可
show collections 查看mytest中的所有集合创建一条文档,生成一个集合
8.文档(Document): 一组由键/值对组成的对象,对应着关系型数据库的行。
9.集合(Collection): 集合就是一组文档,类似于关系数据库中的表。
10.什么是PyMongo
PyMongo是用于MongoDB的开发工具,是Python操作MongoDB数据库的推荐方式。
11.PyMongo库的基本使用流程如下:
12.在Windows系统下,使用pip命令安装第三方库PyMongo,如下所示。
pip install pymongo
13.创建一个MongoClient类的对象,用于连接MongoDB服务器,构造方法的语法格式如下:
class pymongo.mongo_client.MongoClient(host=‘localhost’, port=27017, document_class=dict, tz_aware=False, connect=True, **kwargs)
参数如下: host – 表示主机名或IP地址。 port – 表示连接的端口号。
14.往集合中插入文档的方法主要有如下两个:
insert_one()方法:插入一条文档对象。
insert_many()方法:插入列表形式的多条文档对象。
15.用于查找文档的方法主要有如下几个:
find_one()方法:查找一条文档对象。
find_many()方法:查找多条文档对象。(这个已经没有了)
find()方法:查找所有文档对象。返回一个Cursor对象需使用for 遍历查看
16.用于更新文档的方法主要有如下几个:
update_one()方法:更新一条文档对象。
update_many()方法:更新多条文档对象。
17.用于删除文档的方法包括如下几个:
delete_one(过滤条件)方法:删除一条文档对象。
delete_many(过滤条件)方法:删除所有记录。
18.实际上,使用pymongo库操作数据库是非常简单的,以后要是碰到更加复杂的需求,在网络上查一下官方文档或者技术博客,应该都能顺利解决。
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
(本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展 是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。 如:有三个人,每个人做的不同的事物,但是是需要协作的完成。 而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据