写在前面
个人总是觉得代码的目的就是要解决实际问题,这次分享的示例和上次分享的一样也是我实际使用过的。最初是因为女朋友在买菜的时候除了草莓,对其他价格一无所知,经常被宰了也乐呵呵的付钱,于是我就写了此程序来查询每天菜价,来规避这种情况。当我把成品献宝给女朋友时,女朋友非常高兴地把买菜这个事永久性的托付给了我。我裂开了...
本次目的
从实战的方式学习php解析html类库simple_html_dom,并实现对官方公布民生商品价格公示信息的爬取。
实战
首先引用simple_html_dom
include("simple_html_dom.php");
其实simple_html_dom里面内置了file_get_content函数 ,那么秉着学习的目的,我们这次改用curl,其优势在于可以设置请求头,模拟ip模拟,设置reffer,模拟登录等。
function curlHttp($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
$head = array(
'Content-Type: application/x-www-form-urlencoded',
'user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $head);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_NOBODY, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
分析一下目标网站
先分析详情页:
信息是以图片的形式展示的,那么我们整个页面需要提取的就是名称和图片地址,上次分享的时候我们使用的正则表达式,可能有的朋友对正则比较头大,这回引入了simple_html_dom就简单的多基本看了示例代码就可以直接上手。
$htmlson = str_get_html(curlHttp("http://124.93.228.152:8090/view-0ee2ebc5431a486d8533c27f3b3e41c6.jhtml));
$title = $htmlson->find("div[class=article-content] h2",0)->innertext;
$img = $htmlson->find("div[class=article-content] img",0)->src;
$image = curlHttp('http://124.93.228.152:8090'.$img);
这里curlHttp是我们封装的curl获取目标网页的,str_get_html则是simple_html_dom内根据字符串创建DOM,定位到元素的方法很简单,(使用类似jQuery选择器的写法同样也可以识别)。把提取的内容保存到本地还是可以使用fwrite。
分析一下列表页,这里做简单演示只爬取第一页,(很奇怪的列表,竟然是post分页)
$url = "http://124.93.228.152:8090/html/NongMaoShiChang/";
$html = str_get_html(curlHttp($url));
foreach($html->find('ul[class=bmxx-list mb-mar] li a') as $e){
echo $e->href;
}
可以看到引入了simple_html_dom后可以非常简单的定位到元素。
我们简单整合一下代码,就可以使用了。
<?php
include("simple_html_dom.php");
function curlHttp($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
$head = array(
'Content-Type: application/x-www-form-urlencoded',
'user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $head);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_NOBODY, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$dir = './data/images/';
if (!file_exists($dir)){
mkdir ($dir,0777,true);
}
$url = "http://124.93.228.152:8090/html/NongMaoShiChang/";
$html = str_get_html(curlHttp($url));
foreach($html->find('ul[class=bmxx-list mb-mar] li a') as $e){
//echo $e->href;
//echo '<br>';
$htmlson = str_get_html(curlHttp("http://124.93.228.152:8090".$e->href));
$title = $htmlson->find("div[class=article-content] h2",0)->innertext;
$img = $htmlson->find("div[class=article-content] img",0)->src;
$image = curlHttp('http://124.93.228.152:8090'.$img);
$file = fopen($dir.$title.".png","w");
if(fwrite($file, $image)){
echo "下载".$title."成功。<br>";
}else{
echo "下载".$title."失败。<br>";
}
fclose($file);
}
写在后面
爬虫学习部分结束,于整个项目和上次一样还有需要完善的地方,我简单描述一下后续的改进和我的实际应用,首先是爬取完整数据
,其次是设置定时任务每天爬取,改进成增量式爬虫,节约资源。至此爬虫部分结束,额外的改进,每日定时发送最新价格信息到邮箱或者微信,由于图片不太适合手机阅读,使用百度AI的表格文字识别接口生成excel,在转换成json方便搜索查询。