PHP_京东数据采集
为什么要做数据采集??
我是一个做网站开发的程序员,做一个网站想要我的网站好看,网站内容 充 实,让网站更加漂亮。如果是我们
自己去录入数据,我们可能要去找 很多资料,还需要美工做很多的图片,这样的成本就会很高。
而且现在京东和淘宝商品数据非常的丰富,我们可以直接写一套数据采集器,直接把数据采集到本网站来使用。
下面直接上代码说明如何做采集
采集时要的参数
1.采集的地址。
这里是采集的jd的列表页,最好是列表页的最后一级分类如:http://list.jd.com/list.html?cat=12218,12222,12243
2.采集的数量。
采集的数量要小于翻页的数量,不然多了没有。
采集方法
/**
* 京东数据的采集
*/
public function jd(){
//采集的数量
number=10;
//采集的地址url='http://list.jd.com/list.html?cat=12218,12222,12243';
//实例化采集的类
jd= new jd_collect(number);
//检查url是否有效
is_url=jd->checkListUrl(url);
if(is_url){
//给类赋值采集的地址
jd->readListPage(url);
//获取列表页商品的详情页url
list=jd->pickGoodsLinkFromList();
//采集到的数据数组
data=jd->collect();
//分类的父级赋值
parent_id=0;
//分类id赋值cate_id=[0,0];
//判断分类是否存在,添加
foreach (data['cat'] ask=>v){cate_id[k]=GoodsCategory::getName(['name'=>v]);
if(!cate_id[k]){
parent_id=GoodsCategory::add([
'name'=>v,
]);
cate_id[k]=&parent_id;
}
}
//对商品进行添加
foreach(data['item'] as v){id = Goods::add([
'name'=>v['name'],
'memo'=>v['name'],
'sell_price'=>v['sell_price'],
'cost_price'=>v['cost_price'],
'market_price'=>v['market_price'],
'sort'=>50,
'img'=>v['img'][0],
'list_img'=>v['img'][0],
'small_img'=>v['img'][0],
'store_num'=>100,
'cate_id'=>cate_id[0],
'cate_two_id'=>cate_id[1],
'start_time'=>time(),
'end_time'=>time()+100*24*60*60,
]);
//对商品的图片进行添加
foreach (v['img'] asimg){
GoodsImg::add([
'goods_id'=>id,
'image'=>img,
'list_img'=>img,
'small_img'=>img,
]);
}
}
}
}
京东数据采集的操作类
number=number; } } /** * @brief 检查列表url */ public function checkListUrl(url) { return strpos(url,'http://list.jd.com/list.html?cat=') === false ? false : true; } /** * @brief 检查详情url */ public function checkShowUrl(url) { return strpos(url,'http://item.jd.com') === false ? false : true; } /** * @brief 挑选分类 * @return array 根据层次返回分类 */ public function pickCatFromList() {catExp = '@
(.+?)@'; preg_match_all(catExp,this->listPageHtml,match); if(!isset(match[0])) { throw new Exception('页面缺少商品分类'); } foreach (match[1] asv){ data[]=strip_tags(v); } return data; } /** * @brief 挑选属性 * @return array 属性数据 */ public function pickAttributeFromList() {keyExp = '@(.+?)@'; $valueExp = '@(.+?)
@'; preg_match_all(keyExp,this->listPageHtml,matchKey); preg_match_all(valueExp,this->listPageHtml,matchValue); if(!isset(matchKey[1])) { throw new Exception('页面缺少商品属性名称'); } if(!isset(matchValue[1])) { throw new Exception('页面缺少商品属性数值'); } //过滤无用的数据 array_shift(matchKey[1]);//移除品牌 array_shift(matchKey[1]);//移除价格 array_shift(matchValue[1]);//移除价格attrData = array(); foreach(matchKey[1] askey => val) {attrData[trim(val,':')] = trim(strip_tags(strtr(matchValue[1][key],array('' => ','))),','); } returnattrData; } /** * @brief 挑选列表页面的商品连接 * @return array 商品详情的url */ public function pickGoodsLinkFromList() { linkExp =''; preg_match_all(linkExp,this->listPageHtml,match); if(!isset(match[1])) { throw new Exception('页面缺少商品详情连接'); } returnmatch[1]; } /** * @brief 获取商品名称从详情页面 * @return string 商品名字 */ public function pickGoodsNameFromShow() { $exp = '/([^]*)/'; preg_match(exp,this->showPageHtml,match); if(!isset(match[0])) { throw new Exception('没有找到商品名称'); } return strip_tags(match[0]); } /** * @brief 获取商品名称从详情页面 * @return string 商品描述 */ public function pickGoodsMemoFromShow() {exp = "/
.*?/ism"; preg_match(exp,this->showPageHtml,match); if(!isset(match[0])) { throw new Exception('没有找到商品名称'); } return strip_tags(match[0]); } /** * @brief 获取商品价格从API * @paramidArray string 商品id数组,如:J_970602 * @return string 商品价格json */ public function getGoodsPriceFromAPI(idString) { //apiUrl = 'http://p.3.cn/prices/mgets?skuIds='.trim(idString,',');apiUrl='http://p.3.cn/prices/get?type=1&area=1_72_4137&pdtk=HxOK%2F%2B%2Fwpjlr75zX3szVoe%2BWRMfuWsRCxWZRS2x7B84nzLc1bJwTzqlQm2fSRjIk&pduid=844111226&pdpin=&pdbp=0&skuid='.trim(idString,',');result = file_get_contents(apiUrl);result = strtr(result,array('J_' => '')); return json_decode(result,true); } /** * @brief 获取商品属性从详情页面 * @return string 商品某属性 */ public function pickGoodsAttributeFromShow() { $exp = '@(.+?)
@s'; preg_match(exp,this->showPageHtml,match); returnthis->cacheAttrData=[]; if(!isset(match[1])) { throw new Exception('没有找到商品属性'); }match[1] = trim(strip_tags(strtr($match[1],array('' => ' ,')))); tempArray = explode(',',match[1]); attrArray = array();tmp = array(); foreach(tempArray askey => val) {tmp = explode(':',val);attrArray[tmp[0]] = trim(tmp[1]); } return this->cacheAttrData =attrArray; } /** * @brief 获取商品图片从详情页面 * @return array 商品的图片url */ public function pickGoodsImageFromShow() { $exp=''; preg_match_all(exp,this->showPageHtml,match); if(!isset(match[1]) || !is_array(match[1])) { throw new Exception('没有找到商品图片'); }jdImageServerPre = 'http://img13.360buyimg.com/n0/'; foreach(match[1] askey => val) {match[1][key] =jdImageServerPre.val; } returnmatch[1]; } /** * @brief 获取商品规格从详情页面 * @return array 商品的规格 array(规格名称=>规格值) */ public function pickGoodsSpecFromShow() { $exp = '@
.*? @s'; preg_match_all(exp,this->showPageHtml,match);result = array(); if(isset(match[0]) &&match[0]) { foreach(match[0] askey => val) {val = trim(strip_tags(strtr(val,array('' => ','))),',');temp = explode(':',val); if(isset(temp[1])) { result[temp[0]] = temp[1]; } } } returnresult; } /** * @brief 获取商品详情从详情页面 * @return string 商品的详情数据 */ public function pickGoodsContentFromShow() { $exp = '@.*@s'; preg_match(exp,this->showPageHtml,match); if(!isset(match[0])) { throw new Exception('没有找到商品详情'); } return strtr(match[0],array('data-lazyload' => 'src')); } /** * @brief 获取商品重量 * @return string 商品重量 */ public function pickGoodsWeightFromShow() { if(!this->cacheAttrData) { this->pickGoodsAttributeFromShow(); } preg_match('@[d.]+@',this->cacheAttrData['商品毛重'],matchAttr); return isset(matchAttr[0]) ? matchAttr[0] : 0; } /** * @brief 获取商品计量单位 * @return string 计量单位 */ public function pickGoodsUnitFromShow() { if(!this->cacheAttrData) { this->pickGoodsAttributeFromShow(); } preg_match('@[d.]+(.*)@',this->cacheAttrData['商品毛重'],matchAttr); return isset(matchAttr[1]) ?matchAttr[1] : '千克'; } /** * @brief 开始采集商品 * @return array('cat' => '商品分类','attr' => '属性','item' => array( * 'goods_no' => '商品编号','up_time' => '上架时间','weight' => '重量','unit' => '计量单位','name' => '商品名字','price' => '商品价格','img' => array(商品图片),'content' => '商品详情','spec' => '商品规格','attr' => '商品属性' * )) */ public function collect() { result = array( 'cat' =>this->pickCatFromList(), // 'attr'=> this->pickAttributeFromList(), 'item'=> array() );goodsUrl = this->pickGoodsLinkFromList(); //取列表页商品的数量goodsUrl=array_slice(goodsUrl,0,this->number); foreach(goodsUrl askey => val) {showurl='http://item.jd.com/'.val.'.html';this->readShowPage(showurl); preg_match('@d+@',val,match);priceObj = this->getGoodsPriceFromAPI('J_'.match[0]); // attrData =this->pickGoodsAttributeFromShow(); result['item'][] = array( // 'goods_no' =>attrData['商品编号'], // 'up_time' => attrData['上架时间'], // 'weight' =>this->pickGoodsWeightFromShow(), // 'unit' => this->pickGoodsUnitFromShow(), 'name' =>this->pickGoodsNameFromShow(), 'sell_price' => priceObj[0]['p'], 'market_price' =>priceObj[0]['m'], 'cost_price' => priceObj[0]['op'], 'img' =>this->pickGoodsImageFromShow(), // 'content'=> this->pickGoodsContentFromShow(), // 'spec' =>this->pickGoodsSpecFromShow(), // 'attr' => attrData ); } returnresult; } }采集器抽象类
checkListUrl(url) == false) { throw new Exception('URL不符合规范'); exit; } if(!content = file_get_contents(url)) { throw new Exception('没有采集到列表页面的html代码'); } //转码GBK转换UTF-8this->listPageHtml = this->converContent(content); } /** * @brief 获取商品详情页面数据 * @param url string 详情页面url */ public function readShowPage(url) { if(this->checkShowUrl(url) == false) { throw new Exception('URL不符合规范'); exit; } content = file_get_contents(url); //转码GBK转换UTF-8 this->showPageHtml =this->converContent(content); } /** * @brief 字符串转码 * @paramcontent string 要转换的字符串 * @return string */ public function converContent(content) { if(this->isUTF8(content) == false) { return iconv('GBK','UTF-8//IGNORE',content); } return content; } public function isUTF8(string) { e=mb_detect_encoding(string, array('UTF-8', 'GBK')); switch(e){ case 'UTF-8' : //如果是utf8编码 return true; break; case 'GBK': //如果是gbk编码 break; } } /** * @brief 检查商品列表url的合法性 * @paramurl string * @return boolean */ abstract public function checkListUrl(url); /** * @brief 检查商品详情url的合法性 * @paramurl string * @return boolean */ abstract public function checkShowUrl($url); /** * @brief 采集商品信息 * @return array */ abstract public function collect(); }
我在本次采集的操作过程中遇到几个问题给总结下。
- 注意采集来数据的页面的编码格式,要主相应的判断和转换
- 注意正则的匹配。采集页面有可能调整对应的正则就需要重新。
注意找出那一部分是页面加载的数据,那一部分是ajax加载过来的数据,要分清楚,不如是得不到数据的
这里我们可以用火狐浏览器的firebug来查看,那些数据是可以用正则来匹配的
图片.png
- 不能用正则匹配的就需要用ajax的请求获得数据如商品详情页商品的价格
这里获取数据的时间我们要注意下,我在做这里的时间第一次直接用http://p.3.cn/prices/mgets?skuIds= 就可以获取数据,但是后面京东需要验证菜返回数据所以我们可以复制firebug中的连接,进行请求就会有数据了。
图片.png
- 这里我做的商品页的商品详情数据没有找到获取的方法,如果有知道的请分享给我。
推荐阅读更多精彩内容
Github标星 8K+,免费又好用的Redis客户端工具!最近在寻找一款免费又好用的Redis客户端工具,于是找到了AnotherRedisDesktopManager,界...梦想de星空阅读 325评论 0赞 7 用python完成淘宝毫秒级抢单,助你秒杀淘宝折扣商品今天给大家提供一种思路,用Python实现秒杀订单,借用自动化方式完成最优解。 1 环境 操作系统:Windows...黑羽_692867294阅读 405评论 1赞 14 教你用Python爬猫眼电影,简单网站却有 “多重思路” !猫眼电影作为爬虫的必备练手网站,相信每个人都试过吧? 那么这篇文章,我就再爬一次猫眼电影,而且用上正则和xpath...黑羽_692867294阅读 165评论 0赞 5 24、比例问题有一些看似特别复杂的比例问题,其实可用直接计算比例的方法: 先看简单的例子【例1】某电器工作功耗为370瓦,待机状...垓下_阅读 28评论 0赞 0 FastAPI项目开发最佳实践最近FastAPI项目特别火,以下是我们项目组在用FastAPI开发时的总结的一些最佳实践以及一些代码规范,分享给...小餐包阅读 463评论 0赞 2
文章来源于互联网,如有雷同请联系站长删除:PHP_京东数据采集