看這篇文章之前大家可以先看下我的上一篇文章:cookies詳解
本篇我們就針對上一篇來說一下cookies的基本應用
使用selenium模擬登陸百度
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PIL import Image
chrome_option = webdriver.ChromeOptions()
chrome_path = "/usr1/webdrivers/chromedriver"
def login_baidu():
driver = None
try:
driver = webdriver.Chrome(executable_path=chrome_path)
driver.get("https://www.baidu.com")
print(driver.title)
WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="u1"]/*[@class="lb"]')))
element = driver.find_element_by_xpath('//*[@id="u1"]/a[7]')
element.click()
WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__footerULoginBtn"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__footerULoginBtn"]')
element.click()
WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__userName"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__userName"]')
element.send_keys("賬號")
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__password"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__password"]')
element.send_keys("密碼")
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__verifyCodeImg"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__verifyCodeImg"]')
driver.get_screenshot_as_file("qrcode.png")
image = Image.open("qrcode.png")
left = element.location.get("x")
top = element.location.get("y")
right = left + element.size.get("width")
bottom = top + element.size.get("height")
cropImg = image.crop((left, top, right, bottom))
cropImg.save("code.png")
yanzheng = input(">>>")
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__verifyCode"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__verifyCode"]')
element.send_keys(yanzheng)
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__submit"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__submit"]')
element.click()
# 如果需要手機驗證碼
try:
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__button_send_mobile"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__button_send_mobile"]')
element.click()
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__input_vcode"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__input_vcode"]')
duanxin = input(">>>")
element.send_keys(duanxin)
WebDriverWait(driver, 10, 0.5).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__button_submit"]')))
element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__button_submit"]')
element.click()
except Exception as e:
print(e)
driver.get_screenshot_as_file("screen.png")
finally:
print("關閉")
if driver:
driver.quit()
selenium操作很簡單,這里不做詳解講解,以后我們開爬蟲基礎系列文章的時候會講到。
selenium保存cookies
cookies = driver.get_cookies()
with open("cookies.txt", "w") as fp:
json.dump(cookies, fp)
這里切記,如果我們要使用json.load讀取數據,那么一定要使用json.dump來寫入數據,不能使用str(cookies)直接轉為字符串進行保存,因為其存儲格式不同。這樣我們就將cookies保存在文件中了。
selenium讀取cookies
def read_cookies():
# 設置cookies前必須訪問一次百度的頁面
driver.get("http://www.baidu.com")
with open("cookies.txt", "r") as fp:
cookies = json.load(fp)
for cookie in cookies:
# cookie.pop('domain') # 如果報domain無效的錯誤
driver.add_cookie(cookie)
driver.get("http://www.baidu.com")
這里不用登錄就會直接顯示我的用戶名。而且要注意不同的瀏覽器可能處理方式不同,比如在火狐瀏覽器中就會報錯:selenium.common.exceptions.InvalidCookieDomainException: Message: .baidu.com,如果碰到這種錯誤(不一定,也可能跟系統、瀏覽器都有關系),在add_cookie的時候我們可以把domain去掉就行了。
requests讀取cookies
import requests
from requests.cookies import RequestsCookieJar
s = requests.session()
s.verify = False
s.headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
s.get("http://www.baidu.com")
#這里我們使用cookie對象進行處理
jar = RequestsCookieJar()
with open("cookies.txt", "r") as fp:
cookies = json.load(fp)
for cookie in cookies:
jar.set(cookie['name'], cookie['value'])
#百度個人中心
r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=jar)
# 也可以使用字典設置
cookies_dict = dict()
with open("cookies.txt", "r") as fp:
cookies = json.load(fp)
for cookie in cookies:
cookies_dict[cookie['name']] = cookie['value']
r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=cookies_dict)
r.encoding = "utf-8"
print(r.text)
requests庫可以使用cookies對象和dict對象來指定cookies,這個可以看一下源碼
通過requests讀取cookies的使用,我們知道在cookies中我們一般只使用name和value,像domain、path等值都是不需要使用的,而且上面傳入cookies字典的例子我們知道,只要保存了cookies中的name和value,無論你以什么樣的方式保存,文件、或者數據庫等,最后讀取出來只要生成對應的字典格式就行了。
requests保存cookies
import requests
s = requests.session()
s.verify = False
s.headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
# 這里可以是模擬登陸的步驟
s.get("http://www.baidu.com")
cookies = requests.utils.dict_from_cookiejar(s.cookies)
with open("cook.txt", "w") as fp:
json.dump(cookies, fp)
print(cookies)
首先我們看一下requests.session里面的cookies,它是一個RequestsCookieJar對象,這就是我們在上面使用的時候用RequestsCookieJar對象讀取cookies的原因了
下面我們看到requests.utils.dict_from_cookiejar方法,這是requests庫提供的一個方法,把上面的RequestsCookieJar對象轉換為一個字典(字典里只有name和value),這就是我上面說的,requests庫只使用name和value值,而我們selenium中保存的cookies中包含domain、path等信息。
另外還有一個方法requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)這個方法,根據字典生成一個RequestsCookieJar對象,為什么需要這樣一個方法呢,可能在上面的應用中有些人會有疑問,我們的cookies是通過get/post方法的參數傳進去的,那么在訪問其他網頁的時候都要去傳遞這樣一個參數嗎?這樣很不方便而且容易遺忘。看上圖的s.cookies變量,它是requests.session對象中的變量,而且是一個RequestsCookieJar類型的對象,那么我們就可以使用這個函數把讀取的字典信息轉換為RequestsCookieJar對象,然后把值直接設置給s.cookies,就像上面代碼里的headers一樣,這樣就方便很多了吧。
上面我都是將cookies值保存在文件中,在大多數情況下我們一般使用都是將其保存在數據庫中,啟動一個服務器專門進行登錄驗證並保存cookies值。后面我會寫一篇Flask+Redis進行cookies池維護的文章,發布在我的微信公眾號上,盡請關注哦。
如果你覺得我的文章還可以,可以關注我的微信公眾號,查看更多實戰文章:Python爬蟲實戰之路
也可以掃描下面二維碼,添加我的微信公眾號