PHP语言学习之php+phantomjs实现今日头条的首页推送抓取
小标 2019-04-30 来源 : 阅读 3829 评论 0

摘要:本文主要向大家介绍了PHP语言学习之php+phantomjs实现今日头条的首页推送抓取,通过具体的内容向大家展示,希望对大家学习php语言有所帮助。

本文主要向大家介绍了PHP语言学习之php+phantomjs实现今日头条的首页推送抓取,通过具体的内容向大家展示,希望对大家学习php语言有所帮助。

PHP语言学习之php+phantomjs实现今日头条的首页推送抓取

 第一次搞爬虫,经验不足,爬出来的效果也不是很好,记录一下吧。


 认识的哥们最近在爬今日头条的数据,不过他是做java的。之前也想用php做点爬数据的东西,于是直接也搞今日头条,万一有不明白的地方还能有个人商量。话不多说,上点干货。


 关于爬虫,我之前的认知是,curl+正则,有点模糊,下面一步一步说吧


 一、观察页面


  今日头条的首页推送数据,是通过ajax获取的,打开页面调试我们可以看到下图


  请求是每次滚动条滚动到底部触发的,然后我们右键新页面打开这个链接


 不难发现这是个接口,返回json数据,在线格式化一下,结果如下


      "has_more": ,
     "message": "success",
     "data":         "chinese_tag": "财经",
         "media_avatar_url": "//p1.pstatp.com/large/4d00054b126ceaf920",
         "is_feed_ad": ,
         "tag_url": "news_finance",
         "title": "重要里程碑!中国政府采购服务器列入“中国芯”",
         "single_mode": ,
         "middle_mode": ,
         "abstract": "尽管美国对中兴销售零部件和软件的禁令将被解除。近日有媒体注意到,在中央国家机关发布的新采购名单中,服务器产品的技术要求格外引人注目。",
         "tag": "news_finance",
         "label": ["网络安全", "龙芯", "CPU", "信息安全", "英特尔"],
         "behot_time": 1527057631,
         "source_url": "/group/6558562819279684109/",
         "source": "环球网",
         "more_mode": ,
         "article_genre": "article",
         "comments_count": 628,
         "group_source": 2,
         "item_id": "6558562819279684109",
         "has_gallery": ,
         "group_id": "6558562819279684109",
         "media_url": "/c/user/5954781019/"
     },         "single_mode": ,
         "abstract": "一个动作,一句话语,一个眼神,这些看似微小的细节,有时都有着丰富的内涵,传递出意味深长的信号。中美华盛顿磋商过去已有几天,但美方最近释放的两个小细节,感觉拼出了一个更完整的中美谈判成果。",
         "middle_mode": ,
         "more_mode": ,
         "tag": "news_world",
         "label": ["中美关系", "中兴", "国际"],
         "comments_count": 233,
         "tag_url": "news_world",
         "title": "这两个小细节,拼出一个更完整的中美谈判成果",
         "chinese_tag": "国际",
         "source": "牛弹琴",
         "group_source": 2,
         "has_gallery": ,
         "media_url": "/c/user/3647305700/",
         "media_avatar_url": "//p2.pstatp.com/large/1566/2791711243",
         "image_list":             "url": "//p3.pstatp.com/list/pgc-image/15269858649775498ea28fe"
         },             "url": "//p3.pstatp.com/list/pgc-image/15269858650368af9b6b970"
         },             "url": "//p3.pstatp.com/list/pgc-image/1526985864933a9921fd8d0"
         }],
         "source_url": "/group/6558354654705484295/",
         "article_genre": "article",
         "item_id": "6558354654705484295",
         "is_feed_ad": ,
         "behot_time": 1527057631,
         "image_url": "//p3.pstatp.com/list/190x124/pgc-image/15269858649775498ea28fe",
         "group_id": "6558354654705484295",
         "middle_image": "//p3.pstatp.com/list/pgc-image/15269858649775498ea28fe"
     },         "single_mode": ,
         "abstract": "这个小品还有一个插曲就是原定的女主本来是闫妮,但是在春晚前3天临时换成了金玉婷,登上春晚后,她还被称为是“春晚第一美女”。",
         "middle_mode": ,
         "more_mode": ,
         "tag": "news_entertainment",
         "label": ["春晚", "金玉婷", "抑郁症", "我是大侦探", "潘长江"],
         "comments_count": 229,
         "tag_url": "news_entertainment",
         "title": "曾5次上春晚,患抑郁症淡出,如今做主播没人看,四处走穴很凄凉",
         "chinese_tag": "娱乐",
         "source": "猫眼娱乐",
         "group_source": 2,
         "has_gallery": ,
         "media_url": "/c/user/64781639962/",
         "media_avatar_url": "//p3.pstatp.com/large/2c6b001dd55cf954a3f6",
         "image_list":             "url": "//p3.pstatp.com/list/pgc-image/15270494556167c19bc847f"
         },             "url": "//p3.pstatp.com/list/pgc-image/1527049455588fe78498ed1"
         },             "url": "//p3.pstatp.com/list/pgc-image/152704945540787d17fdfb9"
         }],
         "source_url": "/group/6558629445270241805/",
         "article_genre": "article",
         "item_id": "6558629445270241805",
         "is_feed_ad": ,
         "behot_time": 1527057631,
         "image_url": "//p3.pstatp.com/list/190x124/pgc-image/15270494556167c19bc847f",
         "group_id": "6558629445270241805",
         "middle_image": "//p3.pstatp.com/list/pgc-image/15270494556167c19bc847f"
     }],
     "next":         "max_behot_time": 1527057631
  }


  我们看这个json的结构,data里的就是我们想要的数据,好了我们只要仿造地址然后 curl模拟请求获取数据就得了。


 二、爬虫研发


  分析数据接口


    地址:‘https://www.toutiao.com/api/pc/feed/?max_behot_time=1527057712&category=__all__&utm_source=toutiao&widen=1&tadrequire=true&as=A1656B107572ABC&cp=5B05529AAB2CEE1&_signature=PNjkzBAeZ-Tys2Ie-4uYMTzY5N‘


  对比之后发现,每次触发的ajax地址只有max_behot_time、as、cp、_signature这4个参数有变化。max_behot_time有点像时间戳,格式化一下,果然是。然后就是as、cp、_signature三个变参,百度了下是js对时间戳的加密出来的。


  知乎上对as、cp有一些文章,_signature百度出来的结果很少。


  再次打开页面调试


 找到参数生成的js,格式化js代码找到如下代码


  片段一:返回3个参数


