一.簡述
爬蟲爬取數(shù)據(jù)時赴恨,有些數(shù)據(jù)并不能讓游客訪問到毫胜,這時候就需要進行登錄狂打,再爬取數(shù)據(jù)擂煞,登錄后再爬取的手段很多,但核心都是通過cookie的方式來記錄身份信息趴乡,因此模擬登錄的核心在于對cookie的使用对省。
二.登錄方法
目前我所知的登錄方法有兩種:
1.通過selenium進行瀏覽器模擬登錄(簡單粗暴)
2.通過分析登錄頁面,獲取登錄接口和提交表單進行登錄驗證
由于知乎改版后晾捏,登錄接口變的有些復雜蒿涎,加入動態(tài)js的方法,因此我采用selenium方式來登錄粟瞬,同時通過session記錄登錄后的cookies同仆,進一步對知乎內(nèi)的內(nèi)容進行爬取萤捆。
三.實現(xiàn)登錄
平臺:windows
工具:Python 2.7.14裙品,Chrome瀏覽器
首先用pip安裝好所需的模塊selenium,requests俗或,BeautifulSoup(網(wǎng)上有教程)市怎,然后下載好chromedriver,將其加入系統(tǒng)環(huán)境變量辛慰,或者直接放在python 安裝目錄下的scripts中区匠。
思路:用selenium打開chrome,通過程序自動輸入賬號密碼帅腌,有驗證碼則需手動填寫下驗證碼驰弄。等到成功登陸之后使用“get_cookies()”函數(shù)來調(diào)出它的Cookies,然后將cookies保存在requests.Session中速客,通過session繼續(xù)訪問登錄后的頁面戚篙。
代碼如下:
from selenium import webdriver
import requests
from time import sleep
from bs4 import BeautifulSoup
browser = webdriver.Chrome()
url= 'https://www.zhihu.com/'
s = requests.Session()
s.headers.clear()#清除requests頭部中的Python機器人信息,否則登錄失敗
browser.get(url)
browser.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[2]/span').click()#避免屏幕失去焦點
browser.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[1]/div[2]/div[1]/input').send_keys('賬號')
browser.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[2]/div/div[1]/input').send_keys('密碼')
try:
img = browser.find_element_by_xpath('//* [@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[3]/div/div[2]/img')#驗證碼圖片鏈接--倒立文字
sleep(10)
except:
img= browser.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[3]/div/span/div/img').get_attribute("src")#驗證碼圖片鏈接--字母數(shù)字
sleep(10)#填寫驗證碼
else:
pass
browser.find_element_by_xpath('//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/button').submit()#登錄
sleep(5)#等待Cookies加載
cookies = browser.get_cookies()
browser.quit()
for cookie in cookies:
s.cookies.set(cookie['name'],cookie['value'])#為session設(shè)置cookies
html=s.get(url).text
soup = BeautifulSoup(html)
items = soup.find_all('a',attrs={'data-za-detail-view-element_name':"Title"})#獲取登錄后加載出的前幾個話題的標題
for item in items:
print item.string
運行結(jié)果: