开发环境python2.7.9 os:win-xp exe打包工具pyinstaller 界面tkinter
=============================================
最近有个朋友让我写个小功能,采集当当网数据,生成淘宝数据包
需要采集出版社,作者,主图,价格
采集方式是搜索书名或者ISBN编号
废话不多说,老司机开始上路了
首先,分析当当网数据,这里祭出大杀器,firefox下fire-bug,查看网络数据不再话下
查看源码
<ul id="component_0__0__6612" class="bigimg"> <li id="p20609259" class="line1"> <a class="pic" title=" 远去的历史场景-祀孔大典与孔庙 " ddclick="act=normalResult_picture&pos=20609259_0_2_q" name="itemlist-picture" href="http://product.dangdang.com/20609259.html" target="_blank"> <p class="name" name="title"> <p class="detail"></p> <p class="price"> <p class="dang" style="display: block">当当自营</p> <p class="search_star_line"> <span class="tag_box"> <p class="search_book_author"> <p class="bottom_p"> </li>
看到搜索结果是这样,
看到这个<li id="p20609259" class="line1">标签,怀疑是搜索结果的
检查了下,果然是,后面line1代表第一个
这样就好弄了,id检查了下,就是商品的id,这样更好了,只要采集这个标签就可以获得搜索结果的id列表
代码如下
def get_bookid(keyword): try: api = "http://search.dangdang.com/?key="+keyword+"&act=input" print api urlresponse = urllib2.urlopen(api,timeout=10).read()#.decode("gbk").encode("utf-8") re_id = re.compile(r‘((?<=" id="p)[0-9]+(?=">))‘) id_all = re.findall(re_id,urlresponse) re_price=re.compile(r‘(?<=<span class="search_now_price">¥).+?(?=</span>)‘) price = re.findall(re_price,urlresponse) return id_all,price except Exception, e: print e return [],[]
这里通过ISBN关键词搜索获取到了id列表,和价格列表
2,分析单品源码,看看需要的信息是否都有需要的
查到html代码部分
<meta name="description" content="当当网图书频道在线销售正版《远去的历史场景-祀孔大典与孔庙》,作者:刘亚伟 著,出版社:山东文艺出版社。最新《远去的历史场景-祀孔大典与孔庙》简介、书评、试读、价格、图片等相关信息,尽在DangDang.com,网购《远去的历史场景-祀孔大典与孔庙》,就上当当网。">
meta 里面都有了,出版社,作者
剩下就是主图了
查到html代码部分
<a href="javascript:;" data-imghref="http://img3x9.ddimg.cn/33/0/20609259-1_w.jpg"> <img src="http://img3x9.ddimg.cn/33/0/20609259-1_x.jpg"> </a>
找了下主图都是这种 数字_x或者w,多次测试下来
基本确定了正则表达式
re_img=re.compile(r‘http:.+[0-9]_w_[0-9]+\.jpg‘) re_img1=re.compile(r‘http:.+[0-9]_w\.jpg‘) re_img2=re.compile(r‘http:.+[0-9]_k_[0-9]+\.jpg‘)
这3个正则基本ok了
这样就完成了
最后就是淘宝数据包格式,淘宝数据包是csv格式+文件夹
文件夹里面都是相关图片,格式是tbi,其实就是jpg换了下后缀
然后csv文件格式是unicode的
这里贴出csv数据
csv_head=‘‘‘version 1.00\ntitle\tcid\tseller_cids\tstuff_status\tlocation_state\tlocation_city\titem_type\tprice\tauction_increment\tnum\tvalid_thru\tfreight_payer\tpost_fee\tems_fee\texpress_fee\thas_invoice\thas_warranty\tapprove_status\thas_showcase\tlist_time\tdescription\tcateProps\tpostage_id\thas_discount\tmodified\tupload_fail_msg\tpicture_status\tauction_point\tpicture\tvideo\tskuProps\tinputPids\tinputValues\touter_id\tpropAlias\tauto_fill\tnum_id\tlocal_cid\tnavigation_type\tuser_name\tsyncStatus\tis_lighting_consigment\tis_xinpin\tfoodparame\tsub_stock_type\titem_size\titem_weight\tbuyareatype\tglobal_stock_type\tglobal_stock_country\twireless_desc\tbarcode\tsubtitle\tsku_barcode\tcpv_memo\tinput_custom_cpv\tfeatures\tbuyareatype\tsell_promise\tcustom_design_flag\tnewprepay\tqualification\tadd_qualification\to2o_bind_service\n宝贝名称\t宝贝类目\t店铺类目\t新旧程度\t省\t城市\t出售方式\t宝贝价格\t加价幅度\t宝贝数量\t有效期\t运费承担\t平邮\tEMS\t快递\t发票\t保修\t放入仓库\t橱窗推荐\t开始时间\t宝贝描述\t宝贝属性\t邮费模版ID\t会员打折\t修改时间\t上传状态\t图片状态\t返点比例\t新图片\t视频\t销售属性组合\t用户输入ID串\t用户输入名-值对\t商家编码\t销售属性别名\t代充类型\t数字ID\t本地ID\t宝贝分类\t账户名称\t宝贝状态\t闪电发货\t新品\t食品专项\t库存计数\t物流体积\t物流重量\t采购地\t库存类型\t国家地区\t无线详情\t商品条形码\t宝贝卖点\tsku 条形码\t属性值备注\t自定义属性值\t尺码库\t采购地\t退换货承诺\t定制工具\t7天退货\t商品资质\t增加商品资质\t关联线下服务\n‘‘‘
def csv_table(title="",price="",detail="",pic1="",IBSN="",pub="",zuo="",code=""): csv_line = "%s\t50005701\t\t1\t\t\t1\t%s\t0\t35\t\t1\t0\t0\t0\t1\t1\t1\t0\t\t%s\t\t0\t0\t\t200\t\t0\t%s\t\t\t\"1636953,2043189,46602357,122216620\"\t\"%s,%s,%s,%s\"\t%s\t\t0\t1087745975\t0\t\t不要重复用户名\t0\t0\t0\t\t0\t\t0\t0\t-1\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" % (title,price,detail,pic1,IBSN,zuo,title,pub,code) return csv_line
用上面函数返回单个商品的数据
最后保存
测试了下,基本上能达到90%的覆盖率
============================
不过作为一个老司机,是不满足这个结果的,我们的目标是要完成95%+的覆盖率经过排查,亚马逊上面的覆盖率毕竟高一点,基本上当当上找不到的亚马逊上面都能找到
作为老司机的我当然是要一试亚马逊了,这可是大公司哈
首先,老方法,urllib2.urlopen()先来探探,结果返回各种504什么的看来爬虫是不太好弄了,要模拟浏览器,比较麻烦,突然想起来亚马逊这么大公司,应该有api接口,这里务必提一下,抓网站前先看下是否有api
不然会浪费大量时间,明明都有接口,那么容易得到数据
果然,经过各种搜索,找到了接口下面放出官方测试页面
http://webservices.amazon.cn/scratchpad/index.html
api和key自己注册去,那个什么Associate Tag随便填写就行了
然后比较贴心的就是还有提供php签名实例,简直不要太贴心好吧,这里赞一个
官网给的php是生成api接口,我把最后修改了下,生成以后访问下接口,获取数据,
$handle = fopen($request_url, "rb"); $contents = stream_get_contents($handle); fclose($handle); header(‘Content-Type: text/xml‘); echo $contents;
部署到自己服务器,然后传入一个查询的参数,ok,接口对接完毕,这样就完成了一个属于自己的api接口
返回数据是xml格式,还是挺不错了,
把接口写入python,做了一个函数
def get_book_data_ISBN(keyword): try: api = "http://xxxxxxx/amzon_UPC.php?ISBN="+keyword print api time.sleep(10) data = urllib2.urlopen(api,timeout=10).read() print data if "xml" in data: pic = xml("URL",xml("LargeImage",data)) Author = xml("Author",data) Publisher = xml("Publisher",data) Price = xml("FormattedPrice",data).split(" ")[-1] title = xml("Title",data)[0:40] return pic,Author,Publisher,Price,title else: return "none","none","none","none","none" except Exception, e: print e return "none","none","none","none","none"
最后测试下来,达到了98%的覆盖率,这样的结果还是挺满意的
界面是用tk写的,这里找了vb的一个插件,可以生成python的界面函数,这样就可以愉快的画界面了
直接生成python界面,好用的不要不要的,太省时间了
最后用pyinstaller打包程exe,测试下来用这个打包还是挺稳定的,win7,win10,xp都可以运行
最终界面如下