Python3实例:爬取淘宝商品列表

这个实例是从淘宝爬数据,原文是:http://www.cnblogs.com/nima/p/5324490.html
因为我比较关心的是网络这一块,所以对文章做了很多删改。侧重在理解request、cookie两个模块
至于如何把数据保存到excel,怎么排版,这些是完全没有意义的,不是正式生产环境,做得多么漂亮都没意义。

这次用了很多新的模块或概念:
图像相关的库Pillow,
下载地址 点击打开链接
原文的是把图片链接写到excel里面的,我改了之后就没有了,只是下载下来。

Mozilla:
经常看到这个单词。原来是只Mozilla基金会,为支持和领导开源的Mozilla而设立的一个非营利组织。

cx_Freeze:打包工具,将python程序打包成exe文件。
下载地址: 点击打开链接
打包的稍后再研究。

cookie的内容通过cookiejar模块来操作,代码里面使用的是子类MozillaCookieJar。
cookie详细讲解看这里 点击打开链接
这个类跟父类只是保存和加载文件的方式有所不同。
看一下保存的内容,用\t分割。为方便查看,用""包着了。
cookie.domain:"s.m.taobao.com",访问的域名
initial_dot:"False",域名是否以“.”开始的,要做一些特殊处理。
cookie.path:"/" 好像是文件目录
secure:"False" 安全的
expires:"" 应该是过期时间
name:"JSESSIONID"
value:"770326E8F4997185C7DB2714D7569FF1"

request:
这不是新的模块,但是趁着这次详细了解了一番。

点击打开链接


下面说说具体的代码

1.这里去的是手机淘宝的页面,获得的信息居然是json来的。

2.代码的核心就是从网上下载网页。因为淘宝可能会出现反爬虫,所以使用cookie,构建head是很有必要的。尽量把自己伪装成一个浏览器。

3.把内容写到excel中。怎么写不重要了。反正没什么好看的。一个练习的例子,往往都是下载数据而已。

但是从数据到信息还差一步,这是一个商业秘密了。所以数据获得再多,不能转化为信息,最终还只是练习而已。

好吧,还是看看代码吧。

