环境
Python 3.6.5
Pycharm Professional 2017.1
需要预备的知识
python基础语法
了解基础的web网页结构知识
了解http协议
熟悉浏览器开发者工具使用
爬虫所需的基础的web网页结构,http协议、开发者工具使用我会在其他文章中补上
简介
Requests 是一个模拟请求的python工具库。用于爬虫三部曲的第一步。
Requests Python编写,基于urllib,自称HTTP for Humans(让HTTP服务人类)。关于urllib的内容,可以参考我的另一篇文章。
特性:
-
支持HTTP连接保持和连接池
-
支持使用cookie保持会话
-
支持自动确定响应内容的编码
-
支持国际化的URL和POST数据自动编码
-
使用更简洁方便,比urllib更加Pythoner
开源地址:https://github.com/kennethreitz/requests
中文文档API:https://requests.readthedocs.io/zh_CN/latest/
安装
最简单方式:打开pycharm底部的终端命令窗口,输入pip install requests即可。
如果网络连接较差,可以尝试使用清华源的地址
临时使用
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
注意,simple 不能少, 是 https 而不是 http
设为默认
升级 pip 到最新的版本 (>=10.0.0) 后进行配置:
pip install pip -U
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
如果 pip 默认源的网络连接较差,临时使用本镜像站来升级 pip:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
知识
Get请求
最简单的get请求
# 导入请求库
import requests
# 访问百度 访问的结果 都存储到了这个response变量里
response = requests.get("https://www.baidu.com")
requests直接将方法名定义为请求方式,第一个参数为请求地址
查看请求结果
# 请求状态码
print(response.status_code)
# 请求的内容,只不过是字节类型,需要进行解码
print(response.content)
# 对上一步进行解码 decode默认解码类型为utf-8
print(response.content.decode())
添加请求参数
1.直接拼接在url里
import requests
# 添加请求头User-Agent 绕过百度反爬 关于UA后边会说到
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"}
# 直接在问号后边补全参数即可,wd是百度的搜索参数
response = requests.get("https://www.baidu.com/s?ie=UTF-8&wd=996",headers=headers)
print(response.content.decode())
自己浏览器的User-Agent,可以使用开发者工具查看。按F12,选择Network,随便选中一个请求,打开Headers选项,在Requests-Headers里边。
爬虫所需的信息一般返回结果为html,json,js,如果请求返回的结果是html的,可以使用这种方式方便查看结果:
# 为了查看方便我们可以把内容保存为html文件,进行本地查看
with open("./temp_result.html","wb") as f:
f.write(response.content)
如果参数是中文的还需要进行转字节,比较麻烦,所以使用下面这种方式是极好的。
2.字典方式传参,自动拼接url
使用另外一个参数params,只需要把参数以字典的形式传入即可,如果有中文也不需要自己转换字节了。
# 使用字典的方式
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
}
params = {"ie":"UTF-8","wd":"狮范客"}
response = requests.get("https://www.baidu.com/s?",params=params,headers=headers)
with open("./temp_result.html","wb") as f:
f.write(response.content)
print(response.content.decode())
Post请求
# 这个请求没有意义 这里我们先了解post方法即可
response = requests.post("http://www.baidu.com",data={"q":"shifanke"})
在post请求里,data参数是post请求要提交的参数,即要放到请求体中的数据。其他的和get请求一样。
Get/Post请求参数列表
-
method:Request请求对象的方法。
-
url:Request请求对象的url。
-
params:(可选)要在查询中发送的字典或字节,即get参数
-
param data:(可选)要放在Request请求对象的数据,即http协议的请求体部分,参数形式为字典、元组、字节或类似文件的列表,即post参数
-
json:(可选)同上,不过格式为json
-
headers:http协议的请求头部分
-
cookie:(可选)请求头的一部分,形式为字典或CookieJar对象
-
files:(可选)上传多部分编码文件。
-
auth:(可选)auth元组或可调用以启用基本消化/定制HTTP身份验证。
-
timeout:(可选)设置等待服务器发送的时间
-
allow_redirects:(可选)是否允许重定向默认设置为True。
-
proxies:(可选)字典方式设置代理
-
stream:(可选)是否立即下载响应内容。默认为“假”。
-
verify:(可选)一个布尔值,在这种情况下,它控制我们是否验证服务器的TLS证书,或字符串,在这种情况下,它必须是路径到要使用的CA束。默认为’ ‘真实的’ '。
-
cert:(可选)字符串,ssl客户端证书文件的路径(.pem)。如果是元组,那就这种格式(‘cert’, ‘key’)。
反爬机制
这里我们先讨论几种简单的,复杂的我们会放在后边。
反爬机制:
- 封杀爬虫程序
- 封杀指定IP
- 封杀非人操作的程序
应对策略:
- 伪装为真实用户
- 更换IP
- 让程序的行为更像人的操作
1.伪装为真实用户
如果直接使用requests进行访问,你的请求头的User-Agent的会显示python-requests/2.22.0,这样服务器很容易,通过这个标识,来判定你是爬虫程序,不是正常用户,所以我们要进行伪装,骗过服务器。
User Agent中文名为用户代理,是Http协议中的一部分(我后边会补充一遍文章聊聊http),属于头域的组成部分,User Agent也简称UA。它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计。
浏览器的UA字串的标准格式:浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识版本信息。但各个浏览器有所不同。
浏览器就是互联网世界上公认被允许的身份,如果我们希望我们的爬虫程序更像一个真实用户,那我们第一步,就是需要伪装成一个被公认的浏览器。用不同的浏览器在发送请求的时候,会有不同的User-Agent头。中文名为用户代理,简称UAUser Agent存放于Headers中服务器就是通过查看Headers中的User Agent来判断是谁在访问。urllib中默认的User Agent,会有Python的字样,如果服务器检查User Agent,可以拒绝Python程序访问网站。
当前的User-Agent可以访问这个接口进行测试:
http://www.useragentstring.com/
我们之前的那个百度搜索的案例,就使用了这种方式。
# 使用字典的方式
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
}
params = {"ie":"UTF-8","wd":"狮范客"}
response = requests.get("https://www.baidu.com/s?",params=params,headers=headers)
with open("./temp_result.html","wb") as f:
f.write(response.content)
print(response.content.decode())
2.封杀指定IP
不知道大家有没有遇到这样的情况,尤其是一些政府网站,一个网页短时间快速多刷新几次,然后就不能访问了。
对服务器来说,在绝大数情况下,一个ip在短时间进行大量的访问,肯定是不正常的。所以为了服务器的稳定不浪费资源,会针对这些ip进行封禁,拉进小黑屋。有可能过两天就给你解了,也有可能很长一段时间不会解禁。
所以这时候,就需要使用代理ip,其实大家用的游戏加速器和科学上网工具就是代理ip。或者手机开热点,电脑连手机,也可以当代理ip用,而且运营商还很贴心的帮你换ip。
代理ip,封了就封了,我们可以无限更换。可以使用网上一些免费的,但是可用率极低,推荐使用一些第三方ip代理服务商提供的,推荐的有:
蘑菇代理 http://www.moguproxy.com/
讯代理 http://www.xdaili.cn/
代理云 http://www.dailiyun.com/
常见的代理 IP 服务有两种:
私密代理(或者叫高效代理):提供 API,我们通过这个 API 提取到代理IP。
2隧道代理(或者叫动态代理):提供一个统一的入口,每个请求随机分发到代理池中的某个代理IP上。
这两种服务,第二种接入更加方便,效果相差不多。
关于如何接入网站上都有文档,或者也可以咨询客服,后边有时间,我可以写个例子供大家参考。这里说一些requests如何设置代理ip。
proxies = {"http":"123.231.21.31:3365"}
# 使用proxies参数 以字典的形式 传入代理IP地址
response = requests.get("http://www.baidu.com",proxies=proxy)
3.封杀非人操作
不知道大家玩游戏的时候apm(每分钟操作的次数)是多少?我是个魔兽争霸和星际的老玩家,基本上也就80左右,那些职业选手基本都是200+,爆发一下可以上400。
如果有人说他的apm1000+,你信不信?
同理可证,服务器如果检测到一个用户,快速的在进行网站访问,达到了一个非正常的用户的阈值,那也也会进行访问限制,即你的访问频率过高。
所以有时候,我们需要控制一下频率,毕竟冲多了,会有问题。冲完你需要睡觉休息,以便再冲,程序也是一样。所以:
time.sleep()是个好东西
在你不断的骚扰别人服务器的时候, 要稍微控制一下。这样,你好我好,大家才好。
任务
如果掌握了需要预备的知识,那么可以尝试以下两个任务
注:这两个都有json的数据接口,不需要进行html解析
获取腾讯招聘职位信息:https://careers.tencent.com/search.html
获取斗鱼颜值主播信息:
https://www.douyu.com/g_yz