本文試用環境:python3
比urllib更強大的python爬蟲請求庫requests,Cookies、登錄驗證、代理設置等操作都有很好的解決
安裝:
pip install requests
引入:
import requests
目錄
1.4、抓取網頁通常加入headers、timeout、time.sleep信息
2.6、其他:SSL 證書驗證、文件上傳、OAuth 認證等
一、基本使用
1.1、一句話的請求
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# pip install requests #安裝
import requests #導入
r=requests.get("https://me.csdn.net/column/weixin_41685388")
#r.encoding ="utf-8" #當出現中文亂碼問題時使用
print(type(r)) #類型:<class 'requests.models.Response'>
print(r. status_code)#狀態:200 或者404、500...等
print(type(r.text)) #響應體的類型:<class 'str'>
print(r.cookies) #cookies:<RequestsCookieJar[<Cookie(.*)/>]>
print(r.text) #頁面內容
#使用get()方法成功實現一個GET請求,這倒不算什麼,
# 更方便之處在於其他的請求類型依然可以用一句話來完成,示例如下:
r1=requests.post('http://httpbin.org/post')
r2=requests.put('http://httpbin.org/put')
r3=requests.delete('http://httpbin.org/delete')
r4=requests.head('http://httpbin.org/get')
r5=requests.options("http://httpbin.org/get")
1.2、get請求的params 參數
import requests
r=requests.get('http://httpbin.org/get?name=germey&age=22')
#<==>等價於
data={'name':'germey','age':22}
r1=requests. get("http://httpbin.org/get", params=data)
print(r1.text)
1.3、post請求的data參數
response=requests.post(url,data=data,headers= Headers,timeout=30) #data爲字典類型
def youdao(input):
import requests
from requests.exceptions import ConnectTimeout
import time
import random
url=r"http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
Headers = { }
Headers["Cookie"]=r'OUTFOX_SEARCH_USER_ID_NCOO=1564612197.2237918; OUTFOX_SEARCH_USER_ID="[email protected]"; _ga=GA1.2.269278628.1571982437; _ntes_nnid=db62add68d78e9de1c202b8b131b32a4,1579175684866; JSESSIONID=aaaGcKLB2j8UhdX6Q3V_w; SESSION_FROM_COOKIE=unknown; ___rl__test__cookies=1579203741289'
Headers["User-Agent"]=r"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
data = { } #post請求需要的data參數,在網頁檢查的Form Data中,
#data["i"]="I am jalen" #認真一點你會發現這就是我們輸入的值,自己做一個簡單的有道翻譯只需要修改這裏就可以實現
data["i"] = input #那就按照習慣在函數外單獨輸入經常變化的值
data["from"]="AUTO"
data["to"]="AUTO"
data["smartresult"]="dict"
data["client"]="fanyideskweb"
data["salt"]="15792037412906"
data["sign"]="324404ee89ccb63c2ea1efb7d311db26"
data["ts"]="1579203741290"
data["bv"]="74b3450c611e373bdb05dc0a4ecdedd0"
data["doctype"]="json"
data["version"]="2.1"
data["keyfrom"]="fanyi.web"
data["action"]="FY_BY_CLICKBUTTION"
rand = random.randint(2, 5)
time.sleep(rand) #延時提交
#請求時data直接用字典格式
try:
response=requests.post(url,data=data,headers= Headers,timeout=30)
#print(response.text)
html = response.json()
#print(html)
tgt = html['translateResult'][0][0][ 'tgt']
print(tgt)
except (ConnectTimeout) as e:
print("ConnectTimeout")
return
if __name__ == '__main__':
input='I am jalen'
youdao(input)
1.4、抓取網頁通常加入headers、timeout、time.sleep信息
- headers:url網頁-->右擊-->檢查(N)-->Network-->F5-->(找到包含所需內容的Name)-->Headers-->Response Headers,常用"Cookie"和"User-Agent"
- timeout:請求響應超時時間限定,超出設定時間報錯:requests.exceptions.ConnectTimeout
- time.sleep:設置延時提交的時間,在實際爬蟲過程中和隨機數聯合使用
import requests
import random
import time
import json
r=requests.get('http://httpbin.org/get?name=germey&age=22')
#<==>等價於
data={'name':'germey','age':22}
Headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'}
rand = random.randint(2, 5)
time.sleep(rand) #延時提交
r1=requests.get("http://httpbin.org/get", params=data,headers= Headers,timeout = 30)
print(type(r1.text))
#print(r1.text)
r1 = r1.json() #str-->json-->dict
print(type(r1)) #查看類型:dict
print(r1) #輸出json格式的結果
'''
<class 'str'>
<class 'dict'>
{'args': {'age': '22', 'name': 'germey'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}, 'origin': '27.47.130.215, 27.47.130.215', 'url': 'https://httpbin.org/get?name=germey&age=22'}
'''
1.5、JSON格式的解析
網頁的返回類型實際上是str類型,但是需要JSON格式進行解析的。可以直接調用json()方法,就可以將返回結果是JSON格式的字符串轉化爲字典。【案例如:1.3、】。
1.6、抓取二進制數據的解析
案例:https://img-blog.csdnimg.cn/20191224145404163.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224
import requests
r=requests.get("https://img-blog.csdnimg.cn/20191224145404163.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224")
print(r.text) #結果:���� JFIF �� C
print(r.content) #結果:b'\xff\xd8\xff\xe0\x00\...代表是bytes類型的數據
with open('python.ico','wb') as f: #將圖片以2進制的格式存在python.ico中,可以.png等其他格式
f. write(r.content)
1.7、響應
發送請求後,得到的就是響應。在上面的實例中,我們使用text和content獲取了響應的內容。此外,還有很多屬性和方法可以用來獲取其他信息,比如狀態碼、響應頭、Cookies等。示例如下:
import requests
r=requests.get("https://blog.csdn.net/weixin_41685388/category_9426224.html")
print(type(r.status_code),r.status_code) # 狀態:200 或404、500等
print(type(r.headers),r.headers) # headers信息
print(type(r.cookies),r.cookies) # Cookie信息
print(type(r.history),r.history) # 請求歷史記錄
print(type(r.text),r.text) # 響應的內容 文本str格式
#print(type(r.json()),r.json()) # 響應的內容 json-->dict
#print(type(r.content),r.content) # 響應的內容 二進制文件
二、requests庫高級應用
2.1、Cookies處理
(1)獲取Cookies。
import requests
r=requests. get("https://www.baidu.com/")
print(type(r.cookies),r.cookies) #獲取cookies
for key, value in r.cookies.items():
print(key+'='+value)
(2)使用Cookies。
Cookies在headers中應用,用於維持登陸狀態,在實際爬取網頁的過程中,可以在瀏覽器中找到。谷歌瀏覽器爲例:url網頁-->右擊-->檢查(N)-->Network-->F5-->(找到包含所需內容的Name)-->Headers-->Response Headers,常用"Cookie"和"User-Agent"。
2.2、會話維持,保持登陸狀態。Session對象。
利用它,我們可以方便地維護一個會話,而且不用擔心cookies的問題,它會幫我們自動處理好。你使用session成功的登錄了某個網站,則在再次使用該session對象求求該網站的其他網頁都會默認使用該session之前使用的cookie等參數。requests庫的session對象還能爲我們提供請求方法的缺省數據,通過設置session對象的屬性來實現 。
尤其是在保持登陸狀態時運用的最多,在某些網站抓取,或者app抓取時,有的時強制登陸,有的是不登陸返回的數據就是假的或者說是不完整的數據,那我們不可能去做到每一次請求都要去登陸一下怎麼辦,就需要用到保持會話的功能了,我們可以只登陸一次,然後保持這種狀態去做其他的或者更多的請求。
import requests
import time
# session()中方法和requests()中一樣
# session.get() session.post()
session = requests.session()
# 使用session發送post請求獲取cookie保存到本地session中。
# 以人人網登錄爲例。
post_url = "http://www.renren.com/PLogin.do"
headers = {"User-Agent": "Mozilla/5.0"}
session = requests.session()
post_data = {"email": "username", "password": "password"}
session.post(post_url, headers=headers, data=post_data)
# 使用session請求登錄後的頁面
# 得到登錄後的網頁內容
url = "http://www.renren.com/xxxxx/profile"
response = session.get(url, headers=headers)
2.3、代理設置
import requests
proxies = {
'http': 'http://192.168.2.47:80',
'https': 'https://157.245.54.87:8080'
} #臨時代理ip會過期
r = requests.get("https://www.taobao.com",proxies=proxies)
print(r.text)
2.4、身份認證
import requests
from requests.auth import HTTPBasicAuth
r=requests.get("http://localhost:5000",auth=HTTPBasicAuth("username","password"))
print(r. status_code)
#或
import requests
r=requests.get("http://localhost:5000",auth=("username","password"))
print(r. status_code)
2.5、Prepared Request
這裏我們引入了Request,然後用url、data和headers參數構造了一個Request對象,這時需要再調用Session的prepare_request()方法將其轉換爲一個Prepared Request對象,然後調用send()方法發送即可,如下:
2.6、其他:SSL 證書驗證、文件上傳、OAuth 認證等
不再贅述
三、異常處理
在調試過程中根據實際情況處理,一般情況都是exceptions.xxxx異常,處理語法:
from requests import exceptions
try:
"無異常執行代碼"
except exceptions.xxxx as e:
"異常執行代碼"
def timeout_request(url):
import json
import requests
from requests import exceptions
try:
response = requests.get(url,timeout=0.000000005)
response.raise_for_status()
except exceptions.ConnectTimeout as e:
print(e)
except (exceptions.HTTPError,exceptions.MissingSchema) as e:
print(e)
urls= ["https://blog.csdn.net/weixin_41685388/category_9426224.html","www.baidu.com/"]
for url in urls:
timeout_request(url)