一、requests模块
使用前需安装requests库pip install requests
。
requests库的七个主要方法:
方法 | 解释 |
---|---|
requests.request() | 构造一个请求,支持以下各种方法 |
requests.get() | 获取html的主要方法 |
requests.head() | 获取html头部信息的主要方法 |
requests.post() | 向html网页提交post请求的方法 |
requests.put() | 向html网页提交put请求的方法 |
requests.patch() | 向html提交局部修改的请求 |
requests.delete() | 向html提交删除请求 |
requests.request(method,url,**kwargs)
构造一个服务器请求request:
- method: “GET”、”POST”、”HEAD”、”PUT”、”PATCH”、”DELETE”
- url: 请求的网址
- **kwargs: 控制访问的参数
params:字典或字节序列,作为参数增加到url中,使用这个参数可以把一些键值对以?key1=value1&key2=value2的模式增加到url中
例如:kw = {‘key1: ’ values’, ‘key2’: ‘values’}
r = requests.request(‘GET’, ‘http:www.python123.io/ws’, params=kw)data:字典,字节序或文件对象,重点作为向服务器提供或提交资源是提交,作为request的内容,与params不同的是,data提交的数据并不放在url链接里, 而是放在url链接对应位置的地方作为数据来存储。,它也可以接受一个字符串对象。
json:json格式的数据, json合适在相关的html,http相关的web开发中非常常见, 也是http最经常使用的数据格式, 他是作为内容部分可以向服务器提交。
例如:kv = {”key1’: ‘value1’}
r = requests.request(‘POST’, ‘http://python123.io/ws‘, json=kv)headers:字典是http的相关语,对应了向某个url访问时所发起的http的头i字段, 可以用这个字段来定义http的访问的http头,可以用来模拟任何我们想模拟的浏览器来对url发起访问。
例子: hd = {‘user-agent’: ‘Chrome/10’}
r = requests.request(‘POST’, ‘http://python123.io/ws‘, headers=hd)cookies:字典或CookieJar,指的是从http中解析cookie
auth:元组,用来支持http认证功能
files:字典, 是用来向服务器传输文件时使用的字段。
例子:fs = {‘files’: open(‘data.txt’, ‘rb’)}
r = requests.request(‘POST’, ‘http://python123.io/ws‘, files=fs)timeout: 用于设定超时时间, 单位为秒,当发起一个get请求时可以设置一个timeout时间, 如果在timeout时间内请求内容没有返回, 将产生一个timeout的异常。
proxies:字典, 用来设置访问代理服务器。
allow_redirects: 开关, 表示是否允许对url进行重定向, 默认为True。
stream: 开关, 指是否对获取内容进行立即下载, 默认为True。
verify:开关, 用于认证SSL证书, 默认为True。
cert: 用于设置保存本地SSL证书路径
返回一个包含服务器资源的response对象,具有以下属性和方法:
属性 | 说明 |
---|---|
r.status_code | http请求的返回状态,若为200则表示请求成功。 |
r.text | http响应内容的字符串形式,即返回的页面内容 |
r.encoding | 从http header 中猜测的相应内容编码方式 |
r.apparent_encoding | 从内容中分析出的响应内容编码方式(备选编码方式) |
r.content | http响应内容的二进制形式 |
r.raw | 返回原始响应体,使用r.raw.read()读取 |
r.headers | 以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None |
r.json() | Requests中内置的JSON解码器 |
r.raise_for_status() | 失败请求(非200响应)抛出异常 |
1 | # requests库 |
1、发送请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import requests
#1.发送get请求
res = requests.get("http://httpbin.org/get")
#2.发送post请求
res = requests.post("http://httpbin.org/post", data={"key":"value",...})
#3.发送head请求
res = requests.head("http://httpbin.org/get")
#4.发送put请求
res = requests.put("http://httpbin.org/put",data={"key":"value", ...})
#5.发送delete请求
res = requests.delete("http://httpbin.org/delete")
#6.发送patch请求
res = requests.patch("http://httpbin.org/get")
2、构造请求参数
(1)get请求参数
1
2
3
4
5
6
7
8
9
10 import requests
def function():
#1.请求参数
payload = {'key1':'value1', 'key2':'value2', 'key3':['value3','value4']} #注意:请求值可以传入列表
#2.拼接url= http://httpbin.org/get?key1=value1&key2=value2&key3=value3&key3=value4
res = requests.get("http://httpbin.org/get", params=payload) #注意:参数是params
print(res.text)
(2)post请求表单
1
2
3
4
5
6
7
8
9
10
11
12
13 import requests
def function():
#1.表单数据
payload1 = {'key1':'value1','key2':'key2'} #注意:一键单值用字典
payload2 = {('key1', 'value1'), ('key1', 'value2')} #注意:一键多值用元组
#2.拼接url
res1 = requests.post("http://httpbin.org/post",data=payload1) #注意:参数是data
res2 = requests.post("http://httpbin.org/post",data=payload2)
print(res1.text)
print(res2.text)
(3)post请求json
1
2
3
4
5
6
7 def function():
#1.post提交json对象数据
payload = {'key1': 'value1', 'key2': 'value2'}
#2.拼接url
res = requests.post("http://httpbin.org/post",data=json.dumps(payload))# 方式一
res = requests.post("http://httpbin.org/post",json=payload)# 方式二
(4)构造请求头headers
1
2
3
4
5
6
7
8
9 def function:
#1.构造请求头
headers = {'user-agent':'my-app/0.0.1'}
#2.定义url
url = "https://api.github.com/some/endpoint"
#3.拼接url
res = requests.get(url, headers=headers)
(5)构造cookies请求
1
2
3
4
5
6
7
8
9 def function():
#1.构造cookies
cookies = dict(sessionId='Jsession3123131')
#2.定义url
url = "http://httpbin.org/cookies"
#3.拼接url
res = requests.get(url, cookies=cookies)
(6)构造请求超时设置
1
2
3
4 def function()
## 设置请求超时:0.1秒没响应就请求超时失败
requests.get('http://github.com',timeout=0.1)
(7)基本身份认证
(HTTP Basic Auth)
1
2
3
4
5
6
7
8 import requests
from requests.auth import HTTPBasicAuth
#身份验证
r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd'))
# r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=('user', 'passwd')) # 简写
print(r.json())
3、响应内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 import requests
def function()
#发送请求
url = "https://api.github.com/some/endpoint"
payload = {'key1':'value1','key2':'key2'}
headers = {'user-agent':'my-app/0.0.1'}
cookies = dict(sessionId='Jsession3123131')
res = requests.post(url,data=payload,headers=headers,cookies=cookies)
#文本数据信息,大部分情况使用这个方法
text = res.text
#原始二进制响应数据
content = res.content
# json响应数据,通常我们使用json模块来处理
json_data = res.json()
# 响应状态码
status_code= res.status_code
# 响应头
headers = res.headers
# 响应cookies
cookies = res.cookies
#使用响应对象的history方法来追踪重定向
res.history
二、urllib模块
python内置http请求库urllib:
- urllib.request:用于访问和读取URLS
- urllib.error:包括了所有urllib.request导致的异常
- urllib.parse:用于解析URLS
- urllib.robotparser:用于解析robots.txt文件(网络蜘蛛)
1、urllib.request
(1)基本方法urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- url: 需要打开的网址
- data:Post提交的数据
- timeout:设置网站的访问超时时间
urlopen返回对象提供方法:
geturl()
:返回请求的url,通常用于确定是否遵循重定向。info()
:返回HTTPMessage对象,表示远程服务器返回的头信息getcode()
:返回Http状态码。如果是http请求,200请求成功完成;404网址未找到read()
,readline()
,readlines()
:返回页面元素fileno()
,close()
:对HTTPResponse类型数据进行操作,这些方法的使用方式与文件对象完全一样
1
2
3
4
5
6
7
8 from urllib import request
page = request.urlopen("http://www.baidu.com/")
print(page.info())
print(page.getURL())
print(page.getcode())
print(page.read())
(2)设置代理urllib.request.build_opener([handler, …])
urllib.request.install_opener(opener)
做爬虫的时候,多都会用到代理IP的,步骤如下:
1)利用urllib.request.ProxyHandler准备代理IP或者请求头。
2)利用urllib.request.build_opener()封装代理IP或请求头。
3)利用urllib.request.instanll_opener()安装成全局。
4)利用urllib.request.urlopen访问网页。
1
2
3
4
5
6
7
8
9 from urllib import request
proxy_support = request.ProxyHandler({'sock5': 'localhost:1080'})
opener = request.build_opener(proxy_support)
request.install_opener(opener)
a = request.urlopen("http://www.baidu.com/ ").read().decode("utf8")
print(a)
(3)使用Requesturllib.request.Request(url, data=None, headers={}, method=None)
使用request()来包装请求,再通过urlopen()获取页面。
1
2
3
4
5
6
7
8
9
10
11
12
13 from urllib import request
url = r'http://www.lagou.com/zhaopin/Python/?labelWords=label'
headers = {
'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
'Referer': r'http://www.lagou.com/zhaopin/Python/?labelWords=label',
'Connection': 'keep-alive'
}
req = request.Request(url, headers=headers)
page = request.urlopen(req).read()
page = page.decode('utf-8')
2、urllib.error
常见的由urllib.request导致的异常:
error.URLError: 是OSError的一个子类,URLError可能产生的原因:
- 网络无连接,即本机无法上网
- 连接不到特定的服务器
- 服务器不存在
error.HTTPError: 是URLError的一个子类,对于不能处理对象response的状态码,urlopen会产生一个HTTPError
- 101: 转换协议 在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。
- 102:继续处理 由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。
- 200:请求成功 处理方式:获得响应的内容,进行处理
- 201:请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到 处理方式:爬虫中不会遇到
- 202:请求被接受,但处理尚未完成 处理方式:阻塞等待
- 204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃
- 300:该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
- 301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL
- 302:请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL
- 304:请求的资源未更新 处理方式:丢弃
- 400:非法请求 处理方式:丢弃
- 401:未授权 处理方式:丢弃
- 403:禁止 处理方式:丢弃
- 404:没有找到 处理方式:丢弃
- 500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
- 501:服务器无法识别 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
- 502:错误网关 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
- 503:服务出错 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from urllib import request
from urllib import error
if __name__ == "__main__":
#一个不存在的连接
url = "http://www.test1.com/test2.html"
req = request.Request(url)
try:
responese = request.urlopen(req)
# html = responese.read()
#想用HTTPError和URLError一起捕获异常,需要将HTTPError放在URLError的前面
except error.HTTPError as e:
print(e.code)
except error.URLError as e:
print(e.reason)
3、urllib.parse
(1)urllib.parse.urlparse(urlstring, scheme=”, allow_fragments=True)
用于将一个URL解析成六个部分,返回一个元组,URL的格式为:scheme://netloc/path;parameters?query#fragment
以下为返回的元组元素:
元素 | 编号 | 值 | 值不存在时默认值 |
---|---|---|---|
scheme | 0 | 请求 | 一定存在 |
netloc | 1 | 网址 | 空字符串 |
path | 2 | 分层路径 | 空字符串 |
params | 3 | 参数 | 空字符串 |
query | 4 | 查询组件 | 空字符串 |
fragment | 5 | 标识符 | 空字符串 |
username | 用户名 | None | |
password | 密码 | None | |
hostname | 主机名 | None | |
port | 端口号 | None |
1
2
3
4
5
6
7 from urllib import parse
o = parse.urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
print(o)
#对应结果:ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='')
(2)urllib.parse.urljoin(base, url, allow_fragments=True)
用于将一个基本的URL和其他的URL组装成成一个完成的URL。
1
2
3
4
5
6
7 from urllib import parse
a=arse.urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
print(a)
#对应结果:http://www.cwi.nl/%7Eguido/FAQ.html
(3)urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None)
urlencode()主要作用就是将url附上要提交的数据。
1
2
3
4
5
6
7
8
9
10
11 from urllib import parse
data = {
'first': 'true',
'pn': 1,
'kd': 'Python'
}
data = parse.urlencode(data).encode('utf-8')
#经过urlencode()转换后的data数据为?first=true?pn=1?kd=Python
#最后提交的url为http://www.lagou.com/jobs/positionAjax.json?first=true?pn=1?kd=Python
4、urllib.robotparser
robotparser为robots.txt文件实现了一个解释器,可以用来读取robots文本的格式和内容,用函数方法检查给定的User-Agent是否可以访问相应的网站资源。如果要编写一个网络蜘蛛,这个模块可以限制一些蜘蛛抓取无用的或者重复的信息,避免蜘蛛掉入动态asp/php网页程序的死循环中。
简单的来说,robots.txt文件是每个网站都应该有的,指引蜘蛛抓取和禁止抓取的一个文本格式的文件,一些合法的蜘蛛或者叫爬虫,都是遵守这个规则的,可以控制他们的访问。
5、GET请求
1
2
3
4
5
6
7
8
9
10
11
12
13 import urllib.request
import urllib.parse
data = {}
data['word'] = 'python3'
url_values = urllib.parse.urlencode(data)
url = "http://www.baidu.com/s?"
full_url = url + url_values
data = urllib.request.urlopen(full_url).read()
z_data = data.decode('UTF-8')
print(z_data)
6、POST数据
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
urlopen()的data参数默认为None,当data参数不为空的时候,urlopen()提交方式为Post。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import urllib.request
import urllib.parse
url = r'http://www.lagou.com/jobs/positionAjax.json?'
headers = {
'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
'Referer': r'http://www.lagou.com/zhaopin/Python/?labelWords=label',
'Connection': 'keep-alive'
}
data = {
'first': 'true',
'pn': 1,
'kd': 'Python'
}
data = parse.urlencode(data).encode('utf-8') #Post的数据必须是bytes或者iterable of bytes,不能是str,因此需要进行encode()编码
req = request.Request(url, headers=headers, data=data)
page = request.urlopen(req).read()
page = page.decode('utf-8')
print(page)
持续更新…
最后更新: 2018年12月04日 21:48