Python 爬虫实践
目录
1. 第一次爬虫
# b---->代表bytes----->字节类型
# encode() 编码
# decode() 解码 utf-8(国际通用码) gbk(国标库) gb2312(国标2312)
'''
#文件使用方式标识
w --- 写,会覆盖所有 r ---读 a --- 写,在末尾追加
wb,rb,ab-------二进制写,读
w+ ---读写,r+读写,区别在于文件不存在,不会创建新文件
'r':默认值,表示从文件读取数据。
'w':表示要向文件写入数据,并截断以前的内容
'a':表示要向文件写入数据,添加到当前内容尾部
'r+':表示对文件进行可读写操作(删除以前的所有数据)
'r+a':表示对文件可进行读写操作(添加到当前文件尾部)
'b':表示要读写二进制数据
'''
# *args: 动态位置传参
# **kwargs: 动态关键字传参
import requests
'''爬取百度首页'''
# 1.确定url, 向服务器发起请求, 获取响应数据
url = 'https://www.baidu.com/'
res = requests.get(url=url)
# 2.解析数据(略过)
res.encoding = 'utf-8'
print(res.text)
# 3.持久化到本地: 写文件, MySQL, redis, MongoDB
# f = open('baidu.html', 'w', encoding='utf-8')
# f.write(res.text)
# f.close()
with open('baidu.html', 'w', encoding='utf-8') as f:
f.write(res.text)
print('执行此行代码前就关闭了文件')
2. 八大请求方式
# 请求: 有客户端向服务器发出的, 可以分为四部分内容:
1.请求方法(Request Method),
2.请求网址 (Request URL),
3.请求头(Request Headers), # ******
4.请求体(Request Body) # ******
# 请求方法:常见有8种 (***背会***)
- GET: 请求页面, 并返回页面内容(**获取**) #重点
- POST: 用于提交表单数据或上传文件, 数据包含在请求体中 # 重点
- PUT: 从客户端向服务器传送的数据取代指定文档中的内容
- DELETE: 请求服务器删除指定的页面
- HEAD: 类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头
- CONNECT: 把服务器当作跳板,让服务器代替客户端访问其他网页
- OPTIONS: 允许客户端查看服务器的性能
- TRACE: 回显服务器收到的请求,主要用于测试或诊断
************
# 中点掌握GET & POST: GET与POST的区别(重点) --> **(面试出镜率较高)**
1.GET请求中的参数包含在URL里面, 数据可以在URL中看到, 而POST请求的URL不会包含这些数据, POST的数据都是通过表单形式传输的, 会包含在请求体中
2.GET请求提交的数据最多只有1024字节, 而POST方式没有限制
3. 请求头简介
# 请求头:
请求头,用来说明服务器要使用的附加信息. 重点掌握: ***Accept, Cookie, Referer, User-Agent***
1.Accept:请求报头域,用于指定客户端可接受哪些类型的信息 # 重点(*/*)
2.Cookie:也常用复数形式 Cookies,这是网站为了辨别用户进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前访问会话。
例如,我们输入用户名和密码成功登录某个网站后,服务器会用会话保存登 录状态信息,后面我们每次刷新或请求该站点的其他页面时,
会发现都是登录状态,这就是Cookies的功劳。 Cookies里有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,
都会在请求头中加 上Cookies并将其发送给服务器,服务器通过Cookies识别出是我们自己,并且查出当前状态是登录状态,所 以返回结果就是登录之后才能看到的网页内容 # 重点
3.Referer:此内容用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如 作来源统计、防盗链处理等 # 重点
***********************************************
4.User-Agent:简称UA,它是一个特殊的字符串头,可以使服务器识别客户使用的操作系统及版本、浏览器 及版本等信息。在做爬虫时加上此信息,可以伪装为浏览器;如果不加,很可能会被识别出为爬虫 # 重点
***********************************************
5.x-requested-with :XMLHttpRequest #代表ajax请求
6.Accept-Language:指定客户端可接受的语言类型
7.Accept-Encoding:指定客户端可接受的内容编码
8.Content-Type:也叫互联网媒体类型(Internet Media Type)或者MIME类型,在HTTP协议消息头 中,它用来表示具体请求中的媒体类型信息。例如,text/html代表HTML格式,image/gif代表GIF图片, application/json代表JSON类型
4. 反爬与反反爬
1.反爬机制:
1).UA检测 2).IP封禁 3).robots协议 4).账号封禁 5).验证码 6).动态数据加载 7).图片懒加载 8).隐藏参数 9).js加密-->js逆向
2.反反爬策略:
1).UA伪装 2).IP代理池 3).settings设置 4).cookie池 5).第三发打码平台 6).1.selenium 2.ajax 3.js逆向
5. 常见的状态码
# 响应状态码: 用于判断请求后的相应状态, 如200代表请求成功, 404代表页面页面找不到, 500代表服务 器错误 # 常见的状态码:
200系列:
200 成功 服务器已成功处理了请求 # 重点1
300系列:
301 永久移动 请求的网页已永久移动到新位置,即永久重定向 # 重点
302 临时移动 请求的网页暂时跳转到其他页面,即暂时重定向 # 重点
400系列:
400 错误请求 服务器无法解析该请求 # 重点
401 未授权 请求没有进行身份验证或验证未通过
403 禁止访问 服务器拒绝此请求 # 重点
404 未找到 服务器找不到请求的网页
500系列:
500 服务器内部错误 服务器遇到错误,无法完成请求 # 重点
501 未实现 服务器不具备完成请求的功能
502 错误网关 服务器作为网关或代理,从上游服务器收到无效响应
504 网关超时 服务器作为网关或代理,但是没有及时从上游服务器收到请求
505 HTTP版本不支持 服务器不支持请求中所用的HTTP协议版本
**(注意: 状态码不能完全代表响应状态, 部分网站的状态码是自定义的, 一切以响应的数据为准)**
6. 响应头
# 响应头: (了解即可)
响应头包含了服务器对请求的应答信息
Date:标识响应产生的时间。
Content-Encoding:指定响应内容的编码。
Server:包含服务器的信息,比如名称、版本号等。
Content-Type:文档类型,指定返回的数据类型是什么,如text/html代表返回HTML文档
application/x-javascript则代表返回JavaScript文件,image/jpeg则代表返回图片。
Set-Cookie:设置Cookies。响应头中的Set-Cookie告诉浏览器需要将此内容放在Cookies中,下次请 求携带Cookies请求。
Expires:指定响应的过期时间,可以使代理服务器或浏览器将加载的内容更新到缓存中。如果再次访问时, 就可以直接从缓存中加载,降低服务器负载,缩短加载时间。
7. 响应体
# 响应体: --------------重要
最重要的当属响应体的内容了。响应的正文数据都在响应体中,比如请求网页时,它的响应体就是网页的HTML 代码;请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的内容就是响应体.
8. 网页基础
# 网页的组成:
网页可以分为三部分, HTML, CSS, JavaScript
1.HTML: 其全称叫作Hyper Text Markup Language,即超文本标记语言。 定义了网页的骨架
2.CSS: 全称叫作Cascading Style Sheets,即层叠样式表。 定义了网页的样式
3.JavaScript: 简称JS,是一种脚本语言 定义了网页与用户的交互行为, 如下载进度条, 提示框, 轮播图
9. 爬虫工作流
1.确定url, 向服务器发送请求并获得响应: requests, urllib, aiohttp
2.在响应中提取目标数据, 即数据解析: xpath, bs4, 正则, PyQuery
3.数据持久化: 文件, 关系型数据库, 非关系型数据库
10. 抓包技能操作认识
***抓包在页面右键检查 或者 F12键
1.箭头---快速定位页面的某个元素(如果在页面定位元素没显示,用快捷键(ctrl+shift+c))
2.小方块---变成手机版的页面
3.Elements---包含页面的所有元素(所有响应数据的集合,也可以快速定位)
4.Network---(重要)网络抓包[Preserve log:保留请求日志,Disable cache:不缓存,缓存提高访问速度]
5.抓包---Headers:包含所有的头部信息,Preview:预览内容,Response:响应内容(搜索:Ctrl+f查询)
【all(所有) XHR(ajax请求) JS(.js) CSS(.css) Img(图片) media(音频,视频) Font(字体文件) Doc(HTML文件)】
11. requests 模块请求
编码:再网页Elements中<head><charset=utf-8></head> 查看编码
import requests
#1.确定url,发起请求,获取响应
url = '链接地址'
res = requests.get(url=url)
res.encoding='utf-8'
print(type(res.text))----------输出获取的是一个字符串
with open('zhihu.html','w',encoding='utf-8') as f:
#res是一个响应对象
#f.write(字符串)
f.write(res.text)
12. requests 模块基本使用
# requests库的安装
pip install requests
1.get请求: 请求拼接再url上,
不携带参数的get请求: 搜狗首页
不携带参数的get请求 + headers:
爬取知乎的发现页 携带参数的get请求 + headers: 知乎的发现栏中搜索Python
# parameters 的缩写 params--{}字典的形式--拼接再url?后面(也可以封装函数,传参)
res = requests.get(url=url, headers=headers, params=params,proxies=proxies)
2.post请求: 构建参数的post请求 携带在Form data中
# data 数据(在网页Form Data里)响应数据是json数据类型--字典{}
res = requests.post(url=url, headers=headers, data=data,proxies=proxies)
3. json形式与流形式的响应数据示例
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象
# json形式响应数据示例: bilibili的Python视频教程, 目录列表
import requests
headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' }
url = 'https://api.bilibili.com/x/web-interface/view?aid=14184325&cid=23153678' res = requests.get(url=url, headers=headers)
print(res)
print(res.status_code)
print(res.headers)
print(res.json())
4.响应数据的获取与属性
(1).响应数据的获取:
res.text: 文本数据
res.json(): json数据 ------->dict
res.content: 流, 图片, 视频, 压缩包, 软件包
(2).响应的其他属性:
res.status_code: 获取响应状态码
res.headers: 响应头
res.cookie: cookie信息
res.history: 历史
13. 代理 IP
# goubanjia.com IP代理商
#proxy 变成了 proxies的参数{}
正向代理:对于浏览器知道服务器的真实地址,例如VPN
反向代理:浏览器不知道服务器的真实地址,例如nginx
代理IP的分类
根据代理ip的匿名程度,代理IP可以分为下面四类:
透明代理(Transparent Proxy):透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以查到你是谁。
匿名代理(Anonymous Proxy):使用匿名代理,别人只能知道你用了代理,无法知道你是谁。
高匿代理(Elite proxy或High Anonymity Proxy):高匿代理让别人根本无法发现你是在用代理,所以是最好的选择。
从请求使用的协议可以分为:
http代理
https代理
socket代理等
不同分类的代理,在使用的时候需要根据抓取网站的协议来选择
import random
ip-list = ['']
proxies = {
协议 IP
'https':'http:// %s' % random.choice(ip-list)
}