前段時間,朋友圈里不知道為什么忽然刮起了一股曬18歲照片的風,不能免俗的我,自然也翻箱倒柜到處找起來以前的照片,由于我存有照片的移動硬盤已經(jīng)損壞,于是就想起了當年非常火的一個社交類網(wǎng)站--人人網(wǎng)(校內(nèi)網(wǎng))。
說來也巧,那天我登陸人人網(wǎng)找照片時,網(wǎng)站也是奇慢無比,打開一張照片要花差不多兩分鐘,在好不容易找到一張滿意的照片并發(fā)完朋友圈裝逼后,不由得忽然擔心起來如果某天網(wǎng)站不在了,豈不是我所有的照片就沒了,于是就打算用爬蟲把照片全存到電腦上。
分析了下人人網(wǎng)的網(wǎng)站,在輸入用戶名和密碼后,利用requests庫的get方法,手動添加cookies和header后,就可以很容易的獲取所有照片的url。相冊信息就在Request URL源代碼里的Album List里。
其實如果就滿足于保存照片的話,到這里已經(jīng)沒啥好寫了,具體的抓取方法都差不多,不論是利用scrapy框架還是簡單的用requests庫,都可以參照以前的代碼來寫。但是,我又想把這個下載照片的代碼分享給好友使用,可總不能讓好友先看完《Python教程-廖雪峰》之后再來用吧,這可相當?shù)牟挥押谩?strong>如何盡量用簡單的語言教會用戶使用我寫的爬蟲代碼,就是我面臨的主要問題了。
最簡單的方法就是將代碼打包成一個exe文件,這樣就只需要簡單的雙擊就可以執(zhí)行了;但是關于網(wǎng)站登陸,目前還不太會處理,以往爬去需要登陸的網(wǎng)站都是先在網(wǎng)站上登陸后,再手動復制cookies到代碼中來實現(xiàn)的,這如果讓另一個沒有基礎的人來弄的話,可能就要麻煩很多了。
百度了一番之后,所幸在一篇知乎專欄里發(fā)現(xiàn)了一種比較偷懶的解決登陸的方法《Python模擬登陸萬能法-微博|知乎》,簡單來說就是通過python的selenium庫來操作瀏覽器模擬手動登陸網(wǎng)站的全過程,然后通過get_cookies()方法獲取登陸后的cookies,然后再將cookies傳遞給requests庫,從而實現(xiàn)后續(xù)的爬取。
selenium簡介
- selenium是一個Web應用的自動化測試工具,它可以模擬真實用戶對瀏覽器的操作,支持多種語言,包括C、JAVA、Perl、Ruby、PHP以及Python等。
- selenium支持驅(qū)動多種瀏覽器,包括ie、chrome、火狐、safari、opera等。
- Python中selenium通過find_element()的方法,對瀏覽器頁面中的元素進行定位,其定位可以借助xpath、id、name、class、css selector等等方式實現(xiàn),然后可以對定位的元素進行文本抓取以及模擬鼠標或鍵盤操作。selenium還可以通過其它方式,例如wait來保證對元素的操作可以正確進行。
Python目前可以通過pyinstaller庫來實現(xiàn)代碼打包成exe的功能,pyinstaller庫使用起來比較簡單,具體方法如下,除此以外我也未再多做研究。
1.在cmd命令行中輸入pip install pyinstaller來安裝pyinstaller庫。
2.在python目錄的Scripts文件夾中找到安裝好的pyinstaller,用鼠標將其拖入cmd中,然后輸入-F,再將python代碼文件用鼠標拖到后面,Enter確認即可。
3.若想更改圖標,在第二步中再額外輸入-i,并將圖標文件.ico拖到后面。
- cmd命令行的輸入格式為:
xxx\xxx\xxx\pyinstaller -F xxx\xxx\代碼文件.py -i xxx\xxx\xxx\圖標.ico
下面具體開始碼代碼。
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
#selenium操作瀏覽器需要下載相應的驅(qū)動。
#我用的是chrome瀏覽器,因此需要下載相應版本的chromedriver.exe。
chromepath = r"C:\chromedriver.exe"
#現(xiàn)在人人網(wǎng)的首頁有太多的圖片了,為了加快載入速度添加一個瀏覽器設置,設置為不加載圖片。
chrome_opt = webdriver.ChromeOptions()
prefs={"profile.managed_default_content_settings.images":2}
chrome_opt.add_experimental_option("prefs",prefs)
browser = webdriver.Chrome(chromepath,chrome_options=chrome_opt)
wait = WebDriverWait(browser,3)
#打開人人網(wǎng)主頁
browser.get('http://www.renren.com/')
#定位到用戶名輸入框,通過send_keys的方式,輸入用戶名
login = wait.until(
EC.presence_of_element_located((By.XPATH,"http://input[@name='email']"))
)
login.send_keys(login_account)
#定位到密碼輸入框,通過send_keys的方式,輸入密碼
pwd = wait.until(
EC.presence_of_element_located((By.XPATH,"http://input[@id='password']"))
)
pwd.send_keys(password)
#勾選保存密碼按鈕
browser.find_element_by_xpath("http://form[@id='loginForm']/dl[@class='savepassword clearfix']/dt/label[@class='labelCheckbox']/input[@id='autoLogin']").click()
#點擊確認并登陸
browser.find_element_by_xpath("http://form[@id='loginForm']/dl[@class='bottom']/input[@id='login']").click()
#不可缺少!
cookie_dic = {}
while 'ln_uact' not in cookie_dic.keys():
cookies = browser.get_cookies()
print('登陸Cookies獲取中...')
# 將selenium獲取的cookies格式轉(zhuǎn)換為requests所識別的格式
for i in cookies:
cookie_dic[i['name']] = i['value']
print('登陸Cookies獲取完畢,準備開始抓取相片...')
登陸人人網(wǎng)并獲取cookies的代碼就已經(jīng)完成了,各個部分的功能已在代碼里注釋了,其中值得說明的一點是最后關于cookies的部分。我用了while循環(huán)來判斷cookies是否正確獲取,之所以這么做是因為從點擊登陸按鈕到頁面完全加載是需要一定的時間,若在頁面未完全加載的情況下獲取cookies,會發(fā)現(xiàn)cookies中少了一些參數(shù),其中就包括了lu_act,此時獲取的cookies則不能用于登陸。
- 這里也可以簡單的通過time.sleep()來設置一個等待時間,等待頁面加載完畢后來獲取cookies,但是這樣代碼就不夠健壯,可能受到網(wǎng)絡帶寬因素的影響。
- 另外也可以通過selenium自帶的顯示等待WebDriverWait來實現(xiàn),通過監(jiān)視頁面上某個元素的狀態(tài)來判斷頁面是否完全加載。我沒有采取這種方法是因為嘗試著用了幾個元素作為判斷依據(jù)都失敗了。。
剩下的代碼則是簡單的用requests庫進行爬取,方法還是對網(wǎng)頁元素以及url進行分析,各個部分在爬蟲源代碼中都已經(jīng)有了詳細注釋,就不再展開細說。需要說明的是,獲取相片信息和下載相片要用到兩個headers,因為二者的host信息不同。
#兩個headers,第一個headers帶有host值,用于獲取相片信息。
#第二個headers不能帶有前面的host值,用于下載相片。
headers = {'Host':'photo.renren.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
headers1 = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'}
在完成所有的爬蟲代碼后,打開cmd運行pyinstaller將代碼打包為exe,大功告成。最后來張運行的效果圖。