01.浏览器
# 一个网页的加载全过程
1. 服务器端渲染
html的内容和数据在服务器进行融合.
在浏览器端看到的页面源代码中. 有你需要的数据
2. 客户端(浏览器)渲染
html的内容和数据进行融合是发生在你的浏览器上的.
这个过程一般通过脚本来完成(javascript)
我们通过浏览器可以看到上述加载过程
# 数据在浏览器的位置:
network ---> All 或 Fetch/XHR 或 JS # 99%只会在这三个里
02.requests
# requests模块
是python的一个非常完善的一个第三方模块,专门用来模拟浏览器进行网络请求的发送
# 本质就是 模拟成浏览器的样子
# url:
协议 域名 端口(80) 资源文件路径 参数
http://www.baidu.com/s?name=alex&age=185
https://www.baidu.com/s?name=alex&age=185
# 发送get请求
# 参数类型:query string parameteres
# 方式: params 和 url传参. 二选一即可
requests.get("https://www.baidu.com/s?ie=UTF-8&wd=周杰伦")
resp = requests.get("https://www.baidu.com/s",
params={
"ie": "UTF-8",
"wd": "周杰伦"
}) # params 是专门给get请求增加参数的
# 发送post请求
# 参数类型:formdata 或 urlcode
requests.post(url, data={"直接给字典就可以了"})
# 参数类型:request payload, 能直观的看到是json类型的数据
requests.post(url, json={"直接给字典就可以了"})
requests.post(url, data=json.dumps({直接给字典就可以了}), headers={
"Content-Type": "application/json; charset=UTF-8"
})
### get/pos对比
get/post, 是http的请求方式 # 我们只需要根据抓包里面的状况去选择使用
get和post的传参方式是不一样的
get的参数,最终都会被添加到url身上 ###
# 状态码 (HTTP协议的状态码)
200 系列 一般指的是你当前本次和服务器进行通信没有问题
300 系列 一般指的是重定向. 注意在响应头上能看到location字样
写爬虫的时候. 基本上不用管302 因为requests可以自动帮你完成这个重定向的动作
403 系列 一般都是被风控拦截了
404 系列 资源文件路径走丢了
你的url不存在.再服务器上人家没办法给你想要的内容
500 系列 服务器内部出现了错误
若浏览器有错,那就是本身服务有问题
若浏览器上啥事儿没有. 你的程序一跑,就500. 基本上就是你给的参数有问题. 让服务器无法正常工作
# 解决:重试 + 异常捕获
for i in range(10):
try:
发请求
break
except Exception as e:
print("出错了")
03.简单反爬(header)
请求头
# 请求头参数
User-Agent # 用户用什么设备发送的请求, 直接复制粘贴就好
Cookie # 服务器 记录在浏览器上 的一个字符串, 写入浏览器上的一个文件中
# 作用: 和服务器之间保持住会话. session:同理,记录在服务器端的
# 解决:
1.可以直接从浏览器抓包中复制. (某些网站可以)
2.requests.session()来保持会话
注意:requests.session(). 可以帮你处理set-cookie的内容.
它不能帮你处理javascript处理的cookie的内容.
如果网站是用js来维护cookie的, name你需要自己来写代码处理这坨逻辑
Referer # 用来检测上一个url是什么. 一般直接复制粘贴即可 eg: 图片防盗链
网页自己添加的一些参数 # 最蛋疼的 JS逆向的地方
### session的使用
session = requests.session()
session.headers = {
}
session.cookie = {
}
session.get()
session.post()
响应头
# 响应头参数
Location # 302重定向地址 我们不管
Set-Cookie # session自动维护 我们也不管
网页自己添加的一些参数 # 一般情况下是不用管的. 万中无一的那种网站会使用到
04.数据解析
# html
re # 常见使用场景:在html中获取到js的一部分代码(字符串)
xpath # 常见使用场景:解析常规的html结构
from lxml import etree
tree = etree.HTML(response.text)
res = tree.xpath("xxxxx/xxx/xxx")
# etree的xpath,默认返回的是列表. 要判断空的情况
if res:
res[0]
else:
xxx
bs4 # 常见使用场景:解析 xml类型和 svg(使用XML格式,定义图像)
.find()
.findall()
# json
response.json()
json.loads(response.text)
# 注意:
如果遇到反爬. 很可能拿到的东西 和 抓包工具获取的 不一致
切记, 先打印response.text. 确定好 返回的内容是json格式. 才开始转化
# jsonp 一般是 network 中 JS 请求类型 返回的数据类型
# 这个"jsonpxxxxxx",也在该url的 请求参数中看得到
callback: jsonpxxxxxx
# eg:
jsonpxxxxxx({json}) => {json}
# 解决:想办法去掉左右两端的xxxxxx( ) => 得到的就是json
"jsonpxxxxxx({json})".replace("xxxxxx(", "")[:-1]
05.多任务异步爬虫
# 一般情况下:
最多是 多进程 + 多线程 就够了, 协程不仅麻烦,而且基本正规的网站 都有频率等限制,用不到协程这么高性能
# 进程是资源单位. 进程与进程之间是隔离的
p1 = Process()
p2 = Process()
Queue / redis # 进程通信:队列 和 redis
# 线程是执行单位,多个线程共享 同一个进程的资源
# 协程是人为干预,主进程下 主线程的任务执行情况,将耗时任务 挂起,并切换到其他任务 (最麻烦的)
06.数据库
MySQL, Mongodb, redis