今日頭條爬蟲策略

目標:爬取今日頭條頭條號王者榮耀資訊和視頻狞贱。

爬蟲關(guān)鍵點:1.分析單頁面獲取所需要的內(nèi)容刻获,2.找到文章列表頁翻頁規(guī)律蜀涨,3.解析加密信息瞎嬉,獲取所需要的內(nèi)容

?????? (1)通過搜索接口獲取今日頭條王者榮耀資訊

最初策略是通過今日頭條首頁搜索框搜索關(guān)鍵字“今日頭條”,獲取搜索列表厚柳。經(jīng)過分析fillder 抓包可以得到今日頭條搜索接口是https://www.toutiao.com/search/?keyword= 最后接上關(guān)鍵字既可以搜索得到想要的內(nèi)容氧枣,但實際上獲取文章列表真正鏈接的請求是:

https://www.toutiao.com/search_content/?offset=0&format=json&keyword=王者榮耀&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis“

去掉其他信息之后,最終獲取的有效的url是:

https://www.toutiao.com/search_content/?offset=0&format=json&keyword=王者榮耀&count=20

現(xiàn)在就很簡單了别垮,可以看到offset是翻頁便监,format=json則表示是通過json格式生成傳遞數(shù)據(jù),keyword則表示搜索的關(guān)鍵字碳想,count 則表示一次傳輸獲取到的數(shù)據(jù)烧董。

第二步就是文章列表中,每一個關(guān)鍵的json數(shù)據(jù)樣式胧奔,現(xiàn)在我們通過鏈接可以看到我們獲取到的數(shù)據(jù)央視是這樣的:


看起來很繁雜逊移,仔細分析之后,可以看到龙填,實際上是有規(guī)律可以遵循的胳泉,重點關(guān)注的是json格式數(shù)據(jù)里面的data的value值,里面是真正的文章信息列表⊙乙牛現(xiàn)在分析清楚之后扇商,可以放下,再進行單頁面的分析請求宿礁。

經(jīng)過分析可以得到案铺,今日頭條單頁面url鏈接是:

?????? “https://www.toutiao.com/a6645464825897943555/“

很明顯,最后的那一串?dāng)?shù)字是關(guān)鍵梆靖,那么红且,這一串?dāng)?shù)字是從哪里獲取的呢坝茎,現(xiàn)在就要回頭看前面的請求列表了,我們拿著“6645464825897943555“這串?dāng)?shù)字,在前面的

文章列表進行搜索暇番,輕易的發(fā)現(xiàn)嗤放,展示這串?dāng)?shù)字的key值就是data里面的“group_id”雖然有點驚訝,但是最終還是拿到了壁酬。

現(xiàn)在我們通過搜索獲取文章列表次酌,跳轉(zhuǎn),和翻頁我們都找到了接口舆乔。下面的事情就簡單了岳服,獲取單頁面數(shù)據(jù)。當(dāng)我點開網(wǎng)頁源代碼的時候希俩,發(fā)現(xiàn)里面就有我想要的內(nèi)容吊宋。

最后通過xpath或者是正則就可以獲取一個單頁面文章所需要的內(nèi)容。


? ? ?這個頁碼有很多亂碼颜武,經(jīng)過百度之后璃搜,發(fā)現(xiàn)其實這些亂碼其實就是前端頁面標簽。經(jīng)過簡單的頁面轉(zhuǎn)義,就能保存為正常的前端頁面鳞上。

????????????? 然后是視頻信息这吻,現(xiàn)在我能夠獲取視頻的video,但是怎么獲取視頻播放的原始url篙议,是一個很頭疼的問題唾糯。這里的分析后面再說。

?????? 剩下的就是可以寫代碼了鬼贱,寫好之后爬取移怯,結(jié)果爬了一會就沒了,總共就爬了245條这难。因此舟误,就需要轉(zhuǎn)方向,爬取頭條號資料雁佳。


