Scrapy 1.4 + Python 3.6模擬登陸知乎

最近學(xué)習(xí)Python爬蟲,用到了Scrapy這個(gè)爬蟲框架。目前Scrapy的最新版本已經(jīng)達(dá)到了Scrapy 1.4,并且支持Python 3,但是網(wǎng)上找到的中文資料基本都是老版本的Scrapy,并且只支持到Python 2.7。于是筆者決定將Scrapy 1.4的學(xué)習(xí)過(guò)程記錄下來(lái),供各位童鞋參考。

這篇文章講解了如何模擬登陸知乎,參考另一篇簡(jiǎn)書文章Scrapy模擬登陸知乎,不過(guò)這篇文章是基于Python 2.7的版本,細(xì)節(jié)方面沒(méi)弄清楚的童鞋可以去看看原文章。

模擬登陸過(guò)程都是在Spider類中完成的,這里用最基本的Spider實(shí)現(xiàn)。

1.在spiders目錄下創(chuàng)建一個(gè)py文件:zhihu_spider.py,繼承自Spider,先把基本的一些東西寫進(jìn)去:

class ZhihuQuestionSpider(Spider):

? ? url_base = 'https://www.zhihu.com'? # 供后面獲取鏈接使用

? ? name = 'login'? # Spider的名字

? ? start_url_base = 'https://www.zhihu.com/collection/27915947?page='? # 爬取頁(yè)面

? ? start_urls = ['https://www.zhihu.com/collection/27915947']? # 這里沒(méi)用到這個(gè)

? ? headers = {

? ? ? ? "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",

? ? ? ? "Accept-Encoding": "gzip,deflate",

? ? ? ? "Accept-Language": "en-US,en;q=0.8,zh-TW;q=0.6,zh;q=0.4",

? ? ? ? "Connection": "keep-alive",

? ? ? ? "Content-Type": " application/x-www-form-urlencoded; charset=UTF-8",

? ? ? ? "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36",

? ? ? ? "Referer": "http://www.zhihu.com"

? ? }

里面都是一些之后會(huì)用到的量,注釋講的很清楚了。

2.重寫Spider的start_requests方法。

這里是整個(gè)爬蟲的開始,從知乎首頁(yè)開始,模擬登陸環(huán)境,這里的cookiejar是Scrapy的Cookie中間件的關(guān)鍵字,1表示這里只需要保存一個(gè)Cookie。這個(gè)方法將獲取到的頁(yè)面交給post_login方法模擬登陸。

# 從這里開始↓

def start_requests(self):

? ? return [Request("https://www.zhihu.com/", headers=self.headers, meta={"cookiejar": 1}, callback=self.post_login)]

3.post_login模擬登陸方法。注意修改一下登陸郵箱和密碼。

# 進(jìn)入知乎主頁(yè)模仿登陸

def post_login(self, response):

? ? self.log('preparing login...')

? ? xsrf = Selector(response).xpath('//div[@data-za-module="SignInForm"]//form//input[@name="_xsrf"]/@value').extract()[0]

? ? self.log(xsrf)

? ? return FormRequest("https://www.zhihu.com/login/email", meta={'cookiejar': response.meta['cookiejar']},

? ? ? ? headers=self.headers,

? ? ? ? formdata={

? ? ? ? '_xsrf': xsrf,

? ? ? ? 'password': '不能把密碼告訴你們',

? ? ? ? 'email': '郵箱也不行',

? ? ? ? 'remember_me': 'true',

? ? ? ? },

? ? ? ? callback=self.after_login,

? ? )

4.登陸成功后的爬蟲操作。這里先介紹以下這個(gè)案例的爬蟲行為:

首先是最開始爬取的頁(yè)面:這是一個(gè)名為生活文體藝術(shù)見聞的收藏,共有九百多篇收藏。

