摘要:在抓取數據之前,請在瀏覽器中登錄過知乎,這樣才使得是有效的。所謂的模擬登陸,只是在中盡量的模擬在瀏覽器中的交互過程,使服務端無感抓包過程。若是幫你解決了問題,或者給了你啟發(fā),不要吝嗇給加一星。
折騰了將近兩天,中間數次想要放棄,還好硬著頭皮搞下去了,在此分享出來,希望有同等需求的各位能少走一些彎路。
源碼放在了github上, 歡迎前往查看。
若是幫你解決了問題,或者給了你啟發(fā),不要吝嗇給加一星。
在開始之前,請確保 scrpay 正確安裝,手頭有一款簡潔而強大的瀏覽器, 若是你有使用 postman 那就更好了。
scrapy genspider zhihu
使用以上命令生成知乎爬蟲,代碼如下:
# -*- coding: utf-8 -*- import scrapy class ZhihuSpider(scrapy.Spider): name = "zhihu" allowed_domains = ["www.zhihu.com"] start_urls = ["http://www.zhihu.com/"] def parse(self, response): pass
有一點切記,不要忘了啟用 Cookies, 切記切記 :
# Disable cookies (enabled by default) COOKIES_ENABLED = True模擬登陸
過程如下:
進入登錄頁,獲取 Header 和 Cookie 信息,
完善的 Header 信息能盡量偽裝爬蟲, 有效 Cookie 信息能迷惑知乎服務端,使其認為當前登錄非首次登錄,若無有效 Cookie 會遭遇驗證碼。 在抓取數據之前,請在瀏覽器中登錄過知乎,這樣才使得 Cookie 是有效的。
Header 和 Cookie 整理如下:
headers = { "Host": "www.zhihu.com", "Connection": "keep-alive", "Origin": "https://www.zhihu.com", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Accept": "*/*", "X-Requested-With": "XMLHttpRequest", "DNT": 1, "Referer": "https://www.zhihu.com/", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", } cookies = { "d_c0": ""AHCAtu1iqAmPTped76X1ZdN0X_qAwhjdLUU=|1458699045"", "__utma": "51854390.1407411155.1458699046.1458699046.1458699046.1", "__utmv": "51854390.000--|3=entry_date=20160322=1", "_zap": "850897bb-cba4-4d0b-8653-fd65e7578ac2", "q_c1": "b7918ff9a5514d2981c30050c8c732e1|1502937247000|1491446589000", "aliyungf_tc": "AQAAAHVgviiNyQsAOhSntJ5J/coWYtad", "_xsrf": "b12fdca8-cb35-407a-bc4c-6b05feff37cb", "l_cap_id": ""MDk0MzRjYjM4NjAwNDU0MzhlYWNlODQ3MGQzZWM0YWU=|1503382513|9af99534aa22d5db92c7f58b45f3f3c772675fed"", "r_cap_id": ""M2RlNDZjN2RkNTBmNGFmNDk2ZjY4NjIzY2FmNTE4NDg=|1503382513|13370a99ee367273b71d877de17f05b2986ce0ef"", "cap_id": ""NmZjODUxZjQ0NzgxNGEzNmJiOTJhOTlkMTVjNWIxMDQ=|1503382513|dba2e9c6af7f950547474f827ef440d7a2950163"", }
在瀏覽器中,模擬登陸,抓取登陸請求信息。
從圖中可以看到 _xsrf 參數, 這個參數與登陸驗證信息無關,但很明顯是由登陸頁面攜帶的信息。 Google了下 xsrf 的含義, 用于防范 跨站請求偽造 。
整理以上,代碼如下:
loginUrl = "https://www.zhihu.com/#signin" siginUrl = "https://www.zhihu.com/login/email" def start_requests(self): return [ scrapy.http.FormRequest( self.loginUrl, headers=self.headers, cookies=self.cookies, meta={"cookiejar": 1}, callback=self.post_login) ] def post_login(self, response): xsrf = response.css( "div.view-signin > form > input[name=_xsrf]::attr(value)" ).extract_first() self.headers["X-Xsrftoken"] = xsrf return [ scrapy.http.FormRequest( self.siginUrl, method="POST", headers=self.headers, meta={"cookiejar": response.meta["cookiejar"]}, formdata={ "_xsrf": xsrf, "captcha_type": "cn", "email": "xxxxxx@163.com", "password": "xxxxxx", }, callback=self.after_login) ]設置Bearer Token
經過上述步驟登陸成功了,有點小激動,有沒有! 但苦難到此還遠沒有結束,這個時候嘗試抓取最近熱門話題,直接返回 code:401 ,未授權的訪問。 授權信息未設置,導致了此類錯誤,莫非遺漏了什么,看來只能在瀏覽器中追蹤請求參數來偵測問題。 在瀏覽器的請求中,包含了Bearer Token, 而我在scrapy中模擬的請求中未包含此信息, 所以我被服務器認定為未授權的。 通過觀察發(fā)現 Bearer Token 的關鍵部分,就是 Cookies 中的 z_c0 包含的信息。
z_c0 包含的信息,是在登陸完成時種下的,所以從登陸完成返回的登陸信息里,獲取要設置的 Cookie 信息, 然后拼接出 Bearer Token,最后設置到 Header 中。
代碼整理如下:
def after_login(self, response): jdict = json.loads(response.body) print("after_login", jdict) if jdict["r"] == 0: z_c0 = response.headers.getlist("Set-Cookie")[2].split(";")[0].split( "=")[1] self.headers["authorization"] = "Bearer " + z_c0 return scrapy.http.FormRequest( url=self.feedUrl, method="GET", meta={"cookiejar": response.meta["cookiejar"]}, headers=self.headers, formdata={ "action_feed": "True", "limit": "10", "action": "down", "after_id": str(self.curFeedId), "desktop": "true" }, callback=self.parse) else: print(jdict["error"])獲取數據
上述步驟后,數據獲取就水到渠成了,為了檢測成功與否, 把返回信息寫到文件中,而且只獲取前五十個,代碼如下:
feedUrl = "https://www.zhihu.com/api/v3/feed/topstory" nextFeedUrl = "" curFeedId = 0 def parse(self, response): with open("zhihu.json", "a") as fd: fd.write(response.body) jdict = json.loads(response.body) jdatas = jdict["data"] for entry in jdatas: entry["pid"] = entry["id"] yield entry jpaging = jdict["paging"] self.curFeedId += len(jdatas) if jpaging["is_end"] == False and self.curFeedId < 50: self.nextFeedUrl = jpaging["next"] yield self.next_request(response) def next_request(self, response): return scrapy.http.FormRequest( url=self.nextFeedUrl, method="GET", meta={"cookiejar": response.meta["cookiejar"]}, headers=self.headers, callback=self.parse)
最終獲取的數據如下圖所示:
寫在最后知乎的數據,只有登錄完成之后,才可有效的獲取,所以模擬登陸是無法忽略不管的。 所謂的模擬登陸,只是在scrapy中盡量的模擬在瀏覽器中的交互過程,使服務端無感抓包過程。 請求中附加有效的 Cookies 和 Headers 頭信息,可有效的迷惑服務端, 同時在交互的過程中,獲取后續(xù)請求必要信息和認證信息,使得整個流程能不斷先前。
若是你遇到什么問題,盡量提出來,歡迎一起來討論解決。
源碼放在了github上, 歡迎前往查看。
若是幫你解決了問題,或者給了你啟發(fā),不要吝嗇給加一星。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40789.html
摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
摘要:學習網絡爬蟲主要分個大的版塊抓取,分析,存儲另外,比較常用的爬蟲框架,這里最后也詳細介紹一下。網絡爬蟲要做的,簡單來說,就是實現瀏覽器的功能。 Python學習網絡爬蟲主要分3個大的版塊:抓取,分析,存儲 另外,比較常用的爬蟲框架Scrapy,這里最后也詳細介紹一下。 首先列舉一下本人總結的相關文章,這些覆蓋了入門網絡爬蟲需要的基本概念和技巧:寧哥的小站-網絡爬蟲,當我們在瀏覽器中輸入...
摘要:從如何評價的話題下開始抓取問題,然后開始爬相關問題再循環(huán)對于每個問題抓取標題,關注人數,回答數等數據設置用戶名和密碼設置獲取值獲得驗證碼的地址準備下載驗證碼獲取請求下載驗證碼打開驗證碼輸入驗證碼請輸入驗證碼輸入賬號和 從如何評價X的話題下開始抓取問題,然后開始爬相關問題再循環(huán) 對于每個問題抓取 標題,關注人數,回答數等數據 zhihuTopicSpider.py # -*- cod...
【百度云搜索,搜各種資料:http://www.bdyss.cn】 【搜網盤,搜各種資料:http://www.swpan.cn】 第一步。首先下載,大神者也的倒立文字驗證碼識別程序 下載地址:https://github.com/muchrooms/... 注意:此程序依賴以下模塊包 Keras==2.0.1 Pillow==3.4.2 jupyter==1.0.0 matplotli...
摘要:今天為大家整理了個爬蟲項目。地址新浪微博爬蟲主要爬取新浪微博用戶的個人信息微博信息粉絲和關注。代碼獲取新浪微博進行登錄,可通過多賬號登錄來防止新浪的反扒。涵蓋鏈家爬蟲一文的全部代碼,包括鏈家模擬登錄代碼。支持微博知乎豆瓣。 showImg(https://segmentfault.com/img/remote/1460000018452185?w=1000&h=667); 今天為大家整...
閱讀 3968·2021-11-16 11:44
閱讀 5189·2021-10-09 09:54
閱讀 2031·2019-08-30 15:44
閱讀 1678·2019-08-29 17:22
閱讀 2753·2019-08-29 14:11
閱讀 3389·2019-08-26 13:25
閱讀 2324·2019-08-26 11:55
閱讀 1595·2019-08-26 10:37