这两天对淘宝的API研究以及相应的数据获取

公司想要做进销存,没办法,上吧~~
原先认为进销存很easy,问了一下仓管才发现,产品的N多属性都需要照顾到,现有的系统是不行了。
……
鉴于淘宝充分的资料,我们还是从淘宝获取一些必要的产品分类、属性比较好~~
PS:为啥我在每个公司第一个事情都是抓取数据?上一次在CI的时候是抓取百度知道、雅虎知识堂。这次又要来获取淘宝的数据,TMD~~
好在淘宝有自己的TOP平台,提供了阿里软件和淘宝的相关API,可以相关API中获取我们需要的数据。
经过这段时间的使用我觉得TOP平台其实发布的还是很仓促的,很多东西都没有相应的文档,可能还需要我们通过曲线的办法来获取,最简单的例子就是 taobao.itemcats.get.v2这个API,需要提供相关的fields字段信息。但是相关字段信息却又没有公布,所以还需要用起来的 API来获取一些数据后自己分析它的字段——简直就是曲线救国啊!!至于怎么获得也是要分情况,大概就是从不需要fields字段的相关API获取,比如 上面那个,我们可以从taobao.itemcats.list.get或者taobao.itemcats.get中获取相关的字段,然后填到 taobao.itemcats.get.v2这个里面来获取。比较不理解TOP为啥干这种事情,难道是因为我获取了它内部的数据所以估计给我一些阻拦? 还是以此来拦住一些开发者??费解~~
另外淘宝对于每一个API获取都需要提供相关的sip_sign来进行验证。对于淘宝的相关API所提供的sip_sign的规则在API文档上面有明确的规定,这里引用一下

签名方式为 md5(appsecret + key + value .... key + value)然后转大写字母,其中key,value对是除签名和图片外的所有请求参数按key做的升序排列, value无需编码。

其中appsecret为你申请的项目时自动生成的一个唯一的appsecret,每个程序不一样。然后的key和value可以在API文档中查阅到, 不过大概看了一下,有一些基本上是必须的,比如sip_appkey、sip_apiname。其中前者为你申请项目时也会自动生成的,个人估计这个是要 和前面的appsecret配合进行验证,否则阿猫阿狗有事没事都来调用一下TOP,淘宝服务器也受不了。sip_apiname每个调用都需要(淘宝 API言:废话,否则我知道你要我干嘛!!)
说了半天,给出一个我调用的实例看一下

define ( " SECRET " , " xxxxxx " ) ;
$params = "" ;
$url = "" ;
$array = array ( " sip_appkey " => xxxx , //xxxx为你申请相应程序的appkey
          
" sip_apiname " => " taobao.itemprop.get " ,
          
" sip_timestamp " => date ( " Y-m-d H:i:s " ) , //部分API需要提供的时间戳和服务器时间戳差距不超过10分钟,所以动态生成
          
" v " => " 1.0 " , //不明白都需要是1.0干嘛还要写
          
" sip_sessionid " => " asjfiasehfisdfdf " , //随便填写,好像是为了加密还是保密用的
          
" cid " => 1201     //需要执行相关分类值
    
) ;
ksort ( $array ) ;
$params .= SECRET ;
foreach ( $array as $key => $value ) {
    
$params .= $key . $value ;
    
$url .= $key . " = " . $value . " & " ;
}
$sign = strtoupper ( md5 ( $params )) ;
$url_prefix = " http://sip.alisoft.com/sip/rest? " ;
$url .= " sip_sign= " . $sign ;
$url = $url_prefix . $url ;

