搜狗微信采集 —— python爬虫系列一
前言:一覺(jué)睡醒,發(fā)現(xiàn)原有的搜狗微信爬蟲(chóng)失效了,網(wǎng)上查找一翻發(fā)現(xiàn)10月29日搜狗微信改版了,無(wú)法通過(guò)搜索公眾號(hào)名字獲取對(duì)應(yīng)文章了,不過(guò)通過(guò)搜索主題獲取對(duì)應(yīng)文章還是可以的,問(wèn)題不大,開(kāi)搞!
目的:獲取搜狗微信中搜索主題返回的文章。
涉及反爬機(jī)制:cookie設(shè)置,js加密。
完整代碼已上傳本人github,僅供參考。如果對(duì)您有幫助,勞煩看客大人給個(gè)星星!
進(jìn)入正題。
流程一:正常套路流程
打開(kāi)搜狗微信,在搜索框輸入“咸蛋超人”,這里搜索出來(lái)的就是有關(guān)“咸蛋超人”主題的各個(gè)公眾號(hào)的文章列表:
按照正常的采集流程,此時(shí)按F12打開(kāi)瀏覽器的開(kāi)發(fā)者工具,利用選擇工具點(diǎn)擊列表中文章標(biāo)題,查看源碼中列表中文章url的所在位置,再用xpath獲取文章url的值,也就是這個(gè)href的值,為避免混亂,我們稱之為“列表頁(yè)面的文章url”。
可以看到“列表頁(yè)面的文章url”需要拼接,一般這種情況需要在瀏覽器中正常訪問(wèn)一下這篇文章,對(duì)比觀察跳轉(zhuǎn)后的url(我們稱之為“真實(shí)的文章url”),再缺頭補(bǔ)頭缺腳補(bǔ)腳即可。下面是兩個(gè)url的對(duì)比:
列表頁(yè)面的文章url: /link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNFzn4G2S0Yt3MduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKnLsDcsuPIjLhLEK3tbGSa3_pkMzadQg75Zhmxb9YI0psZvVepKtN4hpzQgtGa2iOlKKLwV_oxooGE6sxg1qinKxTb5VwJUcLBM1RgkzAPRtmyIGw2VAg..&type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&k=92&h=z 真實(shí)的文章url: https://mp.weixin.qq.com/s?src=11×tamp=1573092595&ver=1959&signature=FjD709D-0vHSyVgQyXCS-TUAcnT0M9Gx6JljQEb6O55zpuyyDaTHqgkRCxNDtt5ZDifDRUUBOemzxcz71FMOmO88m6RWfR0r4fFBe0VefAsjFu0pl-M0frYOnXPF5JD8&new=1
這里很明顯兩個(gè)url的路徑不一致,應(yīng)該是中間經(jīng)過(guò)了一些調(diào)轉(zhuǎn),python的requests庫(kù)是帶自動(dòng)調(diào)轉(zhuǎn)功能,我們先把域名https://mp.weixin.qq.com補(bǔ)上試一下訪問(wèn)
明顯這里做了反爬限制,那么這里開(kāi)始,我們就需要抓包分析了。這里用到的工具是Firefox瀏覽器的開(kāi)發(fā)者工具。抓包觀察的是從搜索結(jié)果頁(yè)面列表文章點(diǎn)擊跳轉(zhuǎn)到文章頁(yè)面的過(guò)程,這里點(diǎn)擊文章超鏈接會(huì)在新窗口打開(kāi),我們只需要在網(wǎng)頁(yè)源碼中把對(duì)應(yīng)a標(biāo)簽的target屬性改為空,就可以在一個(gè)窗口中觀察整個(gè)流程的數(shù)據(jù)包了。
流程二:抓包分析之跳轉(zhuǎn)實(shí)現(xiàn)
抓包分析:
通過(guò)抓包我們可以找到搜索結(jié)果頁(yè)面跳轉(zhuǎn)到文章頁(yè)面的過(guò)程,這里觀察發(fā)現(xiàn),“列表頁(yè)面的文章url”返回的結(jié)果中就包含了“真實(shí)的文章url”的信息,這意味著我們只需要正確訪問(wèn)到“列表頁(yè)面的文章url”,根據(jù)返回的數(shù)據(jù)就能拼接出“真實(shí)的文章url”并訪問(wèn)了,這樣我們就實(shí)現(xiàn)從“列表頁(yè)面的文章url”到“真實(shí)的文章url”的跳轉(zhuǎn)了!
流程三:抓包分析之手動(dòng)獲取的“列表頁(yè)面的文章url”無(wú)法訪問(wèn)分析
此時(shí)我們的目標(biāo)就從獲取“真實(shí)的文章url”轉(zhuǎn)變到正確的訪問(wèn)“列表頁(yè)面的文章url”了,繼續(xù)分析抓包數(shù)據(jù)中的“列表頁(yè)面的文章url”信息:
抓包數(shù)據(jù):
url:https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNEnNekGBXt9LMduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKnLsDcsuPIjLhLEK3tbGaBLLLEV3E0vo604DcwbvX2VNudQZNnBemevd34BJP94ZL5zUiA49LgzIjRlpGxccVxTTaLhHZKstaeqw41upSVAe0f8bRARvQ..&type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&k=60&h=U
method:GET
請(qǐng)求參數(shù):{"url":"dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNEnNekGBXt9LMduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKnLsDcsuPIjLhLEK3tbGaBLLLEV3E0vo604DcwbvX2VNudQZNnBemevd34BJP94ZL5zUiA49LgzIjRlpGxccVxTTaLhHZKstaeqw41upSVAe0f8bRARvQ..","type":"2","query":"咸蛋超人","k":"60","h":"U"}
headers:
Host: weixin.sogou.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Referer: https://weixin.sogou.com/weixin?type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&ie=utf8&s_from=input&_sug_=n&_sug_type_=1&w=01015002&oq=&ri=1&sourceid=sugg&sut=750912&sst0=1573092594229&lkt=0%2C0%2C0&p=40040108
Cookie: 見(jiàn)下
Cookie:{"ABTEST":"4|1573094886|v1","IPLOC":"CN4401","JSESSIONID":"aaa3VBk4eXnIf8d4bdx4w","SNUID":"57A28ED20A0F9FB2BBE3E0180AF00D25","SUID":"5EAB87DB2613910A000000005DC385E6","SUV":"00F221C2DB87AB5E5DC385E7BC43F633"}
這里的重點(diǎn)有三個(gè):
請(qǐng)求參數(shù):對(duì)比我們獲取的“列表頁(yè)面的文章url”分析可以發(fā)現(xiàn),這里多了兩個(gè)參數(shù)“k”、“h”,這是需要我們?cè)O(shè)法獲取的。
headers:經(jīng)過(guò)測(cè)試該網(wǎng)站對(duì)User-Agent敏感,一次訪問(wèn)前后User-Agent需要一致。
Cookie:Cookie中參數(shù)需要獲取才能正確訪問(wèn)該url。這些參數(shù)分別是:ABTEST、IPLOC、JSESSIONID、SNUID、SUID、SUV。
3.1:獲取參數(shù)“k”、“h”
按照經(jīng)驗(yàn),從一個(gè)url轉(zhuǎn)變成另一個(gè)url有兩種情況:跳轉(zhuǎn)和javascript字符串處理。經(jīng)過(guò)多次抓包分析發(fā)現(xiàn),搜索結(jié)果頁(yè)面點(diǎn)擊文章超鏈接到我們現(xiàn)在的目標(biāo)url并沒(méi)有存在跳轉(zhuǎn)情況,抓包數(shù)據(jù)中的“列表頁(yè)面的文章url”和我們獲取的“列表頁(yè)面的文章url”可以判定為同一個(gè)url,所以猜測(cè)為javascript字符串處理。經(jīng)過(guò)一番搜尋,發(fā)現(xiàn)搜索結(jié)果頁(yè)面的源碼中有一段非常可疑的代碼:
<script>
(function(){$("a").on("mousedown click contextmenu",function(){var b=Math.floor(100*Math.random())+1,a=this.href.indexOf("url="),c=this.href.indexOf("&k=");-1!==a&&-1===c&&(a=this.href.substr(a+4+parseInt("21")+b,1),this.href+="&k="+b+"&h="+a)})})();
</script>
這其中最重要的代碼就是:this.href+="&k="+b+"&h="+a,這代碼就是在點(diǎn)擊事件發(fā)生時(shí)給a標(biāo)簽href屬性的內(nèi)容添加"&k="、"&h=",正是用這段代碼對(duì)該url的參數(shù)進(jìn)行js加密和添加的。我們只需要把這段代碼用python實(shí)現(xiàn)就可以解決這個(gè)問(wèn)題了,下面是實(shí)現(xiàn)python實(shí)現(xiàn)代碼:
def get_k_h(url):
b = int(random.random() * 100) + 1 a = url.find("url=") url = url + "&k=" + str(b) + "&h=" + url[a + 4 + 21 + b: a + 4 + 21 + b + 1]
reuturn url
3.2:獲取Cookie的參數(shù)
觀察抓包數(shù)據(jù)可以發(fā)現(xiàn),當(dāng)我們一開(kāi)始訪問(wèn)時(shí)并沒(méi)有帶任何cookie,但經(jīng)過(guò)一系列請(qǐng)求,到我們的目標(biāo)請(qǐng)求時(shí)候,瀏覽器已經(jīng)通過(guò)前面請(qǐng)求的返回?cái)?shù)據(jù)包的Set-Cookie屬性把Cookie構(gòu)造出來(lái)了,而我們要做的就是在Cookie構(gòu)造從無(wú)到有這個(gè)過(guò)程中找到所有ResponseHeaders中帶SetCookie屬性的而且參數(shù)是我們需要的參數(shù)的請(qǐng)求,并模擬訪問(wèn)一遍,就能得到所有參數(shù)并構(gòu)建出我們需要的Cookie了。
例如搜狗微信搜索接口的請(qǐng)求的ResponseHeaders就有5個(gè)Set-Cookie字段,其中ABTEST、SNUID、IPLOC、SUID都是我們最終構(gòu)造Cookie所需的參數(shù)(和最后的Cookie值對(duì)比可以發(fā)現(xiàn),這里的SUID值還不是我們最終需要的,要在后面的數(shù)據(jù)包中繼續(xù)發(fā)掘)。
經(jīng)過(guò)分析,經(jīng)過(guò)四個(gè)請(qǐng)求獲取到的ResponseHeaders后我們就能正確構(gòu)建Cookie了:
1. 得到ABTEST、SNUID、IPLOC、SUID:
https://weixin.sogou.com/weixin?type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&ie=utf8&s_from=input&_sug_=n&_sug_type_=1&w=01015002&oq=&ri=1&sourceid=sugg&sut=750912&sst0=1573092594229&lkt=0%2C0%2C0&p=40040108
2. 需要IPLOC、SNUID,得到SUID:
https://www.sogou.com/sug/css/m3.min.v.7.css
3. 需要ABTEST、IPLOC、SNUID、SUID,得到JSESSIONID:
https://weixin.sogou.com/websearch/wexinurlenc_sogou_profile.jsp
4. 需要IPLOC、SNUID、SUID,得到SUV
https://pb.sogou.com/pv.gif
這四個(gè)請(qǐng)求都能根據(jù)前面請(qǐng)求獲取到的Cookie參數(shù)來(lái)構(gòu)造自己需要的Cookie去正確訪問(wèn)。值得注意的是最后一個(gè)請(qǐng)求,除了需要正確拼接Cookie外,還需要獲取正確的請(qǐng)求參數(shù)才能正常訪問(wèn):
這種找參數(shù)的活可以利用瀏覽器的全局搜索功能,一番搜尋后,就會(huì)發(fā)現(xiàn)在搜索結(jié)果頁(yè)面的源代碼中已經(jīng)返回了這里所需的所有參數(shù),用正則把這些參數(shù)解析出來(lái)即可:
那么根據(jù)這些解析出來(lái)的參數(shù)和前面三個(gè)請(qǐng)求得到的Cookie參數(shù)就能正確訪問(wèn)第四個(gè)請(qǐng)求并得到所需的所有Cookie參數(shù)啦!
流程四:構(gòu)造正確的請(qǐng)求信息
此時(shí),我們已經(jīng)分析出所有正確模擬請(qǐng)求的流程了,梳理一下:
獲取“k”、“h”參數(shù),傳入搜索結(jié)果頁(yè)面得到的“列表頁(yè)面的文章ur”,調(diào)用get_k_h()即可。
獲取所需Cookie參數(shù),構(gòu)造正確的Cookie,按照流程三給出的4個(gè)url,分別構(gòu)造請(qǐng)求獲取ResponseHeaders中的SetCookie即可。
構(gòu)造正確的請(qǐng)求訪問(wèn)“列表頁(yè)面的文章url”。
根據(jù)3中請(qǐng)求返回的數(shù)據(jù),拼接出“真實(shí)的文章url”,也就是流程二。
請(qǐng)求“真實(shí)的文章url”,得到真正的文章頁(yè)面數(shù)據(jù)。
至此,所有分析結(jié)束,可以愉快的碼代碼啦!
結(jié)語(yǔ):此次采集涉及到的反爬技術(shù)是Cookie構(gòu)造和簡(jiǎn)答的js加密,難度不大,最重要的是耐心和細(xì)心。此外提醒各位看客大人遵循爬蟲(chóng)道德,不要對(duì)他人網(wǎng)站造成傷害,peace!
作者:
hyonline
出處:
https://www.cnblogs.com/hyonline/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出,
原文鏈接
如有問(wèn)題, 可私信咨詢.
總結(jié)
以上是生活随笔為你收集整理的搜狗微信采集 —— python爬虫系列一的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: bootstrap之 Badge 角标
- 下一篇: redis如何清空当前缓存和所有缓存