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'] as $k=>$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'] as $img){
               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] as $v){ $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] as $key => $val) { $attrData[trim($val,':')] = trim(strip_tags(strtr($matchValue[1][$key],array('' => ','))),','); } return $attrData; } /** * @brief 挑选列表页面的商品连接 * @return array 商品详情的url */ public function pickGoodsLinkFromList() { $linkExp =''; preg_match_all($linkExp,$this->listPageHtml,$match); if(!isset($match[1])) { throw new Exception('页面缺少商品详情连接'); } return $match[1]; } /** * @brief 获取商品名称从详情页面 * @return string 商品名字 */ public function pickGoodsNameFromShow() { $exp = '/

([^<>]*)<\/h1>/'; 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 = "/
.*?<\/div>/ism"; preg_match($exp,$this->showPageHtml,$match); if(!isset($match[0])) { throw new Exception('没有找到商品名称'); } return strip_tags($match[0]); } /** * @brief 获取商品价格从API * @param $idArray 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); return $this->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 as $key => $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] as $key => $val) { $match[1][$key] = $jdImageServerPre.$val; } return $match[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] as $key => $val) { $val = trim(strip_tags(strtr($val,array('
    ' => ','))),','); $temp = explode(':',$val); if(isset($temp[1])) { $result[$temp[0]] = $temp[1]; } } } return $result; } /** * @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 as $key => $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 ); } return $result; } }

    采集器抽象类
    checkListUrl($url) == false)
            {
                throw new Exception('URL不符合规范');
                exit;
            }
    
            if(!$content = file_get_contents($url))
            {
                throw new Exception('没有采集到列表页面的html代码');
            }
    
            //转码GBK转换UTF-8
            $this->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 字符串转码
         * @param $content 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的合法性
         * @param $url string
         * @return boolean
         */
        abstract public function checkListUrl($url);
    
        /**
         * @brief 检查商品详情url的合法性
         * @param $url string
         * @return boolean
         */
        abstract public function checkShowUrl($url);
    
        /**
         * @brief 采集商品信息
         * @return array
         */
        abstract public function collect();
    }
    

    我在本次采集的操作过程中遇到几个问题给总结下。

    • 注意采集来数据的页面的编码格式,要主相应的判断和转换

    • 注意正则的匹配。采集页面有可能调整对应的正则就需要重新。

    • 注意找出那一部分是页面加载的数据,那一部分是ajax加载过来的数据,要分清楚,不如是得不到数据的

    这里我们可以用火狐浏览器的firebug来查看,那些数据是可以用正则来匹配的


    PHP_京东数据采集_第1张图片
    图片.png
    • 不能用正则匹配的就需要用ajax的请求获得数据如商品详情页商品的价格

    这里获取数据的时间我们要注意下,我在做这里的时间第一次直接用http://p.3.cn/prices/mgets?skuIds= 就可以获取数据,但是后面京东需要验证菜返回数据所以我们可以复制firebug中的连接,进行请求就会有数据了。

    PHP_京东数据采集_第2张图片
    图片.png

    • 这里我做的商品页的商品详情数据没有找到获取的方法,如果有知道的请分享给我。

    你可能感兴趣的:(PHP_京东数据采集)