这样子我们就获得了一个真实可用的调用淘宝API的链接地址了。这个地址显示的是XML文件,你可以通过PHP中的DOMDocument对它进行处理,比如存到数据库、或者在你的程序中直接调用,反正随便你啦~~
PS:有些API规定地址只能使用一次,比如本例中的那个,如果你生成URL你在浏览器中访问,第一次是正常的,如果刷新一下的话就会出现1002错误, 那么你重新生成一下就OK了~~而且现在淘宝的API不知道是限定了访问速度还是服务器不堪重负,我在运行这个抓取程序,并且用DOMDocument进 行处理的时候发现时不时会出现URL访问出现1002错误,但是不是每一个都是出现,所以估计不是程序问题,而是TOP平台自身的问题,解决办法也很简 单,程序多运行几次就好了·~不要骂我,我也实在是找不到更好的处理办法了,只能将这个运行了10次左右~~
淘宝API石油身份限制的,总共分成三种,apiType分别是1、2、3.其中apiType=2的时候需要进行用户绑定。也就是你访问了一个API调 用链接,也就是我们上面生成的URL之后,他会返回一个含有一个链接的XML,进入这个链接登录(我登录的是淘宝),然后选择授权时间就可以了,从几分钟 到1个小时不等(最高是1个小时),然后再选择时间内就可以直接调用相应API而不用再次认证了~这个认证是在服务器端的,与浏览器无关。
这其中还涉及到DOMDocument的问题,对DOMDocument我只想说几句,DOMDocument在XML解析是很方便的,尤其是和JS类似 的getElementById和getElementsByTagName让人感觉很直观的对DOM进行处理。但是我觉得在DOMDocument在处 理简单的XML的时候,也就是嵌套不要太多层的情况下还是很好用的,比如我用taobao.itemcats.get.v2和 taobao.itemprops.get.v2这两个API获取分类和属性的时候,由于XML结构非常简单,好像是不超过3层,比如看一下 taobao.itemcats.get.v2返回的XML格式

< rsp >
 
< item_cat >
< cid > 14 </ cid >
< parent_cid > 0 </ parent_cid >
< name > 数码相机/摄像机/图形冲印 </ name >
< is_parent > true </ is_parent >
</ item_cat >
 
< item_cat >
< cid > 21 </ cid >
< parent_cid > 0 </ parent_cid >
< name > 居家日用/厨房餐饮/卫浴洗浴 </ name >
< is_parent > true </ is_parent >
</ item_cat >
 
</ rsp >

这样子用DOMDocument处理非常方便,你完全可以通过tagName将所有数据取出来然后进行重新排列成需要的数组。因为所有的数据都是一次通过tagName就可以选取出来。
但是如果层数太多,像taobao.itemprop.get这种,返回来是一个超级复杂的XML,层数到了5层,你就发现用DOMDocument写出来会非常的复杂,也可能是我对DOMDocument理解的不够,欢迎指正。代码如下:这里是PHP处理代码:

$dom = new DOMDocument () ;
$dom -> load ( $url ) ;
$allContent = $dom -> getElementsByTagName ( " item_prop " ) ;
foreach ( $allContent as $singleContent ){
    
//获取与property对应的pid
    
foreach ( $singleContent -> getElementsByTagName ( " pid " ) as $pids ){
        
$pid = $pids -> nodeValue ;
        
break ;
    
}
    
foreach ( $singleContent -> getElementsByTagName ( " name " ) as $names ){
        
$name = $names -> nodeValue ;
        
break ;
    
}
    
foreach ( $singleContent -> getElementsByTagName ( " must " ) as $musts ){
        
$must = $musts -> nodeValue ;
        
break ;
    
}
    
foreach ( $singleContent -> getElementsByTagName ( " multi " ) as $multis ){
        
$multi = $multis -> nodeValue ;
        
break ;
    
}
    
//        echo $pid."   " . $must ."    " . $multi . "<br />";
    
//将ture和false转化为1和0
    
if ( " true " == $must ){
        
$must = 1 ;
    
} else {
        
$must = 0 ;
    
}
    
if ( " true " == $multi ){
        
$multi = 1 ;
    
} else {
        
$multi = 0 ;
    
}
 
    
$sql = " INSERT INTO `property_detail`(`pid`,`name`,`must`,`multi`) VALUES( {$pid},\"{$name}\",{$must},{$multi} ) " ;
    
//        echo $sql."<br />                ";
    
$db -> query ( $sql ) ;
    
$i = 0 ;
    
$result = array () ;
    
foreach ( $singleContent -> getElementsByTagName ( " prop_value " ) as $values ){
        
foreach ( $values -> getElementsByTagName ( " vid " ) as $vids ){
            
$result [ $i ][ ' vid ' ] = $vids -> nodeValue ;
            
break ;
        
}
        
foreach ( $values -> getElementsByTagName ( " name " ) as $names ){
            
$result [ $i ][ ' name ' ] = $names -> nodeValue ;
            
break ;
        
}
        
foreach ( $values -> getElementsByTagName ( " is_parent " ) as $is_parents ){
            
if ( " true " == $is_parents -> nodeValue ){
                
$tmp = 1 ;
            
} else {
                
$tmp = 0 ;
            
}
            
$result [ $i ][ ' is_parent ' ] = $tmp ;
        
}
        ++
$i ;
    
}
    
$query = " INSERT INTO `property_value`(`vid`,`name`,`is_parent`,`pid`) VALUES " ;
    
foreach ( $result as $eachValue ){
        
if ( ! $eachValue [ ' is_parent ' ]){
            
$eachValue [ ' is_parent ' ] = 0 ;
        
}
        
$query .= " ( {$eachValue['vid']},\"{$eachValue['name']}\",'{$eachValue['is_parent']}',{$pid} ), " ;
    
}
    
$query = substr ( $query , 0 ,- 1 ) ;
}