(2)ip被封脐帝,反爬。

????????????? 可能是之前嘗試次數(shù)太多了,頭條將我的ip封掉糖权。最后通過買了阿布云代理搁拙,配置好之后和簸,又能夠順利爬取亡电。


(3)爬取頭條號里面的文章和視頻內(nèi)容

進入一個頭條號頁面:

?????? https://www.toutiao.com/c/user/60018788872/#mid=1566905732637697

這個url可以固定髓迎,重點是爬取里面的文章列表和詳情頁。

?????? 現(xiàn)在我們能獲取每一個單頁面文章或視頻的單頁面內(nèi)容,所以爬頭條號資訊的時候腿堤,只需要解決怎么拉取文章列表和翻頁就可以了阀坏。

?????? 首先是看源代碼,里面沒有任何我需要的文章內(nèi)容的信息笆檀,所以可以判斷是通過其他請求獲取到數(shù)據(jù)的忌堂。


經(jīng)過分析可以得知,獲取文章列表鏈接是:

?????? “https://www.toutiao.com/c/user/article/?page_type=1&user_id=%d&max_behot_time=%d&count=20&as=A185BCF242D2906&cp=5C22825930C6AE1&_signature=“

這些信息每一個都是必須的酗洒,user_id和max_behot_time 都是可以通過前面的文章列表獲取士修。最關(guān)鍵的點是as,cp,_signature這三個值是怎么獲取的,暫時沒有找到出處樱衷。

一開始棋嘲,因為不懂前端代碼,沒想過js會對這里產(chǎn)生影響矩桂,經(jīng)過搜索之后沸移,決定采用模擬瀏覽器的方式進行操作,即使用selenium庫進行操作侄榴。通過模擬瀏覽器發(fā)送請求的方式雹锣,網(wǎng)頁源代碼經(jīng)過模擬瀏覽器渲染,可以獲取到標準的前端展示代碼頁面牲蜀,也就可以直接獲取到笆制,同時通過模擬瀏覽器下拉菜單操作方式绅这,獲取更多的資訊涣达。但是通過這個方式操作之后,發(fā)現(xiàn)有幾個弊端:

[if !supportLists](1)?????[endif]下拉請求時經(jīng)常無法更新頁面证薇,并不是每次請求必有回應(yīng)度苔。

[if !supportLists](2)?????[endif]需要獲取數(shù)據(jù)的時候,每次都是從第一頁開始拉取浑度,翻頁就是下拉菜單寇窑,但是在這過程中我并不能保存頁面,所以無法做到實時存儲箩张。

[if !supportLists](3)?????[endif]爬取速度實在慢的可憐甩骏,其他我都忍了,20分鐘才獲取100多條數(shù)據(jù)先慷,這種速度實在不能忍饮笛。


最后決定放棄這種方式,重新回到找url規(guī)律的問題上來论熙。關(guān)鍵點就是as福青,cp,signature 這三個值怎么獲取。通過百度之后无午,可以知道as媒役,cp這些值,我可以在js中找到對應(yīng)的函數(shù)宪迟。


即上圖這酣衷,可以清楚的看到,里面有一個固定的as次泽,cp函數(shù)鸥诽,最開始,我天然的以為as,cp和signature是有某種函數(shù)關(guān)系存在的箕憾,然后又經(jīng)過百度牡借,可以找到那段函數(shù)。經(jīng)過百度搜索和查詢袭异,最后找到簽名函數(shù)是js中的:

