网络爬虫就是模拟浏览器发送网络请求,接收请求响应,按照一定的规则,自动地抓取互联网信息的程序。
爬虫分为:
通用爬虫 :通常指搜索引擎的爬虫(https://www.baidu.com)
聚焦爬虫 :针对特定网站的爬虫
爬虫流程:
1、向起始url发送请求,并获取响应
2、对响应进行提取
3、如果提取url,则继续发送请求获取响应
4、如果提取数据,则将数据进行保存
Robots协议:
网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,但它仅仅是互联网中的一般约定
HTTP 超文本传输协议 默认端口号:80
HTTPS HTTP + SSL(安全套接字层),即带有安全套接字层的超本文传输协议 默认端口号:443
HTTPS比HTTP更安全,但是性能更低
常见的状态码:
200:成功
302:临时转移至新的url
307:临时转移至新的url
404:找不到该页面
500:服务器内部错误
503:服务不可用,一般是被反爬
response的常用属性:
response.text 响应体 str类型
respones.content 响应体 bytes类型
response.status_code 响应状态码
response.request.headers 响应对应的请求头
response.headers 响应头
response.request.cookies 响应对应请求的cookie
response.cookies 响应的cookie(经过了set-cookie动作)
根据代理ip的匿名程度,代理IP可以分为下面四类:
透明代理(Transparent Proxy):透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以查到你是谁。
匿名代理(Anonymous Proxy):使用匿名代理,别人只能知道你用了代理,无法知道你是谁。
高匿代理(Elite proxy或High Anonymity Proxy):高匿代理让别人根本无法发现你是在用代理,所以是最好的选择。
练习:
把网络上的图片保存到本地
我们来把www.baidu.com的图片保存到本地思考:
以什么方式打开文件
保存什么格式的内容
分析:
图片的url: https://www.baidu.com/img/bd_logo1.png
利用requests模块发送请求获取响应
以2进制写入的方式打开文件,并将response响应的二进制内容写入
import requests
# 图片的url
url = 'https://www.baidu.com/img/bd_logo1.png'
# 响应本身就是一个图片,并且是二进制类型
response = requests.get(url)
# print(response.content)
# 以二进制+写入的方式打开文件
with open('baidu.png', 'wb') as f:
# 写入response.content bytes二进制类型
f.write(response.content)
发送带header的请求
我们先写一个获取百度首页的代码
import requests
url = 'https://www.baidu.com'
response = requests.get(url)
print(response.content)
# 打印响应对应请求的请求头信息
print(response.request.headers)
思考
对比浏览器上百度首页的网页源码和代码中的百度首页的源码,有什么不同?
代码中的百度首页的源码非常少,为什么?
为什么请求需要带上header?
模拟浏览器,欺骗服务器,获取和浏览器一致的内容
header的形式:字典
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
用法
requests.get(url, headers=headers)
完整的代码
import requests
url = 'https://www.baidu.com'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 在请求头中带上User-Agent,模拟浏览器发送请求
response = requests.get(url, headers=headers)
# print(response.content)
# 打印请求头信息
print(response.request.headers)