從這個(gè)頁(yè)面獲取每個(gè)提問(wèn)的頁(yè)面,在從提問(wèn)頁(yè)面里獲取問(wèn)題、鏈接、閱讀量、關(guān)注量等信息,如下圖中紅圈圈出來(lái)的信息。

這里有個(gè)問(wèn)題,收藏頁(yè)面只顯示10個(gè)提問(wèn),剩下的提問(wèn)在分頁(yè)里面,怎么處理呢?

可以通過(guò)這個(gè)鏈接搞定:

start_url_base = 'https://www.zhihu.com/collection/27915947?page='? # 爬取頁(yè)面

page=后面填入相應(yīng)的數(shù)字就代表相應(yīng)的分頁(yè),當(dāng)我們將第一個(gè)分頁(yè)的提問(wèn)爬取完成之后,將這個(gè)url后面加入其他的數(shù)字就可以爬取下一頁(yè)的提問(wèn)了。

5.登陸成功后進(jìn)入相應(yīng)的分頁(yè)(即每頁(yè)顯示十個(gè)提問(wèn)的那個(gè)頁(yè)面),這個(gè)收藏一共91頁(yè),所以循環(huán)(1~91)次。

# 登陸成功后從start_urls里讀出初始url,注入cookie

def after_login(self,response):

? ? # 創(chuàng)建csv文件

? ? with open('items.csv', 'w', newline='') as csvfile:

? ? writer = csv.writer(csvfile, dialect=('excel'))

? ? writer.writerow(['標(biāo)題', '鏈接', '關(guān)注量', '瀏覽量'])

? ? for page in range(1, 92):

? ? ? ? url = self.start_url_base + str(page)

? ? ? ? yield Request(url, meta={'cookiejar': 1}, headers=self.headers, callback=self.request_question)

6.分析該分頁(yè),得到提問(wèn)的鏈接,并進(jìn)入提問(wèn)頁(yè)面爬取有用的信息。筆者還是更喜歡用BeautifulSoup,將xpath轉(zhuǎn)為BeautifulSoup可以這樣:

soup = BeautifulSoup(request.body, 'lxml')

# 分析得到urls

def request_question(self,request):

? ? soup = BeautifulSoup(request.body, 'lxml')

? ? for urlDiv in soup.find_all('div', class_='zm-item'):

? ? ? ? url = self.url_base + urlDiv.find('a').get('href')

? ? ? ? yield Request(url,meta={'cookiejar':1},headers = self.headers,callback=self.parse_question)

7.最后一步了,進(jìn)入提問(wèn)頁(yè)面,提取有用信息保存到csv中。

# 獲取有用的信息

def parse_question(self,response):

? ? soup = BeautifulSoup(response.body, 'lxml')

? ? item = ZhihuItem()

? ? item['questionTitle'] = soup.find('h1').string

? ? item['url'] = response.url

? ? followDiv = soup.find('div', class_='NumberBoard QuestionFollowStatus-counts')

? ? item['follow'] = followDiv.find_all('div', class_='NumberBoard-value')[0].string

? ? item['page_view'] = followDiv.find_all('div', class_='NumberBoard-value')[1].string

? ? # 將問(wèn)題標(biāo)題寫入csv

? ? with open('items.csv', 'a', newline='') as csvfile:

? ? ? ? writer = csv.writer(csvfile, dialect=('excel'))

? ? ? ? writer.writerow([item['questionTitle'], item['url'], item['follow'], item['page_view']])

? ? return item

8.在命令行里輸入:scrapy crawl login運(yùn)行爬蟲,爬取結(jié)果如下:

不過(guò)沒(méi)能解決知乎安全驗(yàn)證的問(wèn)題,當(dāng)爬取過(guò)多、過(guò)快時(shí)就要輸入驗(yàn)證碼了。

(PS.誰(shuí)能告訴簡(jiǎn)書怎么插入代碼啊,```完全沒(méi)用呀?。。。?br>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容