Function(function(e) {

??? return'e(e,a,r){(b[e]||(b[e]=t("x,y","x "+e+"y")(r,a)}a(e,a,r){(k[r]||(k[r]=t("x,y","newx[y]("+Array(r+1).join(",x[y]")(1)+")")(e,a)}r(e,a,r){n,t,s={},b=s.d=r?r.d+1:0;for(s["$"+b]=s,t=0;t>>065:h=,y=,[y]=h66:u(e(t[b],,67:y=,d=,u((g=).x===c?r(g.y,y,k):g.apply(d,y68:u(e((g=t[b])<"<"?(b--,f):g+g,,70:u(!1)71:n72:+f73:u(parseInt(f,3675:if(){bcase74:g=<<16>>16g76:u(k[])77:y=,u([y])78:g=,u(a(v,x-=g+1,g79:g=,u(k["$"+g])81:h=,[f]=h82:u([f])83:h=,k[]=h84:!085:void086:u(v[x-1])88:h=,y=,h,y89:u({e{r(e.y,arguments,k)}e.y=f,e.x=c,e})90:null91:h93:h=0:;default:u((g<<16>>16)-16)}}n=this,t=n.Function,s=Object.keys||(e){a={},r=0;for(cin e)a[r]=c;a=r,a},b={},k={};r'.replace(/[--]/g, function(i) {

??????? return e[15 &i.charCodeAt(0)]

??? })

}("v[x++]=v[--x]t.charCodeAt(b++)-32function return

))++.substrvar .length(),b+=;break;case

