11.Python爬虫必学的网络编程知识
1、基础知识
HTTP:(HyperText Transport Protocol)是超文本传输协议缩写
URL:(Uniform Resource Locator)是统一资源定位符的缩写
HTTP请求方式
对比项 | GET | POST |
---|---|---|
提交方式 | 提交的参数数据放在URL之后,使用? 与URL进行分割,多个参数之间使用& 分隔 | 提交的参数数据不放在URL中提交,模拟提交表单数据 |
提交数据长度 | 受限 | 无限制 |
安全性 | 安全性低,提交的数据与URL混合在一起提交,很容易被发现 | 安全性高 |
状态码:常见的状态码
- 200:表示请求成功,成功返回请求资源
- 404:表示请求的资源不存在
- 500:服务器错误
2、urllib库
urllib库内置模块:
模块 | 说明 |
---|---|
urllib.request | HTTP请求模块,在程序中模拟浏览器发送HTTP请求 |
urllib.error | 异常模块,捕获由于HTTP请求问题产生的异常,并进行处理 |
urllib.parse | URL解析模块,提供了处理URL的工具函数 |
urllib.robotparser | robots.txt解析模块,网站通过robots.txt文件设置爬虫可爬取的网页 |
2.1、urllib.request.urlopen
函数
常用参数:
url:目标URL访问地址
data:默认是None,表示GET方式发送请求,data有值,表示POST方式发送请求
timeout:访问超时时间
GET请求
import urllib.request
#data没值是GET
res = urllib.request.urlopen("http://www.baidu.com")
print(res.read().decode("utf8"))
- POST请求
import urllib.request
# 请求数据
param_dict = {"key":"hello world"}
# 调用urlencode函数将字典类型数据转成字符串
param_str = urllib.parse.urlencode(param_dict)
#将传输数据封装成一个bytes对象
param_datas=bytes(param_str,encoding="utf8")
#data有值是POST
res = urllib.request.urlopen("http://httpbin.org/post",data=param_datas)
print(res.read().decode("utf8"))
- 超时时间
import urllib.request
res = urllib.request.urlopen("http://www.baidu.com",timeout=0.001)
print(res.read())
- 响应状态码和头信息
import urllib.request
res = urllib.request.urlopen("http://www.baidu.com")
print(res.status)
print(res.getheaders())
2.2、urllib.request.Request
类
- Request类的构造方法
class Request:
def __init__(self, url, data=None, headers={},
origin_req_host=None, unverifiable=False,
method=None):
...省略
参数说明:
参数名称 | 是否必填 | 说明 |
---|---|---|
url | 是 | HTTP请求的目标地址 |
data | 否 | HTTP请求要传输的数据,数据是bytes字节流数据 |
headers | 否 | 请求头信息,头信息使用字典存储 |
origin_req_host | 否 | 发起HTTP请求的主机名称或者IP地址 |
unverifiable | 否 | 表示这个请求是否为无法验证的。默认值是False |
method | 否 | 发起HTTP请求的方式,如GET、POST等 |
import urllib.request
import urllib.parse
url = "http://httpbin.org/post"
#设置浏览器信息
headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"}
data_dict={"word":"hello world"}
#将字典类型数据转换成bytes字节流
data=bytes(urllib.parse.urlencode(data_dict),encoding="utf8")
#创建Request对象
request = urllib.request.Request(url,data=data,headers=headers,method="POST")
res = urllib.request.urlopen(request)
print(res.read().decode("utf8"))
2.3、urllib.error
异常处理
为了提高程序的稳定性,需要捕获这些异常,还可以根据需要捕获的异常做进一步处理
- URLError:通过reason属性可以获取产生URLError的原因
产生URLError的原因:
- 网络异常,失去网络连接
- 访问的服务器不存在,服务器连接失败
import urllib.request
import urllib.error
# 不存在的url
url="http://www.qwertqwert123.com"
try:
request_obj = urllib.request.Request(url=url)
res = urllib.request.urlopen(request_obj)
except urllib.error.URLError as e:
print(e.reason)
- HTTPError:是URLError的子类
返回属性说明:
- code:响应的状态码
- reason: 获取产生HTTPError的原因
- headers:获取HTTP请求头信息
import urllib.request
import urllib.error
try:
# 不存在的地址
res = urllib.request.urlopen("http://www.baidu.com/qwe")
except urllib.error.HTTPError as e:
print("异常原因:",e.reason)
print("响应状态码:",e.code)
print("请求头信息:",e.headers)
except urllib.error.URLError as err:
print(err.reason)
3、requests库
基于urllib开发的HTTP相关操作库,相比直接使用urllib库更加简单、更加易用
3.1 安装(pip或者pip3安装)
pip3 install requests
3.2 使用
GET请求
import requests
url="http://httpbin.org/get"
res = requests.get(url)
print("返回类型:",type(res))
print("状态码:",res.status_code)
print("响应内容:\n",res.text)
- 结果:
返回类型: <class 'requests.models.Response'>
状态码: 200
响应内容:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0",
"X-Amzn-Trace-Id": "Root=1-5ff045c8-30b38f5f724544101d7cd8cb"
},
"origin": "223.73.124.224",
"url": "http://httpbin.org/get"
}
POST请求
import requests
url="http://httpbin.org/post"
data ={
"test":"hello world"
}
res = requests.post(url=url,data=data)
print("状态码:",res.status_code)
print("响应内容:\n",res.text)
- 结果:
状态码: 200
响应内容:
{
"args": {},
"data": "",
"files": {},
"form": {
"test": "hello world"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0",
"X-Amzn-Trace-Id": "Root=1-5ff04695-0cc9f99351d3f06c3345a93c"
},
"json": null,
"origin": "223.73.124.224",
"url": "http://httpbin.org/post"
}
添加头信息:
主要是伪装成浏览器向网站发送请求,防止被请求的服务器拦截非浏览器的请求
import requests
url="http://httpbin.org/post"
data ={
"test":"hello world"
}
# 添加头信息
headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"}
res = requests.post(url=url,data=data,headers=headers)
print("状态码:",res.status_code)
print("响应内容:\n",res.text)
- 结果:
状态码: 200
响应内容:
{
"args": {},
"data": "",
"files": {},
"form": {
"test": "hello world"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-5ff0473d-0e1061c93fb5612c5004fc37"
},
"json": null,
"origin": "223.73.124.224",
"url": "http://httpbin.org/post"
}
通过添加头信息和不加头信息的POST请求对比得到的结果发现:
- 不加头信息返回结果显示:
"User-Agent": "python-requests/2.22.0"
- 添加头信息返回结果的
User-Agent
与我们设置的头信息一样的
Response对象:
常用返回值说明:
- text:获取服务端返回的响应内容
- content:获取二进制数据,如服务器返回的图片、视频等
- url:获取请求的url
- encoding:获取响应内容的编码格式
- cookies:获取cookies信息
- headers:获取响应头信息