[python]  view plain  copy
  1. # -*- coding:utf-8 -*-  
  2. import urllib.request, urllib.parse, http.cookiejar  
  3. import os, time,re  
  4. from PIL import Image  
  5. import json  
  6. from openpyxl import Workbook  
  7.    
  8. # 找出文件夹下所有html后缀的文件  
  9. def listfiles(rootdir, prefix='.xml'):  
  10.     file = []  
  11.     for parent, _, filenames in os.walk(rootdir):  
  12.         if parent == rootdir:  
  13.             for filename in filenames:  
  14.                 if filename.endswith(prefix):  
  15.                     file.append(rootdir + '/' + filename)  
  16.             return file  
  17.         else:  
  18.             pass  
  19.   
  20. def writeexcel(path,dealcontent):  
  21.     workbook = Workbook() #构造一个workBook的对象   
  22.     worksheet = workbook.create_sheet('1',0)#构造一个表格。坐标要从1开始的。  
  23.     for i in range(0,len(dealcontent)):  
  24.         for j in range(0,len(dealcontent[i])):  
  25.             if i!=0 and j==len(dealcontent[i])-1:  
  26.                 if dealcontent[i][j] != '':   
  27.                     try:  
  28.                         worksheet.cell(row=i+1,column=j+1).value = dealcontent[i][j]#写入sheet中   
  29.                     except:  
  30.                         pass  
  31.             else:  
  32.                 if dealcontent[i][j]:  
  33.                     worksheet.cell(row=i+1,column=j+1).value = dealcontent[i][j].replace(' ','')   
  34.     workbook.save(path)  
  35.       
  36. #这里才是代码的核心  
  37. def getHtml(url, myProxy='', postdata={}):  
  38.     """ 
  39.         抓取网页:支持cookie 
  40.     url网址,postdata为POST的数据 
  41.  
  42.     """  
  43.     # COOKIE文件保存路径  
  44.     filename = 'cookie.txt'  
  45.   
  46.     # 声明一个MozillaCookieJar对象实例保存在文件中  
  47.     cj = http.cookiejar.MozillaCookieJar(filename)   
  48.   
  49.     # 从文件中读取cookie内容到变量  
  50.     # ignore_discard的意思是即使cookies将被丢弃也将它保存下来  
  51.     # ignore_expires的意思是如果过期了也照样保存  
  52.     # 如果存在,则读取主要COOKIE  
  53.     if os.path.exists(filename):  
  54.         cj.load(filename, ignore_discard=True, ignore_expires=True)  
  55.     # 建造带有COOKIE的处理器  
  56.     cookieHandler = urllib.request.HTTPCookieProcessor(cj)  
  57.     if myProxy:# 开启代理支持  
  58.         #使用代理,就要用到代理的Handler  
  59.         proxyHandler = urllib.request.ProxyHandler({'http':'http://'+myProxy})  
  60.         print('代理:'+myProxy+'启动')  
  61.         opener = urllib.request.build_opener(proxyHandler, cookieHandler )  
  62.     else:  
  63.         opener = urllib.request.build_opener(cookieHandler)  
  64.   
  65.     # 打开专家加头部  
  66.     opener.addheaders = [('User-Agent',  
  67.                           'Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5'),  
  68.                          ('Referer',  
  69.                           'http://s.m.taobao.com'),  
  70.                          ('Host''h5.m.taobao.com')]  
  71.   
  72.     # 分配专家  
  73.     urllib.request.install_opener(opener)  
  74.     # 有数据需要POST  
  75.     if postdata:  
  76.         # 数据URL编码  
  77.         postdata = urllib.parse.urlencode(postdata)  
  78.         html_bytes = urllib.request.urlopen(url, postdata.encode()).read()  
  79.     else:  
  80.         html_bytes = urllib.request.urlopen(url).read()  
  81.   
  82.     # 保存COOKIE到文件中  
  83.     cj.save(ignore_discard=True, ignore_expires=True)  
  84.     return html_bytes  
  85.   
  86. # 去除标题中的非法字符 (Windows)  
  87. def validateTitle(title):  
  88.     rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/\:*?"<>|'  
  89.     new_title = re.sub(rstr, "", title)  
  90.     return new_title  
  91.   
  92. # 递归创建文件夹  
  93. def makeFolder(path):  
  94.     try:  
  95.         os.makedirs(path)  
  96.     except:  
  97.         print('目录已经存在:'+path)  
  98.    
  99. if __name__ == '__main__':  
  100.     #对应目录  
  101.     dataDir = './data'   
  102.     imageDir = './image'  
  103.     makeFolder(dataDir)  
  104.     #表单参数    
  105.     keyword = r'卡包'  
  106.     orderType = 1 #1.按销量优先,2.按价格低到高,3.价格高到低,4.信用排序,5.综合排序  
  107.     pageNum = 10 #需要抓取的页数  
  108.     waitSeconds = 4#每次抓取后暂停时间  
  109.     isGetImage = 1#'抓取图片按1,不抓取按2:'  
  110.     #构建表单      
  111.     postdata = {}  
  112.     postdata['event_submit_do_new_search_auction']= 1  
  113.     postdata['search']= '提交查询'  
  114.     postdata['_input_charset']= 'utf-8'  
  115.     postdata['topSearch']= 1  
  116.     postdata['atype']= 'b'  
  117.     postdata['searchfrom']= 1  
  118.     postdata['action']= 'home:redirect_app_action'  
  119.     postdata['from']= 1  
  120.     postdata['q']= keyword  
  121.     postdata['sst']= 1  
  122.     postdata['n']= 20  
  123.     postdata['buying']= 'buyitnow'  
  124.     postdata['m']= 'api4h5'  
  125.     postdata['abtest']= 16  
  126.     postdata['wlsort']= 16  
  127.     postdata['style']= 'list'  
  128.     postdata['closeModues']= 'nav,selecthot,onesearch'  
  129.     if orderType == 1:  
  130.         postdata['sort'] = '_sale'  
  131.     elif orderType == 2:  
  132.         postdata['sort'] = 'bid'  
  133.     elif orderType== 2:  
  134.         postdata['sort']='_bid'  
  135.     elif orderType==4:  
  136.         postdata['sort']='_ratesum'  
  137.       
  138.     #获取每一页的数据  
  139.     for page in range(0, pageNum):   
  140.         postdata['page']= page   
  141.         taobaoUrl = "http://s.m.taobao.com/search?"   
  142.         try:  
  143.             content1 = getHtml(taobaoUrl, '', postdata)  
  144.             file = open(dataDir + '/' + str(page) + '.json''wb')#这是手机淘宝,获得的是json文件  
  145.             file.write(content1)  
  146.         except Exception as e:  
  147.                 if hasattr(e, 'code'):  
  148.                     print('页面不存在或时间太长.')  
  149.                     print('Error code:', e.code)  
  150.                 elif hasattr(e, 'reason'):  
  151.                         print("无法到达主机.")  
  152.                         print('Reason:  ', e.reason)  
  153.                 else:  
  154.                     print(e)  
  155.         time.sleep(waitSeconds)  
  156.         print('暂停'+str(waitSeconds)+'秒')      
  157.                
  158.     files = listfiles(dataDir, '.json')  
  159.     total = [['页数''店名''商品标题''商品打折价''发货地址''评论数''原价''售出件数''政策享受''付款人数''金币折扣','URL地址','图像URL','图像'],]  
  160.     for filename in files:  
  161.         try:  
  162.             doc = open(filename, 'rb')  
  163.             doccontent = doc.read().decode('utf-8''ignore')  
  164.             product = doccontent.replace(' ''').replace('\n''')  
  165.             product = json.loads(product)  
  166.             onefile = product['listItem']  
  167.         except:  
  168.             print('抓不到' + filename)  
  169.             continue  
  170.         for item in onefile:  
  171.             itemlist = [filename, item['nick'], item['title'], item['price'], item['location'], item['commentCount']]  
  172.             itemlist.append(item['originalPrice'])   
  173.             itemlist.append(item['sold'])  
  174.             itemlist.append(item['zkType'])  
  175.             itemlist.append(item['act'])  
  176.             itemlist.append(item['coinLimit'])  
  177.             itemlist.append('http:'+item['url'])  
  178.             picpath=item['pic_path'].replace('60x60','720x720')  
  179.             itemlist.append(picpath)  
  180.             if isGetImage==1:  
  181.                 if os.path.exists(imageDir):  
  182.                     pass  
  183.                 else:  
  184.                     makeFolder(imageDir)  
  185.                 url=urllib.parse.quote(picpath).replace('%3A',':')  
  186.                 urllib.request.urlcleanup()  
  187.                 try:  
  188.                     pic=urllib.request.urlopen(url)  
  189.                     picno=time.strftime('%H%M%S', time.localtime())  
  190.                     filenamep=imageDir+'/'+picno+validateTitle(item['nick']+'-'+item['title'])  
  191.                     filenamepp=filenamep+'.jpeg'  
  192.                     sfilename=filenamep+'s.jpeg'  
  193.                     filess=open(filenamepp,'wb')#从网络上获得图片  
  194.                     filess.write(pic.read())  
  195.                     filess.close()  
  196.                     img = Image.open(filenamepp)#以图片的格式打开  
  197.                     w, h = img.size  
  198.                     size=w/6,h/6  
  199.                     img.thumbnail(size, Image.ANTIALIAS)  
  200.                     img.save(sfilename,'jpeg')  
  201.                     itemlist.append(sfilename)  
  202.                     print('抓到图片:'+sfilename)  
  203.                 except Exception as e:  
  204.                     if hasattr(e, 'code'):  
  205.                         print('页面不存在或时间太长.')  
  206.                         print('Error code:', e.code)  
  207.                     elif hasattr(e, 'reason'):  
  208.                             print("无法到达主机.")  
  209.                             print('Reason:  ', e.reason)  
  210.                     else:  
  211.                         print(e)  
  212.                     itemlist.append('')  
  213.             else:  
  214.                 itemlist.append('')   
  215.             total.append(itemlist)  
  216.     if len(total) > 1:    
  217.         writeexcel( keyword + '淘宝手机商品.xlsx', total)  
  218.     else:  
  219.         print('什么都抓不到')  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值