01 基本原理
一、爬虫是什么
首先思考一下爬虫到底是个什么东西呢?
当然不可能是下面这个可爱得小东西啦
1.什么是爬虫
爬虫实际上就是伪造浏览器向服务器发送请求
2. 什么是互联网
互联网是由网络设备(网线,路由器,交换机,防火墙等等)
和一台台计算机连接而成,像一张网一样。
3.互联网建立得目的
互联网的核心价值在于数据的共享/传递
数据是存放于一台台计算机上的,而将计算机互联到一起的目的就是为了能够方便彼此之间的数据共享/传递,否则你只能拿U盘去别人的计算机上拷贝数据了。
4.什么是上网?爬虫要做得是什么?
我们所谓的上网便是由用户端计算机发送请求给目标计算机,将目标计算机的数据下载到本地的过程。
用户上网获取网络数据得方式是:
浏览器提交请求--下载网页代码--解析/渲染
爬虫程序:
模拟浏览器发送请求--下载网页代码--只提取有用得数据--存放于数据库或文件中
5.浏览器和爬虫的区别
爬虫程序是只提取网页代码中对我们有用的数据
6.总结爬虫:
如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的猎物/数据
二、爬虫的基本流程
1、发起请求
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等
2、获取响应内容
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等
3、解析内容
解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等
解析json数据:json模块
解析二进制数据:以b的方式写入文件
4、保存数据
数据库MySQL/redis/Mongodb
文件file
三、请求与响应
以百度为例
http协议:http://www.baidu.com
Request:用户通过浏览器(socket client)发送请求给服务器(socket server)
Response:服务器接收请求,分析用户发来的请求信息,然后返回数据(返回的数据中可能包含其他链接,如:图片,js,css等)
ps:浏览器在接收Response后,会解析其内容来显示给用户
爬虫程序在模拟浏览器发送请求然后接收Response后,是要提取其中的有用数据。
四、Request请求
1、请求方式:
常用的请求方式:GET,POST
其他请求方式:HEAD,PUT,DELETE,OPTHONS
ps:用浏览器演示get与post的区别,(用登录演示post)
post与get请求最终都会拼接成这种形式:k1=xxx&k2=yyy&k3=zzz
post请求的参数放在请求体内:可用浏览器查看,存放于form data内
get请求的参数直接放在url后
2、请求url
url全称统一资源定位符,如一个网页文档,一张图片
一个视频等都可以用url唯一来确定
url编码
https://www.baidu.com/s?wd=图片
图片会被编码(看示例代码)
网页的加载过程是:
加载一个网页,通常都是先加载document文档,
在解析document文档的时候,遇到链接,则针对超链接发起下载图片的请求
3、请求头
User-agent:请求头中如果没有user-agent客户端配置,
服务端可能将你当做一个非法用户
host
cookies:cookie用来保存登录信息
refer
location
一般做爬虫都会加上请求头
4、请求体
如果是get方式,请求体没有内容
如果是post方式,请求体是format data
ps:
1、登录窗口,文件上传等,信息都会被附加到请求体内
2、登录,输入错误的用户名密码,然后提交,就可以看到post,正确登录后页面通常会跳转,无法捕捉到post
4.1模拟浏览器访问百度首页
import requests
''' 请求百度首页 '''
# 请求url
url = 'https://www.baidu.com'
# 伪装浏览器请求头
baidu_home_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}
# 发送get请求百度首页
response = requests.get(url,headers=baidu_home_headers)
print(response.status_code) # 响应内容的状态码
print(response.text) # 响应内容
4.2 模拟百度搜索
首先我们先真实的浏览器访问一下百度搜索的接口
根据上图我们可以找到访问的接口
https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%B0%8F%E7%8B%97&rsv_pq=f222e7ac000523a5&rsv_t=7968MXDKtP7gbrsNe0OmOHJRV%2FPMw42sN03VrBzYXFpRQcwLZZt%2B%2FAGxFUo&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=16&rsv_sug1=27&rsv_sug7=101&rsv_sug2=0&inputT=7764&rsv_sug4=9234
# 根据上面的接口来看,我们可以发现上述接口中有很多事请求携带的参数,并不是所有都需要
真正的访问接口:
#这里我们又会发现我们在搜索框中输入的关键字转换成了二进制(这个后面我们会说明)
# 示例代码
import requests
# 请求url
url = 'https://www.baidu.com/s?wd=%E5%B0%8F%E7%8B%97'
# 伪装浏览器请求头
baidu_home_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}
# 发送get请求百度首页
response = requests.get(url,headers=baidu_home_headers)
print(response.status_code) # 响应内容的状态码
print(response.text) # 响应内容
# 在这里我们会发现我们得到的结果是乱码的,为什么?
baidu_home_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3'
}
response = requests.get(url,headers=baidu_home_headers)
print(response.status_code) # 响应内容的状态码
print(response.text) # 响应内容
# 这里我们在去请求访问的时候,我们得到的响应结果就是正确的了
#持久化存储
with open('dog.html','w',encoding='utf8') as fw:
fw.write(response.text)
基于以上的请求我们发现我们只是以一个搜索词为例的
1. 如果我们想要换一个搜索词改怎么做?
方式一:直接修改url
from urllib.parse import urlencode
url = 'https://www.baidu.com/s?' + urlencode({'wd':'小狗'})
方式二:请求时携带params参数
response = requests.get(url,headers=baidu_home_headers,params={'wd':'小狗'})
五、Response
1、响应状态
200:代表成功
301:代表跳转
404:文件不存在
403:权限
502:服务器错误
2、Respone header
set-cookie:可能有多个,是来告诉浏览器,把cookie保存下来
3、preview就是网页源代码
最主要的部分,包含了请求资源的内容
如网页html,图片
二进制数据等
六、总结
1.总结爬虫流程
发送请求---得到数据/解析---持久化存储
2.请求头需要注意携带的参数
headers
Accept
Cookie
Host
User-Agent(重要--一定要带)
Referer
3.爬虫所需要的工具
请求库:requests,selenium
解析库:re,beautifulsoup,xpath
存储库:file,MySQL,Mongodb,Redis
4.爬虫常用框架
scrapy