2、使用urllib模块读取网络资源、发送请求参数、读取受保护的网络资源

1)打开URL对应的资源

  • urlopen(url, data=None) 方法(urllib.request子模块下):用于打开 url 指定的资源,并从中读取数据
import urllib.request

with urllib.request.urlopen('http://www.crazyit.org/index.php') as f:
    print(f.read(540).decode('UTF-8'))     # 打开网络资源后,该资源可理解为一个文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>企业应用开发与实践 CrazyIt做最受欢迎的Java论坛</title>
<meta name="keywords" content="Java论坛,疯狂Java,Android,学习,论坛,Java知识论坛,前端开发,SpringMVC,SpringCloud,SpringBoot,Redis,Shiro,Hibernate,Spring,hadoop,云计算,大数据,AI,人工智能" />

2)发送请求参数

(1)模拟 test 的网站服务端:
  • test/get.jsp 页面将收到的 name 和 password 数据返回
  • test/post.jsp 页面将请求方式与受到的 name 和 password 数据返回
  • test/put 返回“Got Data:put数据”
(2)urlopen() 函数:向被请求的 url 发送数据
  • GET 请求直接将请求参数追加到 url 后面即可
params = {'name':'fkit', 'password':'6656565'}

with urllib.request.urlopen('http://192.168.1.17:8888/test/get.jsp?%s' & urllib.parse.urlencode(params)) as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_urllib模块

  • POST 请求用 data 参数
params = {'name':'fkit', 'password':'6656565'}

with urllib.request.urlopen('http://192.168.1.17:8888/post.jsp', data=urllib.parse.urlencode(params).encode('UTF-8')) as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_urllib模块_02

  • PUT、PATCH、DELETE 等请求需要使用 urllib.request.Reques 来构建请求参数,构建 Request对 象时,可通过 method 参数指定请求方式
# put请求参数
params = 'put数据'.encode('UTF-8')
# 创建Request对象
req = urllib.request.Request(url='http://192.168.1.17:8888/test/put', data=params, method='PUT')

with urllib.request.urlopen(req) as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_urllib模块_03

3)访问受保护的资源

(1)模拟 test 的网站服务端
  • test/secret.jsp 页面为受保护的资源,需要登录(test/login.jsp)后才能访问
(2)http.cookiejar 模块:可管理 session id
  • 访问受保护的资源时
import urllib.request

with urllib.request.urlopen('http://192.168.1.17:8888/test/secret.jsp') as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_urllib模块_04

分析:访问被保护的资源时必须先登录才能访问

  • 登录访问受保护的资源
import urllib.request

params = {'name':'crazyit.org', 'pass':'leegang'}

# 登录
with urllib.request.urlopen('http://192.168.1.17:8888/test/login.jsp', data=urllib.parse.urlencode(params).encode('UTF-8')) as f:
    print(f.read().decode('UTF-8'))

with urllib.request.urlopen('http://192.168.1.17:8888/test/secret.jsp') as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_发送请求参数_05

分析

  • Web 应用基于 HTTP 协议通信,HTTP 是一种不保存状态,即无状态(stateless)协议
  • 实际中,网站的登录基于 cookie
  • 保持登录状态访问受保护的资源
  • python 中 http.cookiejar 模块可管理 session id
  • 登录后用 cookie 记录登录后的 session id,下次使用同样的 session id 登陆即可读取受保护的资源
import urllib.request
import http.cookiejar

# 创建 Cookiejar 对象
cookie_jar = http.cookiejar.MozillaCookieJar('a.txt')
# 创建 Cookie 处理器
cookie_proc = urllib.request.HTTPCookieProcessor(cookie_jar)
# 创建 OpeneDirector 对象(当程序使用 OpeneDirector 对象发送多次请求时,它们使用相同的Cookie,因此服务端就可以维持多次访问状态)
opener = urllib.request.build_opener(cookie_proc)

params = {'name':'crazyit.org', 'pass':'leegang'}

# 登录,使用 opener 的 open() 方法
with opener.open('http://192.168.1.17:8888/test/login.jsp', data=urllib.parse.urlencode(params).encode('UTF-8')) as f:
    print(f.read().decode('UTF-8'))
# 使用 opener 的open()方法(可多次 open 与服务器建立请求,服务器可根据 Cookie 来维护它们的状态)
with opener.open('http://192.168.1.17:8888/test/secret.jsp') as f:
    print(f.read().decode('UTF-8'))

Python查本机无线网卡 如何用python查找网络资源_urllib模块_06