这是相关的XML代码:

< rsp >
    
< item_prop >
        
< pid > <![CDATA[ 1626891]]>
        
</ pid >
        
< name > <![CDATA[ 健康状况]]>
        
</ name >
        
< must > false </ must >
        
< multi > true </ multi >
        
< prop_values list = " true " >
            
< prop_value >
                
< vid > <![CDATA[ 3228192]]>
                
</ vid >
                
< name > <![CDATA[ 办公室减小肚子]]>
                
</ name >
            
</ prop_value >
            
< prop_value >
                
< vid > <![CDATA[3228193]]>
                
</ vid >
                
< name > <![CDATA[ 对抗电脑/手机辐射]]>
                
</ name >
            
</ prop_value >
        
</ prop_values >
    
</ item_prop >
    
< item_prop >
        
< pid > <![CDATA[ 162689]]>
        
</ pid >
        
< name > <![CDATA[ Hello]]>
        
</ name >
        
< must > false </ must >
        
< multi > true </ multi >
        
< prop_values list = " true " >
            
< prop_value >
                
< vid > <![CDATA[ 322819]]>
                
</ vid >
                
< name > <![CDATA[ 办公室]]>
                
</ name >
            
</ prop_value >
            
< prop_value >
                
< vid > <![CDATA[322819]]>
                
</ vid >
                
< name > <![CDATA[ 对抗]]>
                
</ name >
            
</ prop_value >
        
</ prop_values >
    
</ item_prop >
</ rsp >

需要根据XML的结构,通过getElementsByTagName现将XML分割成一个个小的块之后,再进行进一步的处理。由于以name为 tagname的标签还分布在不同层的XML,所以更加麻烦,还要判断这个name在什么地方~~我觉得我实在是某些方面出了问题。但是从 DOMDocument提供的函数却又找不到更好的处理办法~
最后只想说一个关于PHP编程方面的事情。PHP本身对于变量不需要先定义在使用。这一定程度上方便了程序员的代码编写,但是也要注意,尤其是一些变量只 用在循环中,一些用作计数或者需要进行连接的字符串,最好在循环内部进行一次初始化,也就是赋予一个空值(字符串)或者0(数字),这样子在每次循环中都 会被初始化一下,不会出现你的数字或者字符串随着你的循环的进行而变得超长或者超大——你想啊,每次循环之后相应的字符串或者数字并没有初始化,然后还会 继续执行操作,然后该变量会随着你的循环进行不断增大~最好的办法是使用变量之前将每个变量都进行一次初始化,字符串初始化为”",数字初始化为0,数组 初始化为array().虽然不是必须,但是是一个避免出错的好办法,尤其是循环中!!另外,也要注意变量的作用域,比如只在循环中需要的,你就没有必要 定义一个全局变量~这个其实已经与PHP没有什么关系了,每种语言都是~~
文字表达比较差,希望能被人看懂。

: http://www.breestealth.com/274/taobao_api_and_the_date_form_top.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值