: "_setParams",:  e = (0, h.
            )(),= 0.url = this._url,
                "refresh" === t ? (i = this..length > 0 ? this.[0].behot_time: 0, this.url += "min_behot_time=" + i) : (i = this..length > 0 ? this.[this..length - 1].behot_time: 0, this.url += "max_behot_time=" + n = (0, _.sign)(i + ""); (0, a.)(this.params,: e.,: e.cp,:


  片段二:as、cp 时间戳加密逻辑,对照知乎上那片文章,这个可以用php的逻辑写,easy


           t = Math.(( ).getTime() / 1e3),
         e = t.toString(16).toUpperCase(),
         i = (0, o.
     )(t).toString().          (8 != e.length)              : "479BB4B7254C150",
             cp: "7E0AC8874BB0985"
           ( n = i.slice(0, 5), s = i.slice( - 5), a = "", r = 0; r < 5; r++) a += n[r] +          ( l = "",
         u = 0; u < 5; u++) l += e[u + 3] +                      : "A1" + a + e.slice( - 3),
             cp: e.slice(0, 3) + l + "E1"
      }


  还差一个参数_signature,这个参数有点难找,结合百度找到了js文件


  相关代码片段:


 (t,     (          ‘ 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","new x[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<b;t)s[n="$"+t]=r[n];for(t=0,b=s=a;t<b;t)s[t]=a[t];c(e,0,s)} c(t,b,k){ u(e){v[x]=e} f{g= ,ting(bg)} l{try{y=c(t,b,k)}catch(e){h=e,y=l}}for(h,y,d,g,v=[],x=0;;)switch(g= ){case 1:u(! )4: f5:u( (e){a=0,r=e; {c=a<r;c&&u(e[a]),c}}( 6:y= ,u( (y8:if(g= ,lg,g= ,y===c)b+=g;else if(y!==l)y9: c10:u(s( 11:y= ,u( +y)12:for(y=f,d=[],g=0;g<y;g)d[g]=y.charCodeAt(g)^g+y;u(String.fromCharCode.apply(null,d13:y= ,h=delete  [y]14:  59:u((g= )?(y=x,v.slice(x-=g,y:[])61:u( [ ])62:g= ,k[0]=65599*k[0]+k[1].charCodeAt(g)>>>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( ){bcase 74: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: void 086: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(c in e)a[r]=c;a=r,a},b={},k={};r‘.replace(/[ -]/g,
                       t[15 & e.charCodeAt(0      } ("v[x++]= v[--x] t.charCodeAt(b++)-32 function  return  )) ++ .substr var  .length () ,b+= ;break;case  ;break}".(" ")))()(‘gr$Daten Иb/s!l y?y?g,(lfi~ah`{mv,-n|jqewVxp{rvmmx,&effkx[!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<k7l l!r&lengthb%^l$1+s$j l  s#i$1ek1s$gr#tack4)zgr#tac$! +0o![#cj?o ]!l$b%s"o ]!l"l$b*b^0d#>>>s!0s%yA0s"l"l!r&lengthb<k+l"^l"1+s"j l  s&l&z0l!$ +["cs\‘(0l#i\‘1ps9wxb&s() &{s)/s(gr&Stringr,fromCharCodes)0s*yWl ._b&s o!])l l Jb<k$.aj;l .Tb<k$.gj/l .^b<k&i"-4j!+& s+yPo!]+s!l!l Hd>&l!l Bd>&+l!l <d>&+l!l 6d>&+l!l &+ s,y=o!o!]/q"13o!l q"10o!],l 2d>& s.{s-yMo!o!]0q"13o!]*Ld<l 4d#>>>b|s!o!l q"10o!],l!& s/yIo!o!].q"13o!],o!]*Jd<l 6d#>>>b|&o!]+l &+ s0l-l!&l-l!i\‘1z141z4b/@d<l"b|&+l-l(l!b^&+l-l&zl\‘g,)gk}ejo{cm,)|yn~Lij~em["cl$b%@d<l&zl\‘l $ +["cl$b%b|&+l-l%8d<@b|l!b^&+ q$sign ‘, [.defineProperty(e, "__esModule",         value: !0
  }


  我槽,第一眼看,这代码好尼玛长,php怎么搞啊!


  然后有个想法,我直接用js跑出这个 参数来不就得了吗,easy


  代码实现:(注意sign这个算法的编码,我被搞过) 从这个链接里去复制:https://bbs.125.la/thread-14108290-1-1.html


 <!DOCTYPE html>
 <html>
     <head>
         <title>check</title>
     </head>
     <body>
         <script type="text/javascript" src="{{ URL::asset(‘/assets/js/md5.js‘) }}"></script>
         <script type="text/javascript">
                               e = t.toString(16).toUpperCase(),
                 i = (t.toString()).toUpperCase(),
                 str = ‘‘                  (8 != e.                     str = ‘//www.toutiao.com/api/pc/feed/?max_behot_time=‘+t+‘&category=__all__&utm_source=toutiao&widen=1&tadrequire=true&as=479BB4B7254C150&cp=7E0AC8874BB0985&_signature=‘+TAC.                                        ( n = i.slice(0, 5), s = i.slice( - 5), a = "", r = 0; r < 5; r++                     a += n[r] +                   ( l = "",u = 0; u < 5; u++                     l += e[u + 3] +                  str = ‘//www.toutiao.com/api/pc/feed/?max_behot_time=‘+t+‘&category=__all__&utm_source=toutiao&widen=1&tadrequire=true&as=‘+"A1" + a + e.slice( - 3)+‘&cp=‘+e.slice(0, 3) + l + "E1"+‘&_signature=‘+TAC.                               Function(function(t) {



              t = Math.(( ).getTime() / 1e3              tmpstr =             $(‘body‘).append(‘<p>‘+tmpstr+‘</p>‘         </script>
     </body>
 </html>


  效果参见://58.87.108.192/check (可加时间戳参数,例://58.87.108.192/check/1527057712)


  然后是抓取数据的事了,php没办法抓取动态数据!


  这块我当时很头疼,问了问同事才知道要用v8引擎的拓展去解析


  然后装v8js,资料太少装不上,gg。想别的方法,百度了一下发现抓取动态数据的时候很多人用 phantomjs,无头浏览器,咦,我那哥们也是用的这个。


  安装 phantomjs 博客网上很多,不赘述。放一个链接:https://blog.csdn.net/wanght89/article/details/78320375


  js代码(获取之前页面生成的 url)


  check.js


  page = (‘webpage‘).create(),
      = (‘system‘  url = ‘//58.87.108.192/check‘  (.args.length === 2    url += ‘/‘+.args[1  page.open(url,     (status !== ‘success‘     console.(‘Unable to access network‘   }       ua = page.evaluate(          res =          domres = document.getElementsByTagName(‘p‘         ( i=0;i<domres.length;i++           res.push(domres[i].                  console.    phantom.    });


  php 代码(其实就是一个curl)


  spider.php


 <? 
   
         =        =  
                ->stopTime = ((‘Y-m-d‘         ->  
     
       curlRequest(           =         curl_setopt(,CURLOPT_URL,         curl_setopt(,CURLOPT_RETURNTRANSFER,1         curl_setopt(,CURLOPT_SSL_VERIFYPEER,0         curl_set

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言PHP频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程