;break}".split("")))()('gr$Daten Иb/s!l y?y?g,(lfi~ah`{mv,-n|jqewVxp{rvmmx,&eff?kx[!cs"l".Pq%widthl"@q&heightl"vr*getContextx$"2d[!cs#l#,*;?|u.|uc{uq$fontl#vr(fillTextx$$龘???2<[#c}l#2q*shadowBlurl#1q-shadowOffsetXl#$$limeq+shadowColorl#vr#arcx88802[%c}l#vr&strokex[c}l"v,)}eOmyoZB]mx[ cs!0s$l$Pb>>s!0s%yA0s"l"l!r&lengthb&l!l Bd>&+l!l &+l!l 6d>&+l!l&+ s,y=o!o!]/q"13o!l q"10o!],l 2d>&s.{s-yMo!o!]0q"13o!]*Ld>>b|s!o!l q"10o!],l!&s/yIo!o!].q"13o!],o!]*Jd>>b|&o!]+l &+s0l-l!&l-l!i\'1z141z4b/@d


上面這一坨钠龙,到這里,我就絕望了御铃,這鬼才看得懂碴里。

詢問領(lǐng)導(dǎo)之后,測試才發(fā)現(xiàn)上真,這個函數(shù)值跟as咬腋,cp沒有半毛錢關(guān)系,跟user_id,和max_hot_time 有關(guān)系睡互。但是怎么運行成了問題根竿。

????????????? 在這個地方卡了一天半之后,求助領(lǐng)導(dǎo)就珠,領(lǐng)導(dǎo)在發(fā)現(xiàn)完全一樣請求之后寇壳,依然解決不了問題。最后決定妻怎,將這部分代碼拷貝下來壳炎,然后通過node.js在本地調(diào)用運行。最后獲得正確的signture值逼侦。

????????????? 至此匿辩,今日頭條最難處理的部分就解決了。

????????????? 在測試中還發(fā)現(xiàn)榛丢,在翻頁的時候(翻頁是使用json數(shù)據(jù)中铲球,max_hot_time值進行翻頁),失敗率非常高,一個翻頁需要請求多次涕滋。最后成功拿到文章列表睬辐。

?????? 最后一個要解決的問題就是,怎么通過video_id獲取視頻原始鏈接。經(jīng)過百度溯饵,最終找到一個有效的解密方案(如果沒有這個侵俗,我這輩子就解不開。)丰刊。即:


1.打開http://toutiao.com/a6309254755004875010/隘谣,查看網(wǎng)頁源代碼獲取videoid = 0425d8f0c2bb425d9361c0eb2eeb4f16

2.拼接成如下字符串/video/urls/v/1/toutiao/mp4/{videoid}?r={randint}。其中

3. 將第二步拼接的字符串進行crc32校驗(php有crc32函數(shù)),獲取值為十六進制需轉(zhuǎn)化成十進制crc32("/video/urls/v/1/toutiao/mp4/0425d8f0c2bb425d9361c0eb2eeb4f16?r=7937864853677161")= 4040162423

4.

拼接Urlhttp://i.snssdk.com/video/urls/v/1/toutiao/mp4/{videoid}?r={randint}&s={checksum}

5. 訪問拼接Urlhttp://i.snssdk.com/video/urls/v/1/toutiao/mp4/0425d8f0c2bb425d9361c0eb2eeb4f16?r=2330415823304158&s=4218775840其中main_url為視頻地址(需要base64解碼)啄巧。


至此今日頭條所有內(nèi)容都可以爬取到了寻歧。?????



總結(jié)今日頭條反爬策略:

[if !supportLists]1.?????[endif]封ip,這是最常見的秩仆,最后買個代理码泛,省事省心。

[if !supportLists]2.?????[endif]網(wǎng)頁文章鏈接(關(guān)鍵內(nèi)容)澄耍,通過另外的url請求獲取噪珊,同時進行加密處理(as,cp,signture)

[if !supportLists]3.?????[endif]對網(wǎng)頁js函數(shù)進行了加密處理,鬼才看得懂

[if !supportLists]4.?????[endif]視頻通過videoid獲取網(wǎng)頁播放鏈接齐莲,經(jīng)過三次加密處理才能獲取最終url

[if !supportLists]5.?????[endif]翻頁請求高失敗率痢站,顯著降低了爬蟲獲取信息的速度。


總結(jié)爬蟲策略:

[if !supportLists]1.?????[endif]首先找信息列表和下拉方式的url規(guī)律选酗,分析獲取單頁面信息的規(guī)律阵难,有了三個點,所有爬蟲都可以爬了

[if !supportLists]2.?????[endif]如果是大網(wǎng)站芒填,多百度多github呜叫,網(wǎng)友可以提供非常多的好的思路。

[if !supportLists]3.?????[endif]讀懂前端代碼很重要氢烘。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怀偷,一起剝皮案震驚了整個濱河市家厌,隨后出現(xiàn)的幾起案子播玖,更是在濱河造成了極大的恐慌,老刑警劉巖饭于,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜀踏,死亡現(xiàn)場離奇詭異,居然都是意外死亡掰吕,警方通過查閱死者的電腦和手機果覆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殖熟,“玉大人局待,你說我怎么就攤上這事。” “怎么了钳榨?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵舰罚,是天一觀的道長。 經(jīng)常有香客問我薛耻,道長营罢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任饼齿,我火速辦了婚禮饲漾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缕溉。我一直安慰自己考传,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布证鸥。 她就那樣靜靜地躺著伙菊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敌土。 梳的紋絲不亂的頭發(fā)上镜硕,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音返干,去河邊找鬼兴枯。 笑死,一個胖子當(dāng)著我的面吹牛矩欠,可吹牛的內(nèi)容都是我干的财剖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼癌淮,長吁一口氣:“原來是場噩夢啊……” “哼躺坟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乳蓄,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤咪橙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虚倒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體美侦,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年魂奥,在試婚紗的時候發(fā)現(xiàn)自己被綠了菠剩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡耻煤,死狀恐怖具壮,靈堂內(nèi)的尸體忽然破棺而出准颓,到底是詐尸還是另有隱情,我是刑警寧澤棺妓,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布瞬场,位于F島的核電站,受9級特大地震影響涧郊,放射性物質(zhì)發(fā)生泄漏贯被。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一妆艘、第九天 我趴在偏房一處隱蔽的房頂上張望彤灶。 院中可真熱鬧,春花似錦批旺、人聲如沸幌陕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搏熄。三九已至,卻和暖如春暇赤,著一層夾襖步出監(jiān)牢的瞬間心例,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工鞋囊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留止后,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓溜腐,卻偏偏與公主長得像译株,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挺益,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容