爬蟲之request模塊
爬蟲之request模塊
request簡介
#介紹:使用requests可以模擬瀏覽器的請求,比起之前用到的urllib,requests模塊的api更加便捷(本質就是封裝了urllib3) #註意:requests庫發送請求將網頁內容下載下來以後,並不會執行js代碼,這需要我們自己分析目標站點然後發起新的request請求 #安裝:pip3 install requests #各種請求方式:常用的就是requests.get()和requests.post() >>> import requests >>> r = requests.get(‘https://api.github.com/events‘) >>> r = requests.post(‘http://httpbin.org/post‘, data = {‘key‘:‘value‘}) >>> r = requests.put(‘http://httpbin.org/put‘, data = {‘key‘:‘value‘}) >>> r = requests.delete(‘http://httpbin.org/delete‘) >>> r = requests.head(‘http://httpbin.org/get‘) >>> r = requests.options(‘http://httpbin.org/get‘) #建議在正式學習requests前,先熟悉下HTTP協議 http://www.cnblogs.com/linhaifeng/p/6266327.html
基於GET請求
基本請求
import requests response=requests.get(‘http://dig.chouti.com/‘) print(response.text)
- 帶參數的get請求
- headers--請求頭
- User-Agent
- 我們要用爬蟲來爬取數據究其本質就是通過腳本模擬瀏覽器來進行操作,在任何一個html界面我們通過f12來調用代碼,通過network選項來找到請求頭進行操作!
一般的網站對於反扒都會加上最基本的User-Agent字段
```python
# 我們來模擬知乎搜索
import requests
reponse=requests.get(‘https://www.zhihu.com/explore‘,
headers={
‘User-Agent‘:‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36‘,
},
)
print(reponse.status_code)
print(reponse.text)
- parms
- 比如在瀏覽器中搜索時,因為瀏覽器不識別漢字,所以我們要進行轉化
- ```python
from urllib.parse import urlencode
params={
‘wd‘:‘美女‘,
}
url=‘https://www.baidu.com/s?%s‘ %urlencode(params,encoding=‘utf-8‘)
print(url)
- 保存爬下來的數據
```python
reponse=requests.get(url,
headers={
‘User-Agent‘:‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36‘,
},
)
print(reponse.status_code) # 打印狀態碼 ## 狀態碼詳解見下一篇文章
print(reponse.text)
reponse.encoding=‘utf-8‘
with open(‘test.html‘,‘w‘,encoding=‘utf-8‘) as f:
f.write(reponse.text)
- 帶參數的GET請求--cookies
```python
#登錄github,然後從瀏覽器中獲取cookies,以後就可以直接拿著cookie登錄了,無需輸入用戶名密碼
#用戶名:egonlin 郵箱[email protected] 密碼lhf@123
import requests
Cookies={ ‘user_session‘:‘wGMHFJKgDcmRIVvcA14_Wrt_3xaUyJNsBnPbYzEL6L0bHcfc‘,
}
response=requests.get(‘https://github.com/settings/emails‘,
cookies=Cookies) #github對請求頭沒有什麽限制,我們無需定制user-agent,對於其他網站可能還需要定制
print(‘[email protected]‘ in response.text) #True
基於POST的請求
- post請求和get請求之間的對比
#GET請求
HTTP默認的請求方法就是GET
* 沒有請求體
* 數據必須在1K之內!
* GET請求數據會暴露在瀏覽器的地址欄中
GET請求常用的操作:
1. 在瀏覽器的地址欄中直接給出URL,那麽就一定是GET請求
2. 點擊頁面上的超鏈接也一定是GET請求
3. 提交表單時,表單默認使用GET請求,但可以設置為POST
#POST請求
(1). 數據不會出現在地址欄中
(2). 數據的大小沒有上限
(3). 有請求體
(4). 請求體中如果存在中文,會使用URL編碼!
#!!!requests.post()用法與requests.get()完全一致,特殊的是requests.post()有一個data參數,用來存放請求體數據
- 發送POST請求,模擬瀏覽器的登錄行為
一 目標站點分析
瀏覽器輸入https://github.com/login
然後輸入錯誤的賬號密碼,抓包
發現登錄行為是post提交到:https://github.com/session
而且請求頭包含cookie
而且請求體包含:
commit:Sign in
utf8:?
authenticity_token:lbI8IJCwGslZS8qJPnof5e7ZkCoSoMn6jmDTsL1r/m06NLyIbw7vCrpwrFAPzHMep3Tmf/TSJVoXWrvDZaVwxQ==
login:egonlin
password:123
二 流程分析
先GET:https://github.com/login拿到初始cookie與authenticity_token
返回POST:https://github.com/session, 帶上初始cookie,帶上請求體(authenticity_token,用戶名,密碼等)
最後拿到登錄cookie
ps:如果密碼時密文形式,則可以先輸錯賬號,輸對密碼,然後到瀏覽器中拿到加密後的密碼,github的密碼是明文
‘‘‘
import requests
import re
#第一次請求
r1=requests.get(‘https://github.com/login‘)
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授權)
authenticity_token=re.findall(r‘name="authenticity_token".*?value="(.*?)"‘,r1.text)[0] #從頁面中拿到CSRF TOKEN
#第二次請求:帶著初始cookie和TOKEN發送POST請求給登錄頁面,帶上賬號密碼
data={
‘commit‘:‘Sign in‘,
‘utf8‘:‘?‘,
‘authenticity_token‘:authenticity_token,
‘login‘:‘[email protected]‘,
‘password‘:‘22222222‘
}
r2=requests.post(‘https://github.com/session‘,
data=data,
cookies=r1_cookie
)
login_cookie=r2.cookies.get_dict()
#第三次請求:以後的登錄,拿著login_cookie就可以,比如訪問一些個人配置
r3=requests.get(‘https://github.com/settings/emails‘,
cookies=login_cookie)
print(‘111111111‘ in r3.text) #Tru
響應Response
- response屬性
```python
import requests
respone=requests.get(‘http://www.jianshu.com‘)
respone屬性
print(respone.text) # 打印響應的頁面的str
print(respone.content) # 打印響應的內容
print(respone.status_code) # 打印響應的狀態碼
print(respone.headers) # 打印頭信息
print(respone.cookies) # 打印cookies
print(respone.cookies.get_dict()) # 打印字典形式的cookies
print(respone.cookies.items()) # 打印列表形式的字典
print(respone.url) # 打印url
print(respone.history) # 打印歷史記錄
print(respone.encoding) # 打印字符編碼
關閉:response.close() # 關閉鏈接
from contextlib import closing
存儲文件
with closing(requests.get(‘xxx‘,stream=True)) as response:
for line in response.iter_content():
pass
```
- 編碼問題
#編碼問題
import requests
response=requests.get(‘http://www.autohome.com/news‘)
# response.encoding=‘gbk‘ #汽車之家網站返回的頁面內容為gb2312編碼的,而requests的默認編碼為ISO-8859-1,如果不設置成gbk則中文亂碼
print(response.text)
- 獲取二進制數據
import requests
response=requests.get(‘https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1509868306530&di=712e4ef3ab258b36e9f4b48e85a81c9d&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F11385343fbf2b211e1fb58a1c08065380dd78e0c.jpg‘)
with open(‘a.jpg‘,‘wb‘) as f:
f.write(response.content)
- 高級用法
- 註:高級用法在這裏只闡述代理用法,其他方法在實際生產環境中所用甚少
#官網鏈接: http://docs.python-requests.org/en/master/user/advanced/#proxies
#代理設置:先發送請求給代理,然後由代理幫忙發送(封ip是常見的事情)
import requests
proxies={
‘http‘:‘http://egon:123@localhost:9743‘,#帶用戶名密碼的代理,@符號前是用戶名與密碼
‘http‘:‘http://localhost:9743‘,
‘https‘:‘https://localhost:9743‘,
}
respone=requests.get(‘https://www.12306.cn‘,
proxies=proxies)
print(respone.status_code)
#支持socks代理,安裝:pip install requests[socks]
import requests
proxies = {
‘http‘: ‘socks5://user:pass@host:port‘,
‘https‘: ‘socks5://user:pass@host:port‘
}
respone=requests.get(‘https://www.12306.cn‘,
proxies=proxies)
print(respone.status_code)
爬蟲之request模塊