PHP 写爬虫

说实话我也想用Python的,毕竟人家招牌。无奈我Python还停留在看语法的阶段,实在太惭愧,鞭笞一下自己加油学习。这里用php的CURL库进行页面抓取。
同事使用的系统需要先登录,然后有很多自定义图表。每个图表有一个graph_id,根据graph_id可以导出某段时间的csv格式报表以及对应的图形png。

1. 登录cookie

可能做爬虫遇到的第一关就是登录了,通常你要抓取的网页需要先验证登录用户。我们知道通常用户会话状态都是通过SessionID来识别,而SessionID通过cookie保存到客户端。所以当你要先登录在抓取页面的时候,先请求登录接口,获取到cookie保存到本地,后面抓取内容的时候每次带上这个cookie文件就可以了。保存cookie的CURL选项CURLOPT_COOKIEJAR:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
# 保存cookie的代码 $this->cookie_file = '/tmp/cookie.curl.tmp'; curl_setopt($ch, CURLOPT_COOKIEJAR , $this->cookie_file);

然后页面抓取的时候通过设置CURLOPT_COOKIEFILE带上这个cookie:

# 设置cookie的代码 curl_setopt($ch, CURLOPT_COOKIEFILE , $this->cookie_file);

2. 页面重定向

解决了会话session的问题,第二的头疼的就是302301重定向了。重定向的页面response一般没有body部分,头部大概长这样:

HTTP/1.1 302 Found Date: Thu, 29 Jun 2017 09:49:51 GMT Server: Apache/2.2.15 (CentOS) ... Location: curl_test.php?action=real_page Content-Length: 0 Connection: close Content-Type: text/html; charset=UTF-8

那怎么办呢?仔细观察头部信息可以发现里面包含了重定向的目标页面Location: xxx...。而CURL可以通过curl_getinfo($ch, CURLINFO_HTTP_CODE)来获取http状态码,到这里似乎就很清楚接下来该干嘛了。

    // 获取的curl结果 $re = curl_exec($ch); list ($header, $body) = explode("\r\n\r\n", $re, 2); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 有的网站会检查referer地址来判断是否请求来自重定向,这里保存上次请求的url供重定向构造referer使用 $last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); curl_close($ch); if ($http_code == 301 || $http_code == 302) { if (preg_match('/Location:(.*?)\n/', $header, $matches)) { // 继续抓取目标页面 $urlinfo = parse_url($url); // 这里match的url地址可能不一样,所以不一定这么简单的拼接就行 $re_url = $urlinfo['scheme'] . '://' . $urlinfo['host'] . substr($urlinfo['path'], 0, strrpos($urlinfo['path'], '/')+1) . trim($matches[1]); return $this->_http_get($re_url, $last_url); } else { return FALSE; } } else if ($http_code == 200) { return $body; } else { echo 'Error: CURL failed.[url='.$url.']; [http code= '. $http_code.']'; return FALSE; }

有的网站会检查referer地址来判断是否请求来自重定向,通过设置curl的CURLOPT_REFERER参数来伪造HTTP_REFERER

小结

以上可以说是最最基础的爬虫知识,至于正则这里就不介绍了。再往后可能就是下载内容根据Content-type判断文件类型,抓取效率问题,反爬虫策略。总之爬虫就是尽量模拟用户的行为去抓取页面,反爬虫就是尽量挑出哪些请求是爬虫哪些不是,彼此斗智斗勇。等哪天有对爬虫更深入的研究的时候再继续说吧,就到这里了,

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