爬虫小白:02-urllib的使用

urllib的使用

一、request模块

http://httpbin.org 是github的http测试的接口。httpbin.org 这个网站能测试 HTTP 请求和响应的各种信息,比如 cookie、ip、headers 和登录验证等,且支持 GET、POST 等多种方法,对 web 开发和测试很有帮助。

导入模块:
1、import urllib
使用:urllib.request.
但这样会报错: AttributeError: module 'urllib' has no attribute 'request'
原因:在python3中request被作为一个模块,而不是方法。
解决方法:将request作为一个模块,如import urllib.request。

2、from urllib import request
requset.

1、urlopen()方法:是一个简单发送网络请求的方法。它接收一个字符串格式的 url ,它会向传入的 url发送网络请求,然后返回结果。
参数:
(1)url='' #字符串格式
例:
import urllib
response =urllib.request.urlopen(url='http://httpbin.org/get')

(2)data:是可选的,传入它则会发起POST请求,否则默认会发送get请求。data参数是字节 类型、或者类文件对象或可迭代对象。
import urllib import request
response = request.urlopen(url='http://httpbin.org/post',
data=b'username=wsq&password=123')

用data就是post请求,字节类型,用b''来转换成字节,且data中的数据会作为表单中的数据。

(3)timeout:设置超时时间,以秒为单位。如果请求超过设置时间,则抛出异常;若没有指定 则用系统默认设置。timeout参数只对 http、https以及ftp连接起作用。
报错会出现:urllib.error.URLError:
from urllib
response =urllib.request.urlopen(url='http://www.baidu.com',
timeout=0.1)
2、Request类:
解释:利用urlopen()可以发起最基本的请求,但这几个参数不足以构件一个完整的请求,可以利用 Request对象来构建更加完整的请求。
(1) 请求头添加:
from urllib import request
headers={
'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64rv:73.0) Gecko/20100101 Firefox/73.0"
} #注意:一定是字典形式。
req = request.Request(url='http://www.baidu.com',headers = headers)

reponse = request.urlopen(req)
Referer:这个涉及防盗链技术,假如爬取一个图片出现403,在请求头里添加上它,大多数都 可以解决。

(2) 操作Cookie。(但不会用它操作,日后常用request)
(3) 设置代理:自己写个代理库。(间接请求,保护自己的IP地址)
(4) 验证:

3、Response对象:
urllib库中的类或者方法,在发送网络请求后,都会返回一个urllib.response的对象(例如: http.client.HTTPResponse object at ......)
它包含了请求回来的数据结果。它包含一些属性和方法,供我们处理返回的结果。

(1)、read():获取响应返回的数据,只能用一次。和文件句柄一样,只能运行一次。#返回的是字节码,decode() 解码成字符串。
(2)、readline():读取一行。没必要。
while True:
data = response.readline()
if data:
print(data)
(3)、info():获取响应头信息。 print(response.info())
(4)、geturl():获取访问的url。 print(response.geturl())
(5)、getcode() :返回状态码。 print(response.getcode())

二、parse模块

parse模块是一个工具模块,提供了需要对url处理的方法,用于解析url。
注意: url中只能包含ascii字符,在实际操作过程中,get请求通过url传递的参数中会有大量特殊字符 (非ascii字符),例如汉字,那么就需要进行url编码。(一个中文用UTF-8有3个字节。)
导包:from urllib import parse(import urllib不行问题同上)

方法:
1、parse.quote():编码
例: url = 'http://httpbin.org/get?username={}'
result = url.format(parse.quote('思齊')) #format方法别忘了
print(result)

结果为: http://httpbin.org/get?username=%E6%80%9D%E9%BD%8A

2、parse.unquote():反编码,看看具体参数是什么。
例1:
print(parse.unquote(result))

结果为: http://httpbin.org/get?username=思齊

3、parse.urlencode():在发送请求时,往往会需要传递很多的参数,如果用字符串拼接会很麻 烦,该方法就是用来拼接url参数的。
例1: args = {'username':'思齊','password':'小淘'}
res = parse.urlencode(args) #注意字典形式
print(res)

结果为: username=%E6%80%9D%E9%BD%8A&pd=123

例2:
args = {'username':'思齊','pd':'123'}
result = 'http://httpbin.org/get?{}'.format(parse.urlencode(args))
print(res)

结果为: http://httpbin.org/get?username=%E6%80%9D%E9%BD%8A&pd=123

注:url中规定多个参数 & 连接。

4、parse.parse_qs(): 和parse.urlencode()是相反的,将它转会字典。
例:print(parse.parse_qs(res))

结果为:{'username': ['思齊'], 'pd': ['123']}

{'http://httpbin.org/get?username': ['思齊'], 'pd': ['123']}

错误信息:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) #当出现这种错误时就是参数用的不是ascii码。

三、error模块

error模块主要负责异常处理,如果请求出现错误,我们可以用error模块进行处理,该模块主要包含
URLError和HTTPError

导包:from urllib import error
1.URLError:是error模块的基类,由request模块产生的的异常都可以用这个类来处理。

