爬虫
1.网络爬虫的定义:
一个已经写好的脚本,用来自动的抓取互联网信息的脚本。
2.爬虫可以解决的问题:
(1)解决冷启动问题
(2)搜索引擎就是基于爬虫的
(3)建立知识图谱,帮助建立机器学习知识图谱
(4)可以制作各种商品的比价软件,趋势分析
初级爬虫工程师
1.web 前端的知识: HTML、CSS、JavaSc1ipt、 DOM、 DHTML 、Ajax、jQuery、json 等;
2、正则表达式, 能提取正常一般网页中想要的信息,比如某些特殊的文字, 链接信息, 知道什么是懒惰, 什么是贪婪型的正则;
3、会使用 XPath 等获取一些DOM 结构中的节点信息;
4、知道什么是深度优先, 广度优先的抓取算法, 及实践中的使用规则;
5、能分析简单网站的结构, 会使用urllib或requests 库进行简单的数据抓取。
中级爬虫工程师:
1、了解什么事HASH,会简单地使用MD5,SHA1等算法对数据进行HASH一遍存储
2、熟悉HTTP,HTTPS协议的基础知识,了解GET,POST方法,了解HTTP头中的信息,包括返回状态码,编码,user-agent,cookie,session等
3、能设置user-agent进行数据爬取,设置代理等
4、知道什么事Request,什么事response,会使用Fiddler等工具抓取及分析简单地网络数据包;对于动态爬虫,要学会分析ajax请求,模拟制造post数据包请求,抓取客户端session等信息,对于一些简单的网站,能够通过模拟数据包进行自动登录。
5、对于一些难搞定的网站学会使用phantomjs+selenium抓取一些动态网页信息
6、并发下载,通过并行下载加速数据爬取;多线程的使用。
高级爬虫工程师:
1、能够使用Tesseract,百度AI,HOG+SVM,CNN等库进行验证码识别。
2、能使用数据挖掘技术,分类算法等避免死链。
3、会使用常用的数据库进行数据存储,查询。比如mongoDB,redis;学习如何通过缓存避免重复下载的问题。
4、能够使用机器学习的技术动态调整爬虫的爬取策略,从而避免被禁IP封禁等。
能使用一些开源框架scrapy,scrapy-redis等分布式爬虫,能部署掌控分布式爬虫进行大规模数据爬取。
搜索引擎:
搜索引擎的组成:
通用爬虫:
通过url将整个网页爬取下来,保存在本地
通用爬虫要想爬取网页,需要网站的url.但是搜索引擎是可以搜索所有网页的。那么通用爬虫url就要涉及到所有网页,这个‘所有’是如何做到的。
1.新网站向搜索引擎主动提交网址
2.在其他网站上设置新网站外链。
3、搜索引擎和DNS解析服务商(如DNSPod等)合作,新网站域名将被迅速抓取。
搜索引擎的工作流程:
1.抓取网页
通过将待爬取的url加入到通用爬虫的url队列中,进行网页内容的爬取。
2.数据存储
将爬取下来网页保存到本地。这个过程中会有一定的去重操作。如果某个网页的内容大部分重复,搜索引擎可能不会保存。
3.数据预处理
提取文字
中文分词
消除噪音(比如版权声明文字、导航条、广告等……)
索引处理
4.提供检索服务,设置网站排名
搜索引擎的局限性:
1.搜索引擎只能爬取原网页,很多内容对用户都是无用的
2.不能满足特定的需求
3.通用引擎只能处理文字,对于视频,文件,音频都是无法提取的
4.大多数都是基于关键字的查询,无法基于语义来查询
聚焦爬虫
准备工作:
1.robots协议(机器人协议)
网络爬虫排除标准
那些可以爬取,哪些不可以爬取
2.sitemap:
网站地图
可以指导我们查看我们查看该网站下的有哪些网页
3.估算网站的大小
在百度搜索栏:site:url
出现该url下的网页个数
4.了解技术架构
pip install builtwith
命令行:Builtwith.parse(“url”)
返回基本架构
http/https
1.http协议、https协议
http:超文本传输协议
是一个规范,约束发布和接受html页面的规范。
https:是http的安全版,在http下加入了ssl层
2.端口号
http:80
https:443
3.https协议的特点:
(1)是一个应用层的协议
(2)无连接
每次的请求都是独立的
但请求并没有断掉,是因为:http 1.1 增加了一个Connection: keep-alive,这个头表示,客户端和服务器的连接是一个长连接。
(3)无状态
无状态表示每次请求都不能记录请求的状态,也就是两条请求之间无法进行通信。
cookie和session可以帮助记录状态
4.url:统一资源定位符
为什么可以通过url来定位互联网上的任意资源?
http://ip:port/path
ip:可以定位电脑
port:端口号—用来从互联网上进入电脑。
path:就是为了在电脑中找到对应的资源路径。
有三种特殊符号
?:问好后面就是请求参数。?username=‘zhangsan’&password=‘123’
&:请求参数用&连结。?username=‘zhangsan’&password=‘123’
#:表示锚点:锚点就是在请求这个url时,页面会跳入锚点指定位置。
基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]
scheme:协议(例如:http, http, ftp)
host:服务器的IP地址或者域名
port:服务器的端口(如果是走协议默认端口,缺省端口80)
path:访问资源的路径
query-string:参数,发送给http服务器的数据
anchor:锚(跳转到网页的指定锚点位置)
5.http的工作流程
(1)地址解析。将url解析出相对应的内容
scheme:协议(例如:http, http, ftp)
host:服务器的IP地址或者域名
port:服务器的端口(如果是走协议默认端口,缺省端口80)
path:访问资源的路径
query-string:参数,发送给http服务器的数据
anchor:锚(跳转到网页的指定锚点位置)
(2)封装http请求数据包
(3)封装成TCP包,建立TCP连接(TCP的三次握手)
TCP握手协议
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
SYN:同步序列编号(Synchronize Sequence Numbers)
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
(4)客户端发送请求
(5)服务器返回响应
(6)服务器关闭TCP连接
6.当在浏览器输出一个url,为什么可以加载出一个页面?
为什么,在抓包的过程中,请求了一个url,会出现很多的资源请求?
(1)当我们在浏览器输入一个url,客户端会发送这个url对应的一个请求到指定服务器获取内容。
(2)服务器收到这个请求,解析出对应的内容,之后将内容封装到响应里面发送给客户端。
比如index.html页面。
(3)当客户端拿到这个html页面,会查看这个页面中是否有css、js、image等url,如果有,在分别进行请求,获取到这些资源。
(4)客户端会通过html的语法,将获取到的所有内容完美的显示出来。
7.客户端请求
(1)组成:
请求行、请求头部、空行、请求数据四个部分组成
(2)请求方法get/post
1.get请求:
get获取—>从服务器上获取资源—>通过参数来告诉服务器需要获取什么资源—>请求参数是在?后面,在url中用&拼接的—>明文显示不安全—>传输参数大小受限
2.post请求:
post,传递—>向服务器传递参数—>数据是封装在请求的实体—>可以传递更多的内容—>更安全
3.get和post的区别
(1)get是从服务器获取内容,post是向服务器传递内容
(2)get不安全,因为参数拼接在url后面。post比较安全,因为参数是放在是实体里面。
(3)get传参大小受限,post不受限。
(3)重要的请求头:
User-Agent:客户端请求标识(浏览器的一些信息)
referer:表示是从哪个网页跳转到当前所在的网页
cookie:在做登录的时候需要封装这个头
Accept:允许传输的数据类型
发送post请求的参数:
Content-Type(POST数据类型)
Content-length:发送表单的长度
X-Ruquestd-With:表示Ajax异步请求
8.http响应:
1.组成:响应行,响应头、空行、响应数据
2.重要的响应头:
Content-Type:text/html;charset=UTF-8;
告诉客户端,资源文件的类型,还有字符编码
3.状态码:
100~199:表示服务器成功接收部分请求,要求客户端继续提交其余请求才能完成整个处理过程。
200~299:表示服务器成功接收请求并已完成整个处理过程。常用200(OK 请求成功)。
300~399:为完成请求,客户需进一步细化请求。例如:请求的资源已经移动一个新地址、常用302(所请求的页面已经临时转移至新的url)、307和304(使用缓存资源)。
400~499:客户端的请求有错误,常用404(服务器无法找到被请求的页面)、403(服 务器拒绝访问,权限不够—DDos)。
500~599:服务器端出现错误,常用500(请求未完成。服务器遇到不可预知的情况)。
hash加密
给一个字符串加密
import hashlib
#1.给一个字符串进行加密
def get_hex(value):
#1.c创建一个加密对象
md5_ = hashlib.md5()
#2.将需要加密的内容update到md5对象中
#将字符串转化成bytes类型两种方法:
#str.encode('utf-8')
#bytes(str,encoding='utf-8')
md5_.update(value.encode('utf-8'))
#3.获取加密内容
return md5_.hexdigest()
给一个文件加密
def get_file_hex(filename):
#规定文件读取的字节
chunk_size=1024
#实例一个对象
md5=hashlib.md5()
with open(filename,'r',encoding='utf-8) as f:
chunk=f.read(chunk_size)
if chunk:
md5.update(chunk.encode("utf-8"))
return md5.hexdigest()