1. requests 庫的使用
安裝
pip install requests
發(fā)送請(qǐng)求
(1)請(qǐng)求方式
- Get 查看資源
- POST 增加資源
- PUT 修改資源
- PATCH 少量修改資源
- DELETE 刪除資源
- HEAD 查看響應(yīng)頭
- OPTIONS 查看可用的請(qǐng)求方法
(2)請(qǐng)求api
- get 方式 后面跟拼接參數(shù): requests.get(url, params={'key1':'value1'})
- 表單參數(shù)提交: requests.post(url, data={'key1':'value1','key2':'value2'})
- json 參數(shù)提交 requests.post(url, json={'key1':'value1','key2':'value2'})
- 提交文件 requests.post(url, files={'file':open('sss.csv','rb')})
(3)請(qǐng)求異常處理(異常放在requests.exceptions包內(nèi))
- 請(qǐng)求超時(shí)處理:except exceptions.Timeout
requests.get(url, timeout=10) - 錯(cuò)誤碼異常處理 except exceptions.HTTPError
如果響應(yīng)的狀態(tài)碼不為200,response.raise_for_status() 會(huì)拋出狀態(tài)碼異常:response.raise_for_status()
import requests
from requests.exceptions import Timeout, ConnectionError, RequestException,.HTTPError
try:
resp = requests.get('http://httpbin.org/get', timeout=0.5)
print(resp.status_code)
except Timeout: # 訪問超時(shí)的錯(cuò)誤
print('Timeout')
except ConnectionError: # 網(wǎng)絡(luò)中斷連接錯(cuò)誤
print('Connect error')
except RequestException: # 父類錯(cuò)誤
print('Error')
except HTTPError: # 錯(cuò)誤碼
print('響應(yīng)狀態(tài)非200')
Demo
//偽造頭信息
headers = {"Host":" music.163.com",
"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
}
requests.get(url,headers = headers)
# 文件上傳
files = {'file' : open('logo.gif','rb')}
resp = requests.post('http://httpbin.org/post', files=files)
解析響應(yīng)
1.響應(yīng)狀態(tài)碼:
1XX:消息
2XX 請(qǐng)求成功:
200 返回響應(yīng)成功 201 資源建立成功 204 成功響應(yīng)周拐,無返回
3XX 重定向:
301 永久移動(dòng) 302 暫時(shí)移動(dòng) 304 上次的get請(qǐng)求訪問過的內(nèi)容
4XX 客戶端錯(cuò)誤:
400 請(qǐng)求有問題 401 認(rèn)證問題 403 權(quán)限不足宾抓,服務(wù)器拒絕執(zhí)行 404 頁面不存在
5XX 服務(wù)器端錯(cuò)誤:
500 服務(wù)器端有bug 501 無法識(shí)別請(qǐng)求的方法502 網(wǎng)關(guān)錯(cuò)誤 503 服務(wù)不可用
2. 響應(yīng)的api
基本api
status_code 狀態(tài)碼
reason 響應(yīng)情況
headers 獲取響應(yīng)頭
url( 響應(yīng)的地址
request 獲得響應(yīng)對(duì)應(yīng)的請(qǐng)求的對(duì)象揉稚,有headers 和 body
內(nèi)容相關(guān)的api:
- content() 讀取二進(jìn)制內(nèi)容 常用于圖片下載
- text() 解析為解碼后的字符串(可以修改requests.encoding = 'utf-8' 默認(rèn)是utf-8)
- json() 將json格式的響應(yīng)解析為python中的字典
demo
一.圖片下載
from contextlib import closing
url = 'http://pic.58pic.com/58pic/16/42/96/56e58PICAu9_1024.jpg'
#偽造頭信息
headers = {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0)
Gecko/20100101 Firefox/51.0'}
#關(guān)閉流的方式發(fā)送請(qǐng)求
with closing(requests.get(url,headers=headers)) as response:
with open('demo.jpg','wb') as f:
#每128個(gè)字節(jié)寫入一次文件
for chunk in response.iter_content(128):
f.write(chunk)
二和蚪、事件鉤子(Event Hooks) 發(fā)送請(qǐng)求恤左,在獲取響應(yīng)時(shí)回調(diào)鉤子函數(shù)
import requests
def func(response,*args,**kws):
pass
requests.get(url,hooks=dict(response=func))
使用進(jìn)階
(1) HTTP認(rèn)證
基本認(rèn)證,驗(yàn)證賬號(hào)與密碼
requests.get(url,auth=(name,password))OAUTH認(rèn)證
from requests.auth import AuthBase
class GitHubAuth(AuthBase):
def __init__(self, token):
self.token= token
def __call__(self,r):
#request 加headers
r.headers['Authorization'] = ' '.join(['token', self.token])
def oauth_advanced():
#傳入access token
auth = GithubAuth('dddsfsdfsdfasf')
response = requests.get(url,auth = auth)
- 代理設(shè)置
有些網(wǎng)站會(huì)限制 IP 訪問頻率鸣皂,超過頻率就斷開連接摔踱。這個(gè)時(shí)候我們就需要使用到代理虐先,我們可以通過為任意請(qǐng)求方式提供proxies
參數(shù)來配置單個(gè)請(qǐng)求。
import requests
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
resp = requests.get('http://www.baidu.com', proxies=proxies)
print(resp.status_code)
也可以通過環(huán)境變量 HTTP_PROXY
和 HTTPS_PROXY
來配置代理派敷。
有些代理需要加上用戶名和密碼的蛹批,代理可以使用http://user:password@host/
語法,比如:
proxies = {
"http": "http://user:pass@10.10.1.10:3128/",
}
2. xpath的使用
安裝
pip install lxml
Demo
from lxml import etree
# 字符串讀取html
html_str = '''
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
html = etree.HTML(html_str)
#也可以從文件讀取html html = etree.parse('hello.html')
res = html.xpath("http://div/ul/li[@class='item-0']/a")
for e in res:
print(e.text)
print(e.get("href"))
xpath語法
1. 獲取 <li> 標(biāo)簽的所有 class
result = html.xpath('//li/@class')
print result
運(yùn)行結(jié)果:
['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
2. 獲取 <li> 標(biāo)簽下 href 為 link1.html 的 <a> 標(biāo)簽
result = html.xpath('//li/a[@href="link1.html"]')
print result
運(yùn)行結(jié)果
[<Element a at 0x10ffaae18>]
3. 獲取 <li> 標(biāo)簽下的所有 <span> 標(biāo)簽
不能這樣寫:result = html.xpath('//li/span')
因?yàn)?/ 是用來獲取子元素的篮愉,而 <span> 并不是 <li> 的子元素腐芍,所以,要用雙斜杠
result = html.xpath('//li//span')
print result
運(yùn)行結(jié)果
[<Element span at 0x10d698e18>]
4. 獲取 <li> 標(biāo)簽下的所有 class试躏,不包括 <li>
result = html.xpath('//li/a//@class')
print result
運(yùn)行結(jié)果
['blod']
5. 獲取最后一個(gè) <li> 的 <a> 的 href
result = html.xpath('//li[last()]/a/@href')
print result
運(yùn)行結(jié)果
['link5.html']
6. 獲取倒數(shù)第二個(gè)元素的內(nèi)容
result = html.xpath('//li[last()-1]/a')
print result[0].text
運(yùn)行結(jié)果
fourth item
7. 獲取 class 為 bold 的標(biāo)簽名
result = html.xpath('//*[@class="bold"]')
print result[0].tag
運(yùn)行結(jié)果
span
進(jìn)階用法
# 對(duì)節(jié)點(diǎn)進(jìn)行xpath查詢 處理字段缺失
tables = html.xpath("http://div[@class='indent']//table")
for table in tables:
score = table.xpath(".//span[@class='rating_nums']")[0].text
description = "暫無簡(jiǎn)介"
node = table.xpath(".//span[@class='inq']")
if node:
description = node[0].text
# 獲取某節(jié)點(diǎn)內(nèi)所有文字內(nèi)容
# <li class="item-1">sss <a href="link2.html">second item</a> ss</li>
res = html.xpath('//li')[1]
text = res.xpath('string(.)')
print(l1)
# 結(jié)果: sss second item ss
進(jìn)階
MongoDB的使用 設(shè)置下載緩存和實(shí)現(xiàn)多進(jìn)程任務(wù)