11.Python爬虫必学的网络编程知识

1、基础知识

  • HTTP:(HyperText Transport Protocol)是超文本传输协议缩写

  • URL:(Uniform Resource Locator)是统一资源定位符的缩写

  • HTTP请求方式

对比项GETPOST
提交方式提交的参数数据放在URL之后,使用?与URL进行分割,多个参数之间使用&分隔提交的参数数据不放在URL中提交,模拟提交表单数据
提交数据长度受限无限制
安全性安全性低,提交的数据与URL混合在一起提交,很容易被发现安全性高
  • 状态码:常见的状态码

    • 200:表示请求成功,成功返回请求资源
    • 404:表示请求的资源不存在
    • 500:服务器错误

2、urllib库

urllib库内置模块:

模块说明
urllib.requestHTTP请求模块,在程序中模拟浏览器发送HTTP请求
urllib.error异常模块,捕获由于HTTP请求问题产生的异常,并进行处理
urllib.parseURL解析模块,提供了处理URL的工具函数
urllib.robotparserrobots.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):
    ...省略

参数说明:

参数名称是否必填说明
urlHTTP请求的目标地址
dataHTTP请求要传输的数据,数据是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:获取响应头信息