网络爬虫是一个程序,可以自动,批量,下载,保存网络资源。css
网络爬虫是假装成客户端与服务端运行数据交互的程序。html
- c / s client / server 客户端/服务端python
- b / s browser 浏览器git
- m / s mobile 移动端github
#*Client发送数据请求给Server,Server接收请求并处理返回一个包含结果的响应体给Client*#web
1.http协议又称为超文本传输协议.(从服务器传输数据到客户端,客户端是没有数据的,都是从服务器下载过来的)正则表达式
2.http完整事务流程:数据库
1.浏览器输入请求网址url,dns(域名解析成惟一的IP地址,找到服务器)json
2.底层协议(TCP/IP链接),三次握手。api
3.客户端发送HTTP请求报文。
4.服务端收到并处理请求,返回一个包含结果的响应。
5.浏览器对响应结果进行渲染和展现。
完整报文(四部分):请求行 , 请求头 , 空行 , 请求数据/请求体
#请求方法-http协议及版本-空格换行-Host(主机):-www.??.com(域名和端口,端口已隐藏)-空格换行空格换行# Get请求不要数据
1. 请求方法
1.0版本 - get post head
1.1版本 - 如图
2. 请求头
'名称 + : + 空格 + 值 '
3. 响应
状态行 , 消息报头 , 空行 , 响应正文
4. 响应状态码(5种类型,3位整数)
5. 响应报头
cookie , session
cookie:凭证,将信息存于客户端,不安全
session:会话,基于Cookie,将信息存于服务端
#Session#
在Requests中,实现了Session(会话)功能,当咱们使用Session时,可以像浏览器同样,在没有关闭浏览器时,可以保持访问状态.经常使用于登陆以后的数据获取.
1 import requests 2 session =requests.Session() 3 4 session.get('http://httbin.org/cookies/set/sessioncookie/123456789') 5 resp = session.get('http://httbin.org/cookies') 6 7 print(resp.text) 8 9 #设置整个headers---若是在get()方法中传入headers和cookies等数据,只有1次有效,想要整个生命周期有效,须要如下方法设置 10 session.headers = { 11 'user-agent':'my-app/0.0.1' 12 } 13 #增长一条headers 14 session.headers.updatedate({'x-test':'true'})
网络资源:只有经过互联网访问到的资源就叫网络资源。
统一资源定位符,网址,惟一标识
http缺陷:发送传输数据是明文,在隐私数据方面不安全.
依托于http,ssl?TCL 协议
- ca证书
- 加密
- 标准端口:80(http) 443(https)
- ↓(密钥每次都会从新生成,没法破解)
到网络上爬取资源,双方数据交互,上网时查看互联网数据,互联网同时采集本身的信息数据.
全部搜索引擎都是爬虫,不分日夜到互联网爬取网页头存在本身的资源里.
对于重复的操做,例如贴吧的灌水,水军,可使用爬虫实现.
过年火车一票难求,能够实现抢票功能,让这个程序一直帮我抢票.360抢票就是爬虫实现的
目的:找到目标资源的http请求。具体指标:
1. 请求方法
2. url
3. 请求头
4. 请求数据(参数)
#*工具(抓包)
fiddler,安装复杂,使用也比较复杂.对于google抓不到的,可使用fiddler解决.
谷歌浏览器,按F12开启调试者模式(Ctrl+Shift+I)
1 from socket import socket 2 3 #建立一个客户单端 4 client = socket() 5 6 #链接服务器 7 client.connect(('www.baidu.com',80)) 8 9 #构造http请求报文 10 data =b'GET / HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n' 11 12 #发送报文 13 client.send(data) 14 15 #接收响应 16 res = b'' 17 temp = client.recv(1024)#接收数据每次1024字节 18 print('*'*20) 19 while temp: 20 res += temp 21 temp = client.recv(1024) 22 23 print(res)#请求演示 24 client.close()
2.2 工具库
1. urllib python标准库,(专用于)网络请求的
2. urllib3 基于python3,牛人开发
3. requests 简单易用,牛逼
2.3 requests
简单介绍:转为人类而构建,优雅和简单的python库,也是有史以来下载次数软件python包之一,下载次数天天超过40w/次
1 import requests #很是简单明了,易用 2 resp = requests.get('https://baidu.com') 3 #网页状态码 4 resp.status_code 5 #按字典取得值 6 resp.headers['content-type'] 7 #获取字符编码类型 8 resp.encoding 9 #获取文本 10 resp.text
Requests目前基本上彻底知足web请求的全部需求,如下是Requests的特性:
1 1. Keep-Alive & 链接池 2 2. 国际化域名和URL 3 3. 带持久Cookie的会话 4 4. 浏览器式的SSL认证 5 5. 自动内容解码 6 6. 基本/摘要式的身份认证 7 7. 优雅的key/value Cookie 8 8. 自动解压 9 9. Unicode响应体 10 10. HTTP(S)代理支持 11 11. 文件分块上传 12 12. 流下载 13 13. 链接超时 14 14. 分块请求 15 15. 支持 .netrc
Requests的安装:pip install requests ##(pip list 可查看已安装库)##
1 #Requests发起请求--请求方法 2 import requests 3 resp = requests.get('https://baidu.com') 4 #Post请求 5 resp = requests.post('http://httpbin.org/post',data={'key':'value'}) 6 #其余请求类型 7 resp = requests.put('http://httpbin.org/put',data={'key':'value'}) 8 resp = requests.delete('http://httpbin.org/delete') 9 resp = requests.head('http://httpbin.org/get') 10 resp = requests.options('http://httpbin.org/get') 11 #传递URL参数 12 import requests 13 params = {'key1':'value1','key2':'value2'} 14 resp =requests.get('http://httpbin.org/get',params=params) 15 #自定义Headers 16 url = 'https://api.github.com/some/endpoint' 17 headers = {'user-agent':'my-app/0.0.1'} 18 resp = requests.get(url,headers=headers) 19 #自定义Cookies 20 url='http://httpbin.org/cookies' 21 cookies={'cookies_are':'working'} 22 resp = requests.get(url,cookies=cookies) 23 resp.text 24 #设置代理 25 proxies={ 26 'http':'http://10.10.1.10:3128', 27 'https':'http://10.10.1.10:1080' 28 } 29 requests.get('http://example.org',proxies=proxies) 30 #重定向 31 resp = requests.get('http://github.com',allow_redirects=False) 32 resp.status_code 33 #禁止证书验证,默认sure 34 resp = requests.get('http://httpbin.org/post',verify=False) 35 #设置禁用证书出现的warning关闭方法 36 from requests.packages.urllib3.exceptions import InsecureRequestWarning 37 #禁用安全请求警告 38 requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 39 40 #设置超时 41 requests.get('http://github.com',timeout=0.001) 42 #响应内容 43 resp.text 44 #状态码 45 resp.status_code 46 #响应报头 47 resp.headers 48 #服务器返回的cookies 49 resp.cookies 50 #url 51 resp.url
3. 获取响应内容
利用socket下载一张图片,较麻烦,基础
1 #经过socket 下载一张图片 2 from socket import socket 3 4 #建立客户端 5 client = socket() 6 img_url = 'http://pic22.nipic.com/20120725/9676681_001949824394_2.jpg' 7 8 #链接服务器 9 client.connect(('pic22.nipic.com',80)) 10 11 #构建请求报文 12 data = b'GET /20120725/9676681_001949824394_2.jpg HTTP/1.0\r\nHost: pic22.nipic.com\r\n\r\n' 13 14 #发送请求 15 client.send(data) 16 17 #接收响应 18 res= b'' 19 temp =client.recv(1024) 20 21 while temp: 22 res += temp 23 temp =client.recv(1024) 24 25 headers,img_data=res.split(b'\r\n\r\n')#自动分割字符串 26 27 #保存图片 28 with open(r'C:\Users\luowe\Desktop\test.jpg','wb') as f: 29 f.write(img_data) 30 31 print('完成')
利用requests下载一张图片,简单粗暴
1 #经过requests 下载一张图片 2 import requests 3 4 img_url = 'http://pic22.nipic.com/20120725/9676681_001949824394_2.jpg' 5 6 #接收响应 7 response = requests.get(img_url) 8 #保存图片 9 with open(r'C:\Users\luowe\Desktop\test.jpg','wb') as f: 10 f.write(response.content) 11 print('完成')
4. 解析内容
响应体:文本(text) , 二进制数据(content)
文本:html , json , (js , css)
1. html解析
2. 正则表达式
3. beautiful soup
4. xpath
#json解析--jsonpath#
1. 写文件
2. 写数据库
1. 请求头反爬(UA,用户代理)
2. cookie(set-cookie,较麻烦,requests直接完爆它)
3. 验证码(点触,加减,扭曲,文字,滑动,语音等)
4. 行为检测(用户点击频率,停留时间经过时间和行为来判断视为爬虫.)
5. 参数加密(MD5加密和其余加密方式)
6. 字体反爬(服务端用本身的字体对某些数据加密,解密有些困难)
1. 并发--多线程,多进程同时爬取
2. 异步--?
3. 分布式--爬虫会监测IP,若是同一个IP访问次数过多,服务端就会考虑封IP,爬虫分布在不一样的电脑上一块儿爬取.
正则表达式是对字符串操做的一种逻辑公式,就是用事先定义好的一些特定字符·及这些特定字符的组合,组成一个"规则字符串",这个'规则字符串
'用来表达对字符串的一种过滤逻辑.
1. 灵活性,逻辑性和功能性很是强;
2. 能够迅速地用极简单的方式达到字符串的赋值控制;
3. 对于刚接触的人来讲,比较晦涩难懂.
1.普通字符(区分大小写) --->例如'testing' 能匹配testing.testing123,不能匹配Testing
2.元字符 --->. ^ $ * + ? { } [ ] | ( ) \
re模块使Python 语言拥有所有的正则表达式功能
re.match 尝试从字符串的起始位置匹配一个模式,若是不是起始位置匹配成功, match() 就返回none.
re.match(pattern , string , flags=0)
re.search 扫描整个字符串并返回第一个成功的匹配
re.search(pattern , string , flags = 0)
re.match 只匹配字符串的开始,若是字符串开始不符合正则表达式,则匹配失败,函数返回None; 而re.search 匹配整个字符串,直到找到第一个匹配.
Python的re 模块提供了re.sub 用于替换字符串中的匹配项.
re.sub(pattern , repl , string , count=0 , flags=0)
在字符串中找到正则表达式所匹配的全部子串,并返回一个列表,若是没有找到匹配的,则返回空列表.
# match 和 search是只匹配一次,, findall匹配全部
re.findall(pattern , string , flags=0)
compile 函数用于编译正则表达式, 生成一个正则表达式( Pattern )对象, 供match() 和 search() 这两个函数使用.
re.compile(pattern[ , flags])
正则表达式能够包含一些可选标志修饰符来控制匹配的模式.修饰符被指定为一个可选的标志.多个标志能够经过安位 OR( | ) 它们来指定. 如re.I | re.M 被设置成I 和 M标志.
1 import re 2 import requests 3 4 page_url='http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1571210386205_R&pv=&ic=&nc=1&z=&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=妹子&f=3&oq=meiz&rsp=0' 5 6 #下载页面的html 7 response = requests.get(page_url) 8 html = response.text 9 10 #解析出图片的url 11 res = re.findall(r'"thumbURL":"(.*?)"',html) 12 #下载图片 13 #假装成浏览器 14 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36' 15 ,'Referer':'image.baidu.com'} 16 for index,url in enumerate(res): 17 response = requests.get(url,headers=headers) 18 #写图片 19 with open(r'C:\Users\luowe\Desktop\爬图\%s.jpg'%index , 'wb') as f: 20 f.write(response.content) 21 print(url)