2、urllib

urllib提供了一系列用于操作URL的功能。

urllib包包含以下几个模块:

request

urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies等。

urllib.request 可以模拟浏览器的一个请求发起过程。

urlopen就是默认的opener,如果需要设置cookie、代理等,就需要自己定义opener

我们可以使用 urllib.request 的 urlopen 方法来打开一个 URL,返回一个HTTPResponse对象,语法格式如下:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, context=None)
'''
url:url 地址。
data:发送到服务器的其他数据对象,默认为 None。
timeout:设置访问超时时间。
cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
context:ssl.SSLContext类型,用来指定 SSL 设置
'''

Get

from urllib import request

resp = request.urlopen('http://www.baidu.com/')
#获取相应状态
print('Statu:',resp.status,resp.code,resp.reason)
#获取相应头,返回结果是一个list
head = resp.getheaders()
for k,v in head:
    print('%s : %s' % (k,v))
#获取html,返回的是一个bytes
htmlBytes = resp.read()
print('Data:',htmlBytes.decode('utf8'))
'''
Statu: 200 200 OK
Bdpagetype : 1
Bdqid : 0xa3f2605700088dec
Cache-Control : private
Content-Type : text/html;charset=utf-8
Date : Sat, 19 Feb 2022 04:05:09 GMT
Expires : Sat, 19 Feb 2022 04:04:28 GMT
P3p : CP=" OTI DSP COR IVA OUR IND COM "
P3p : CP=" OTI DSP COR IVA OUR IND COM "
Server : BWS/1.1
Set-Cookie : BAIDUID=2A0FEC55C3A41C151689C00F84061B38:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie : BIDUPSID=2A0FEC55C3A41C151689C00F84061B38; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie : PSTM=1645243509; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie : BAIDUID=2A0FEC55C3A41C15DAA13C7EFAE72913:FG=1; max-age=31536000; expires=Sun, 19-Feb-23 04:05:09 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Set-Cookie : BDSVRTM=0; path=/
Set-Cookie : BD_HOME=1; path=/
Set-Cookie : H_PS_PSSID=35836_35106_31660_35768_35776_34584_35490_35871_35804_35324_26350; path=/; domain=.baidu.com
Traceid : 1645243509051811482611813610699325214188
Vary : Accept-Encoding
Vary : Accept-Encoding
X-Frame-Options : sameorigin
X-Ua-Compatible : IE=Edge,chrome=1
Connection : close
Transfer-Encoding : chunked
Data: <!DOCTYPE html>
    <html>...
'''

Post

如果要以POST发送一个请求,只需要把参数data以bytes形式传入。

例如,在本地使用java写一个post接口

@PostMapping("/postTest")
@ResponseBody
public String postTest(String name,int age){
    return "收到post请求,name = " + name + ",age = " + age;
}

使用python发送post请求

from urllib import request,parse
# dict类型的参数
requestData = {
    'name':'lucy',
    'age':18
}
# 通过parse.urlencode()将字典转换为字符串
requestDataBytes = parse.urlencode(requestData).encode('utf8')
# data设置参数,发送请求
resp = request.urlopen('http://localhost:8090/postTest',data=requestDataBytes)

print('Status:',resp.code,resp.reason)
head = resp.getheaders()
print(type(head))
for k,v in head:
    print('%s : %s' % (k,v))

print('Data:',resp.read().decode('utf8'))

'''
Status: 200 
<class 'list'>
Content-Type : text/plain;charset=UTF-8
Content-Length : 39
Date : Sat, 19 Feb 2022 04:48:03 GMT
Connection : close
Data: 收到post请求,name = lucy,age = 18
'''

Request对象

如果我们要想模拟浏览器发送GET请求,就需要使用Request对象,通过往Request对象添加HTTP头User-Agent,我们就可以把请求伪装成浏览器。例如,模拟Win7使用Chrome请求廖雪峰首页(这个首页是有反爬的,不加请求头无法回503):

User-Agent中文名为用户代理,是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。通过这个标 识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计;例如用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的 UA来判断的。UA可以进行伪装。

from urllib import request

#定义Request对象
req = request.Request('http://www.liaoxuefeng.com/')
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1')

resp = request.urlopen(req)
#获取相应状态
print('Statu:',resp.status,resp.code,resp.reason)
#获取相应头,返回结果是一个dict字典
head = resp.getheaders()
for k,v in head:
    print('%s : %s' % (k,v))
#获取html,返回的是一个bytes
htmlBytes = resp.read()
print('Data:',htmlBytes.decode('utf8'))

User-Agent

User-Agent中文名为用户代理,是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。通过这个标 识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计;例如用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的 UA来判断的。UA可以进行伪装。

常用的User-Agent可以在网上查到

Chrome-Win7:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1

Handler

Handler 的中文是处理者、处理器。 Handler 能处理请求(HTTP、HTTPS、FTP等)中的各种事情。它的具体实现是这个类 urllib.request.BaseHandler。它是所有的 Handler 的基类,其提供了最基本的Handler的方法,例如default_open()、protocol_request()等。

继承 BaseHandler常见的类:

代理

有些网站做了浏览频率限制。如果我们请求该网站频率过高。该网站会被封 IP,禁止我们的访问。所以我们需要使用代理来突破这“枷锁”。

通过一个Proxy去访问网站,我们需要利用ProxyHandler来处理

这个网站可以查询一些免费的代理:https://www.kuaidaili.com/free/

from urllib import request

#定义代理服务器,需要传入一个字典
ph = request.ProxyHandler({
    'http':'103.37.141.69:80',
    'https':'103.37.141.69:80'
})

#定义opener
op = request.build_opener(ph)
#定义Request对象,如果没有request要设置,url也可以直接写在op.open的参数里面
req = request.Request('http://w')
#访问
resp = op.open(req)

print('Status:',resp.code,resp.reason)
head = resp.getheaders()
print(type(head))
for k,v in head:
    print('%s : %s' % (k,v))

print('Data:',resp.read().decode('utf8'))

Cookie

如果请求的页面每次需要身份验证,我们可以使用 Cookies 来自动登录,免去重复登录验证的操作。获取 Cookies 需要使用http.cookiejar.CookieJar() 实例化一个 Cookies 对象。再用 urllib.request.HTTPCookieProcessor 构建出 handler 对象。最后使用 opener 的 open() 函数即可。

保存cookie

import http.cookiejar
import urllib.request
#需要请求的地址
url = "http://tieba.baidu.com/"
#保存cookie的文件
fileName = 'cookie.txt'
#实例化一个Cookies对象
cookie = http.cookiejar.CookieJar()
#构建handler对象
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open(url)
#将cookie保存到文件中
f = open(fileName,'a')
for item in cookie:
    f.write(item.name+" = "+item.value+'\n')
f.close()

携带cookie

直接设置到请求头就可以了