2.HTTPError:是的子类,主要包含三个属性:code:请求的状态码、reason:错误的原因、headers: 响应的报头。
例:
try:
request.urlopen('https://www.jianshu.com')#不是合法的用户会被 ban。
except error.HTTPError as e:
print(e.code)
print(e.reason)
print(e.headers)

四、robotparse模块

robotparse模块主要负责处理爬虫协议文件,robots.txt的文件。
导包:from urllib import robotparse
https://www.amazon.cn/robots.txt #亚马逊中国的爬虫协议,如图1

urllib3的使用

介绍:是一个基于python3的功能强大,友好的http客户端。
保证线程安全(不需考虑锁的问题),连接池保持(而不向之前的一样连一下关一下),支持重复请求、重定位,保证代码百分百被使用。

导包:import urllib3

(1)构造请求(request):
1.实例化一个PoolManager对象构造请求,这个实例对象处理了连接池和线程安全的所有细节,所以我们不用自行处 理。
例: http = urllib3.PoolManager()
在这里我出现了一个错误,如下:
AttributeError: module 'urllib3的使用' has no attribute 'PoolManager',我出现 这个原因是py文件所在的文件夹命名为urllib3。

2.用request()方法发送请求,可以用request()方法发送任意请求,GET POST....
第一个参数是何种类型的请求;第二个参数是请求的网站。

例1:发送get请求
response = http.request('GET','http://httpbin.org/get ',b'User- Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64rv:73.0) Gecko/20100101 Firefox/73.0')
此处传的二进制数据报错

例2:发送POST请求
response = http.request('POST','http://httpbin.org/post',
fields={'hello':'world'})

3.请求传入数据(data):

  • Headers:加入请求头
    在request方法中添加字典格式的headers参数来指定请求头。
    例:http = urllib3.PoolManager()
    response = http.request('POST','http://httpbin.org/get ',
    headers={'key':'value'})

  • Query parameters(字符串参数):
    *get,head,delete请求,可通过提供字典类型的参数fields来添加查询参数。(复习一 下:在urllib中我们通过parse.quote()编码这里只需提供fields参数即可)
    例:http = urllib3.PoolManager()
    response = http.request('get','http://httpbin.org/get ',
    fields={'key':'value'})

*对于post,put请求,如果需要查询参数,需要通过url编码将参数编码正确格式再拼接到url中。
例: 如图1、2、3
import urllib3
import urllib.parse import urlencode
import json
http = urllib3.PoolManager()
args = {'username':'思齊','password':'小淘'}

方法一:

result = urlencode(args)
url = 'http://httpbin.org/post?' + result #字符串拼接

方法二:

url1 = 'http://httpbin.org/post?{}'
url1 = url.format(parse.urlencode(args))


response = http.request('POST',url)
print(json.loads(response.data.decode('utf-8')))

*form data(表单数据):
对于post,put,需要提供字典类型的参数fields来传递form表单数据。
response = http.request('post','http://httpbin.org/get ',
fields={'key':'value'})

*json数据
当我们需要发送json数据时,我们需要在request方法中传入编码后的二进制数据类型的body参数,并 指定Content-Type的请求头。

*文件上传(通常不用这个上传)
对于文件上传,我们可以模仿浏览器表单的方式

对于二进制数据上传,我们用指定body的方式,并设置Content-Type的请求头。

*注意:get,head,delete请求中提供fields参数会自动拼接到url中,而对post,put请求中你提供的 fields参数会填写到form表单中,若你想拼接到url中只能主动的使用字符串拼接的方法。
(2)http响应对象提供 status、data、headers等属性
例1:
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/get')
print(type(response))#返回的是

也就是http响应对象

print(response.data) #返回的是二进制数据
print(response.headers)#返回的是

字典形式,因此可以通过键名看键值

print(response.status)

(3)返回的是 json格式数据 可以通过json模块,loads为字典数据类型。
例:
import urllib3
import json
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/ip')
print(json.load(response.data.decode('utf-8')))

// response.data.decode('utf-8') 解码成字符串。

(4)返回的数据都是字节类型,对于大量的数据我们通过stream(流)来处理更好,也可以当作一个文件对象来处理。
例1:流
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/bytes/1024',
preload_content = False)
for i in response.stream(32): #一点点读对内存好,下图片就可以用这种方法
print(i)

例2:文件对象
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/bytes/1024', preload_content = False)
for line in response: #比如说大文件可能5G大小,不能一次性回来,一批一批的回来
print(line)

(5)代理
例1:import urllib3
proxy = urllib3.ProxyManager('http://ip:端口号')
//用这个ip来帮助你来向某网站发送请求,保护了你自己的ip地址不被暴露。

response = proxy.request('get','http://httpbin.org/ip')
//http://httpbin.org/ip 查看请求的ip地址

print(response.data)

//遇到如下错误urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='115.210.79.22', port=8118): Max retries exceeded with url: http://httpbin.org/ip (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused',))) 如果是初次使用代理,以上三 种错误出现的原因基本是1.端口错误2.代理类型不正确。 明确的一点是访问https站点,要用https类型的代理。http同理。(当然我找的是免费代理,可能不好用。)

你可能感兴趣的:(爬虫小白:02-urllib的使用)