urllib requests库这两个都是网络请求库,用来模拟浏览器的行为向指定服务器发起请求,并保存服务器返回的数据。
urllib库的一些函数
最基本的网络请求库
- 在urllib库中,所有和网络请求相关的方法都集中到了 urllib.request 模块中,首先时urlopen 函数的使用:
from urllib import request
resp = request.urlopen('http://www.baidu.com')
print(resp.read())
这里的urlopen函数返回的是网页源代码 <http.client.HTTPResponse object at 0x000001C776123460>
一个HTTPResponse对象。用read()读取这个对象的内容。
urlopen:创建一个表示远程url的类文件对象,然后像本地文件一样操作这个文件对象来获取远程数据。
urlopen(url, data=None, timeout=<object object at 0x0000029504DFEE60>, *, cafile=None, capath=None, cadefault=False, context=None)
Open the URL url, which can be either a string or a Request object.
url: 请求的url,这个可以是字符串或者一个request对象。
date :请求的date,如果设置了这个就会变成post请求。
返回值:返回值resp是一个http:client.HttprEspoNse对象,这个对象是文件句柄对象。有read(size)、 readline、 readlines以及 getcode(获取响应值)等方法。
但是如果需要执行更复杂的操作,比如增加HTTP报头,必须创建一个 Request 实例来作为urlopen()的参数(request.Request());而需要访问的url地址则作为 Request 实例的参数。
描述 | 方法 |
---|---|
获取HTTP协议版本号(10 for HTTP/1.0, 11 for HTTP/1.1) | resp.version |
获取响应码 | resp.status resp.getcode() |
获取响应描述字符串(OK) | resp.reason |
获取实际请求的页面url(防止重定向用) | resp.geturl() |
获取特定响应头信息 | esp.getheader(name=“Content-Type”) |
#获取响应头信息,返回二元元组列表 | resp.getheaders() |
获取响应头信息,返回字符串 | resp.info() resp.headers |
读取响应体 | resp.readline().decode(‘utf-8’) resp.read().decode(‘utf-8’) |
- urlretrieve函数方便的将网页上的一个文件保存到本地。
urlretrieve(url,filename=None,reporthook=None,date=None)
from urllib import request
request.urlretrieve("http://tiebapic.baidu.com/forum/w%3D580%3B/sign=d673df0037a446237ecaa56aa819730e/342ac65c1038534340a3225b8413b07eca808858.jpg",'NERO.jpg')
然后你就会发现你的文件夹里出现了尼禄酱的图片。。。
- urlencode函数可以把字典数据转换成URL编码的数据。
from urllib import parse #不是request了
date={'name':'钢板日川','age':18,'}
qs = parse.urlencode(qs)
print(qs)
>>>name=%E9%92%A2%E6%9D%BF%E6%97%A5%E5%B7%9D&age=18
其实当我们发送的请求含有中文字符,浏览器会自动给我们编码。但是urlopen的url有汉字就会报错。就用这个urlencode函数进行编码。注意操作的是字典。
**parse.quote('蔷薇‘)**这个函数可以操作字符串进行编码。
-
parse_qs函数将经过编码的url参数进行解码。
parse.parse_qs(qs))
-
urlparse和urlsplit 对一个url中的各个部分进行分割。urlparse和urlsplit基本上是一样的,不同的是:urlparse有params属性(可选参数),ursplit没有这个属性的
a = parse.urlparse('https://www.baidu.com/s?ie=utf-8&fr=bks0000&wd=%E8%94%B7%E8%96%87')
>>> a
ParseResult(scheme='https', netloc='www.baidu.com', path='/s', params='', query='ie=utf-8&fr=bks0000&wd=%E8%94%B7%E8%96%87', fragment='') #query:查询的意思,为了在数据库中寻找某一特定文件、网站、记录或一系列记录
>>> a.fragment #锚点,就是#后面的
''
>>> a.scheme
'https'
- request.Request类 如果想要在请求的时候增加一些请求头(User-Agent用户代理UA),那么必须使用request.Request类来说实现。
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
rq = request.Request('https://www.baidu.com/',headers=headers)
resp= request.urlopen(rq)
print(resp.read().decode()) #decode()解码,增加可读性.resp.read()是一个bytes对象
你就会发现,获取到内容远比不加请求头的多。可以到网页源代码 ctrl + F 搜索你得到的某些句子,这些都会在源代码中找到。
- ProxyHandler处理器(代理设置) 很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,就会禁止这个ip的访问。就可以使用代理服务器去访问(西刺免费代理IP,快代理,代理云啥的,当然免费的IP是不稳定的,多试几个)。
url = 'http://httpbin.org/ip' #这个网站能获取请求的信息,就像ip地址啥的,但是要翻墙。。。
handler = request.ProxyHandler({'http':'122.193.244.243:9999'}) #从代理网站复制的IP 最后要加上端口号的。
opener = request.bulid_open(handler)
resp = opener.open(url) #使用opener去发送一个请求
print(resp.read())
opener是 urllib.request.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构建好的)。
我们采用urlopen()的方式去请求,其实是有些局限性的,比如我们需要打开debug模式,或通过代理模式去请求,就不行了。如果要实现debug模式或代理请求的话,我们需要自己定义Handler和opener。
可以使用相关的 Handler处理器 来创建特定功能的处理器对象;
然后通过 urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象;
使用自定义的opener对象,调用open()方法发送请求。
如果程序里所有的请求都使用自定义的opener,可以使用urllib.request.install_opener() 将自定义的 opener 对象 定义为 全局opener,表示如果之后凡是调用urlopen,都将使用这个opener(根据自己的需求来选择)
在urllib库中,给我们提供了一些Handler,如:HTTPHandler,HTTPSHandler,ProxyHandler,BaseHandler,AbstractHTTPHandler,FileHandler,FTPHandler,分别用于处理HTTP,HTTPS,Proxy代理等。
(说不出来的难受,,,太乱了,,我就找不到一个能完整深入的讲出相关知识的资料,,如果有人能推荐个那就好了。。。)
函数 | 方法 |
---|---|
request.urlopen() | 返回页面源代码一个HTTPResponse对象 |
urlretrieve() | 方便的将网页上的一个文件保存到本地 |
urlencode() | 可以把字典数据转换成URL编码的数据。parse模块方法 |
parse.quote() | 这个函数可以操作字符串进行编码。parse模块 |
parse_qs() | 将经过编码的url参数进行解码。parse.parse_qs(qs)) |
urlparse和urlsplit | 对一个url中的各个部分进行分割。urlparse和urlsplit基本上是一样的,不同的是:urlparse有params属性(可选参数),ursplit没有这个属性的也是parse模块的 |
request.Request() | 如果想要在请求的时候增加一些请求头(User-Agent用户代理UA,cookie),那么必须使用request.Request类来说实现。 |
ProxyHandler处理器 | 代理设置 |
对parse模块做个总结:
一、获取url参数
- 解析url(urlparse)
from urllib import parse
url = 'http://ccforever/get_page?page=1&index=1'
b = parse.urlparse(url)
print(b)
ParseResult(scheme='http', netloc='ccforever', path='/get_page', params='', query='page=1&index=1', fragment='')
- 获取query参数(parse_qs)
a.直接获取queryprint(b.query)
b.解析query参数 或编码过的urlc = parse.parse_qs(b.query)
注意:当query参数中有 ‘ + ’ 的时候,会被解码,并不是我们想要的
d = parse.parse_qs('page=7464ssfa18f46+78dasf&index=2')
print(d)
{'page': ['7464ssfa18f46 78dasf'], 'index': ['2']}
二、编码成url参数(urlencode)
from urllib import parse
url_dict = {
'name': 'Alan Walker', # 此处中间多了空格
'page': 1,
'index': 1
}
f = urllib.parse.urlencode(url_dict)
print(f)
结果为:
name=Alan+Walker&page=1&index=1 # 结果处中间的空格变成了‘+’
三、(编码)quote/quote_plus
from urllib import parse
url = 'http://ccforever/get_page++?*-&%$#@!'
g = parse.quote(url)
print(g) >>>http%3A//ccforever/get_page%2B%2B%3F%2A-%26%25%24%23%40%21 # 编码除斜线 ‘/’外所有符号
g = parse.quote_plus(url)
print(g) >>>http%3A%2F%2Fccforever%2Fget_page%2B%2B%3F%2A-%26%25%24%23%40%21 # 编码包括斜线 ‘/’的所有符号
四、(解码)unquote/unquote_plus
①unquote
unquote(string, encoding=‘utf-8’, errors=‘replace’)
from urllib import parse
url = 'http%3A%2F%2Fccforever%2Fget_page%2B%2B%3F%2A-%26%25%24%23%40%21'
g = parse.unquote(url)
print(g)
>>>
http://ccforever/get_page++? # 此处未解码 ‘+’号
②unquote_plus
from urllib import parse
url = 'http%3A%2F%2Fccforever%2Fget_page%2B%2B%3F%2A-%26%25%24%23%40%21'
g = parse.unquote_plus(url)
print(g)
>>>
http://ccforever/get_page ? #此处将 ‘+’号解码为空格
。。。待续,,,,,,,,,,,,,,,