前段時(shí)間春畔,朋友圈里不知道為什么忽然刮起了一股曬18歲照片的風(fēng)脱货,不能免俗的我,自然也翻箱倒柜到處找起來(lái)以前的照片律姨,由于我存有照片的移動(dòng)硬盤已經(jīng)損壞振峻,于是就想起了當(dāng)年非常火的一個(gè)社交類網(wǎng)站--人人網(wǎng)(校內(nèi)網(wǎng))择份。
說(shuō)來(lái)也巧扣孟,那天我登陸人人網(wǎng)找照片時(shí),網(wǎng)站也是奇慢無(wú)比荣赶,打開一張照片要花差不多兩分鐘凤价,在好不容易找到一張滿意的照片并發(fā)完朋友圈裝逼后鸽斟,不由得忽然擔(dān)心起來(lái)如果某天網(wǎng)站不在了,豈不是我所有的照片就沒了料仗,于是就打算用爬蟲把照片全存到電腦上湾盗。
分析了下人人網(wǎng)的網(wǎng)站,在輸入用戶名和密碼后立轧,利用requests庫(kù)的get方法格粪,手動(dòng)添加cookies和header后,就可以很容易的獲取所有照片的url氛改。相冊(cè)信息就在Request URL源代碼里的Album List里帐萎。
其實(shí)如果就滿足于保存照片的話,到這里已經(jīng)沒啥好寫了胜卤,具體的抓取方法都差不多疆导,不論是利用scrapy框架還是簡(jiǎn)單的用requests庫(kù),都可以參照以前的代碼來(lái)寫葛躏。但是澈段,我又想把這個(gè)下載照片的代碼分享給好友使用,可總不能讓好友先看完《Python教程-廖雪峰》之后再來(lái)用吧舰攒,這可相當(dāng)?shù)牟挥押谩?strong>如何盡量用簡(jiǎn)單的語(yǔ)言教會(huì)用戶使用我寫的爬蟲代碼败富,就是我面臨的主要問題了。
最簡(jiǎn)單的方法就是將代碼打包成一個(gè)exe文件摩窃,這樣就只需要簡(jiǎn)單的雙擊就可以執(zhí)行了;但是關(guān)于網(wǎng)站登陸兽叮,目前還不太會(huì)處理,以往爬去需要登陸的網(wǎng)站都是先在網(wǎng)站上登陸后猾愿,再手動(dòng)復(fù)制cookies到代碼中來(lái)實(shí)現(xiàn)的鹦聪,這如果讓另一個(gè)沒有基礎(chǔ)的人來(lái)弄的話,可能就要麻煩很多了蒂秘。
百度了一番之后泽本,所幸在一篇知乎專欄里發(fā)現(xiàn)了一種比較偷懶的解決登陸的方法《Python模擬登陸萬(wàn)能法-微博|知乎》,簡(jiǎn)單來(lái)說(shuō)就是通過(guò)python的selenium庫(kù)來(lái)操作瀏覽器模擬手動(dòng)登陸網(wǎng)站的全過(guò)程姻僧,然后通過(guò)get_cookies()方法獲取登陸后的cookies观挎,然后再將cookies傳遞給requests庫(kù),從而實(shí)現(xiàn)后續(xù)的爬取段化。
selenium簡(jiǎn)介
- selenium是一個(gè)Web應(yīng)用的自動(dòng)化測(cè)試工具,它可以模擬真實(shí)用戶對(duì)瀏覽器的操作造成,支持多種語(yǔ)言显熏,包括C、JAVA晒屎、Perl喘蟆、Ruby缓升、PHP以及Python等。
- selenium支持驅(qū)動(dòng)多種瀏覽器蕴轨,包括ie港谊、chrome、火狐橙弱、safari歧寺、opera等。
- Python中selenium通過(guò)find_element()的方法棘脐,對(duì)瀏覽器頁(yè)面中的元素進(jìn)行定位斜筐,其定位可以借助xpath、id蛀缝、name顷链、class、css selector等等方式實(shí)現(xiàn)屈梁,然后可以對(duì)定位的元素進(jìn)行文本抓取以及模擬鼠標(biāo)或鍵盤操作嗤练。selenium還可以通過(guò)其它方式,例如wait來(lái)保證對(duì)元素的操作可以正確進(jìn)行在讶。
Python目前可以通過(guò)pyinstaller庫(kù)來(lái)實(shí)現(xiàn)代碼打包成exe的功能煞抬,pyinstaller庫(kù)使用起來(lái)比較簡(jiǎn)單,具體方法如下真朗,除此以外我也未再多做研究此疹。
1.在cmd命令行中輸入pip install pyinstaller來(lái)安裝pyinstaller庫(kù)。
2.在python目錄的Scripts文件夾中找到安裝好的pyinstaller遮婶,用鼠標(biāo)將其拖入cmd中蝗碎,然后輸入-F,再將python代碼文件用鼠標(biāo)拖到后面旗扑,Enter確認(rèn)即可蹦骑。
3.若想更改圖標(biāo),在第二步中再額外輸入-i臀防,并將圖標(biāo)文件.ico拖到后面眠菇。
- cmd命令行的輸入格式為:
xxx\xxx\xxx\pyinstaller -F xxx\xxx\代碼文件.py -i xxx\xxx\xxx\圖標(biāo).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操作瀏覽器需要下載相應(yīng)的驅(qū)動(dòng)袱衷。
#我用的是chrome瀏覽器捎废,因此需要下載相應(yīng)版本的chromedriver.exe。
chromepath = r"C:\chromedriver.exe"
#現(xiàn)在人人網(wǎng)的首頁(yè)有太多的圖片了致燥,為了加快載入速度添加一個(gè)瀏覽器設(shè)置登疗,設(shè)置為不加載圖片。
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)主頁(yè)
browser.get('http://www.renren.com/')
#定位到用戶名輸入框,通過(guò)send_keys的方式辐益,輸入用戶名
login = wait.until(
EC.presence_of_element_located((By.XPATH,"http://input[@name='email']"))
)
login.send_keys(login_account)
#定位到密碼輸入框断傲,通過(guò)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()
#點(diǎn)擊確認(rèn)并登陸
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所識(shí)別的格式
for i in cookies:
cookie_dic[i['name']] = i['value']
print('登陸Cookies獲取完畢认罩,準(zhǔn)備開始抓取相片...')
登陸人人網(wǎng)并獲取cookies的代碼就已經(jīng)完成了,各個(gè)部分的功能已在代碼里注釋了续捂,其中值得說(shuō)明的一點(diǎn)是最后關(guān)于cookies的部分垦垂。我用了while循環(huán)來(lái)判斷cookies是否正確獲取,之所以這么做是因?yàn)閺狞c(diǎn)擊登陸按鈕到頁(yè)面完全加載是需要一定的時(shí)間疾忍,若在頁(yè)面未完全加載的情況下獲取cookies乔外,會(huì)發(fā)現(xiàn)cookies中少了一些參數(shù),其中就包括了lu_act一罩,此時(shí)獲取的cookies則不能用于登陸杨幼。
- 這里也可以簡(jiǎn)單的通過(guò)time.sleep()來(lái)設(shè)置一個(gè)等待時(shí)間,等待頁(yè)面加載完畢后來(lái)獲取cookies聂渊,但是這樣代碼就不夠健壯差购,可能受到網(wǎng)絡(luò)帶寬因素的影響。
- 另外也可以通過(guò)selenium自帶的顯示等待WebDriverWait來(lái)實(shí)現(xiàn)汉嗽,通過(guò)監(jiān)視頁(yè)面上某個(gè)元素的狀態(tài)來(lái)判斷頁(yè)面是否完全加載欲逃。我沒有采取這種方法是因?yàn)閲L試著用了幾個(gè)元素作為判斷依據(jù)都失敗了。饼暑。
剩下的代碼則是簡(jiǎn)單的用requests庫(kù)進(jìn)行爬取稳析,方法還是對(duì)網(wǎng)頁(yè)元素以及url進(jìn)行分析,各個(gè)部分在爬蟲源代碼中都已經(jīng)有了詳細(xì)注釋弓叛,就不再展開細(xì)說(shuō)彰居。需要說(shuō)明的是,獲取相片信息和下載相片要用到兩個(gè)headers撰筷,因?yàn)槎叩膆ost信息不同陈惰。
#兩個(gè)headers,第一個(gè)headers帶有host值毕籽,用于獲取相片信息抬闯。
#第二個(gè)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運(yùn)行pyinstaller將代碼打包為exe,大功告成蒸播。最后來(lái)張運(yùn)行的效果圖睡榆。