urllib库是python中最基本的网络请求库,可以模拟浏览器的行为,向指定服务器发送一个请求,并保存服务器返回的数据。
在pyhon3的urllib库中,所有的网络请求相关的方法,都被集中到urllib.request模块下。
函数原型如下:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url: 需要打开的网址
data:Post提交的数据
timeout:设置网站的访问超时时间
直接用urllib.request模块的urlopen()获取页面,page的数据格式为bytes类型,需要decode()解码,转换成str类型。
1. url 参数:目标资源在网路中的位置。可以是一个表示URL的字符串(如:http://www.pythontab.com/);也可以是一个urllib.request对象,详细介绍请跳转
2. data参数:data用来指明发往服务器请求中的额外的参数信息(如:在线翻译,在线答题等提交的内容),data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。
3. timeout:设置网站的访问超时时间
4. cafile、capath、cadefault 参数:用于实现可信任的CA证书的HTTP请求。(基本上很少用)
5. context参数:实现SSL加密传输。(基本上很少用)
三. 返回处理方法详解
urlopen返回对象提供方法:
read() , readline() ,readlines() , close() :对HTTPResponse类型数据进行操作
info():返回HTTPMessage对象,表示远程服务器返回的头信息
getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
geturl():返回请求的url
四. 版本区别, 注意事项
python2和python3在导入urlrequest的方式都不一样。
python2是这样:import urllib2
而python3里面把urllib分开了,分成了urlrequest和urlerror,在这里我们只需导入urlrequest即可。from urllib.request import urlopen
这个函数可以方便的将网页上的文件保存到本地。
req.urlretrieve("https://bkimg.cdn.bcebos.com/pic/cdbf6c81800a19d85413042d3cfa828ba61e4682?x-bce-process=image/watermark,g_7,image_d2F0ZXIvYmFpa2UxMTY=,xp_5,yp_5"
,"song.jpg")
第一个参数是图片的地址,第二参数是文件的名称,如果参数中带文件路径则会下载具体的目录下,如果没有就下载到py文件同目录下。
req.urlretrieve("https://bkimg.cdn.bcebos.com/pic/cdbf6c81800a19d85413042d3cfa828ba61e4682?x-bce-process=image/watermark,g_7,image_d2F0ZXIvYmFpa2UxMTY=,xp_5,yp_5"
,"D:\\1340109116\\workspacet\\songHui.jpg")
用浏览器发送请求的时候,如果url中包含了中文或者其它特殊字符,那么浏览器会自动给我们进行编码,(用%加十六进制数字%)。如果我们用代码请求,就需要特殊处理下进行参数编码。这个时候就需要使用urlencode函数。
注意这个函数是在urllib.parse下的。
parm={"name":"福尔摩斯","age":14,"tianshi":"hello"}
res= parse.urlencode(parm)
print(res)
具体用法:
如果我们在百度首页输入汉字:刘德华 我们只留下关键的url信息如下,
如果我们在代码中直接使用地址栏的这个url进行urlopen看能正常结果吗
详细错误信息如下:我们可以看到底层编码是用的ascii,中文并不支持。所以我们需要进行编码
D:\Python\crawler_1\venv\Scripts\python.exe D:/Python/crawler_1/com/crawler/learn_1/Urllib_1.py
Traceback (most recent call last):
File "D:/Python/crawler_1/com/crawler/learn_1/Urllib_1.py", line 3, in
res = req.urlopen("https://www.baidu.com/s?wd=刘德华")
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 163, in urlopen
return opener.open(url, data, timeout)
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 466, in open
response = self._open(req, data)
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 484, in _open
'_open', req)
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 444, in _call_chain
result = func(*args)
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 1297, in https_open
context=self._context, check_hostname=self._check_hostname)
File "D:\Python\PaythonInstall\lib\urllib\request.py", line 1254, in do_open
h.request(req.get_method(), req.selector, req.data, headers)
File "D:\Python\PaythonInstall\lib\http\client.py", line 1106, in request
self._send_request(method, url, body, headers)
File "D:\Python\PaythonInstall\lib\http\client.py", line 1141, in _send_request
self.putrequest(method, url, **skips)
File "D:\Python\PaythonInstall\lib\http\client.py", line 983, in putrequest
self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-12: ordinal not in range(128)
Process finished with exit code 1
注意,百度会把http协议转成https,代码中直接调用https也会不通的。使用http协议然后把中文转码之后可以正常请求了。
有了编码就有转码:parse_qs
有时候要对url中的各个组成部分就行分割,我们就可以用urlparse,urlsplit。在parse模块下。实例如下:
可以看到url被分成:协议,域名,路径,参数,锚。我们可以分别获取各部分内容进行使用。
对于有些反爬虫的网站,我们直接urlopen是得不到信息的,比如拉钩网。如果我们直接根据下图找到的url请求的话看下得到什么:
得到一小段看不懂的返回,结果前面看到是以b开头的,
url="https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput="
res=req.urlopen(url)
print(res.read())
******************************************************
b'\n\n\n\n\t\n\tDocument \n\t\n\t\n\n\n\t\n\t\t\n\t\t\n\t\t\n\t\xe5\xbd\x93\xe5\x89\x8d\xe8\xaf\xb7\xe6\xb1\x82\xe5\xad\x98\xe5\x9c\xa8\xe6\x81\xb6\xe6\x84\x8f\xe8\xa1\x8c\xe4\xb8\xba\xe5\xb7\xb2\xe8\xa2\xab\xe7\xb3\xbb\xe7\xbb\x9f\xe6\x8b\xa6\xe6\x88\xaa\xef\xbc\x8c\xe6\x82\xa8\xe7\x9a\x84\xe6\x89\x80\xe6\x9c\x89\xe6\x93\x8d\xe4\xbd\x9c\xe8\xae\xb0\xe5\xbd\x95\xe5\xb0\x86\xe8\xa2\xab\xe7\xb3\xbb\xe7\xbb\x9f\xe8\xae\xb0\xe5\xbd\x95\xef\xbc\x81\n\n'
我们可以用decode转码一下得到我们能看懂的内容。
url="https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput="
res=req.urlopen(url)
print(res.read().decode("utf-8"))
***************************************
***此处省略若干****