用python买手机

用python买手机

最近某同学一直碎碎念要买P20,我想说此时买似不太明智,但不知从何说起,恰逢放假,闲来无事,遂用python爬取淘宝、京东手机销售数据做个简单分析,本博客主要实现了以下功能

  • 爬取淘宝上手机的月销售数据并存为excel表格

  • 统计淘宝上不同品牌手机的月销量并以条形图形式展示

  • 使用python代码打开浏览器搜索京东上手机数据并爬取

  • 统计京东上不同手机品牌的评价量并以条形图形式展示


爬取淘宝数据

def key_name( number ):
    #获取页面的内容并返回
    name = '手机'
    URL_1 = "https://s.taobao.com/search?ie=utf8&initiative_id=staobaoz_20170905&stats_click=search_radio_all%3A1&js=1&imgfile=&q="
    URL_2 = "&suggest=0_1&_input_charset=utf-8&wq=u&suggest_query=u&source=suggest&p4ppushleft=5%2C48&s="
    URL = ( URL_1 + name + URL_2 + str(number))
    #print(URL)
    res = requests.get( URL )
    return res.text
  • 获取数据块
    查看淘宝搜索手机后所在页面源代码如图
    源代码截图
    可以看到,我所需要的手机价格与月销量等数据在data:之后,header之前,因此使用正则表达式来获取数据块,获取数据块代码如下:
def find_date( text):
    #根据整个页面的信息,获取商品的数据所在的HTML源码并放回
    reg = r',"data":{"spus":\[({.+?)\]}},"header":'
    reg = re.compile(reg)
    info = re.findall(reg, text)
    return info[0]
  • 解析数据
    获取到数据块之后,需要从数据块中解析需要的手机品牌、配置、价格、月销量等数据。需要注意的是,代码获取的价格和月销量为字符串形式,需要强制转换为int型再写入excel表格。
    对于计算不同品牌手机的月销量问题,采用字符串查找方式,比如华为手机,在手机商品的标题中查找‘华为’、‘荣耀’关键词,如查找到,则该手机则认为是华为手机,月销量加在华为手机上。
    代码如下:
def manipulation_data( info, sales_count, sheet ):
    #解析获取的HTML源码,获取数据
    Date = eval(info)

    for d in Date:
        T = " ".join([t['tag'] for t in d['tag_info']])
        #print(d['title'] + '\t' + d['price'] + '\t' + d['importantKey'][0:len(d['importantKey'])-1] + '\t' + T)
        #将数据写入对应的excel表格中
        sheet.write(sales_count['line'],0,d['title'])
        sheet.write(sales_count['line'],1,int(d['price']))
        sheet.write(sales_count['line'],2,int(d['month_sales']))
        sheet.write(sales_count['line'],3,T)
        #统计不同品牌手机的月销售量
        for key in sales_count.keys():
            if str(d['title']).find('荣耀')>=0:
                sales_count['华为']=sales_count['华为']+(int(d['month_sales']))
            elif str(d['title']).find(str(key))>=0:
                sales_count[key]=sales_count[key]+(int(d['month_sales']))
        sales_count['line']= sales_count['line'] + 1
    return sales_count
  • 绘制条形图
    得到不同品牌手机月销量后,需要对其进行按月销量进行排序,使用sorted方法,排序完成后再使用dict方法强制转换为字典形式,我写了两个绘制条形图函数,可根据需要调用,使用包主要是matplotlib和pygal:
def show(sales_count):
    #按照手机销售量进行排序并绘图(网页版)
    sales_count=dict(sorted(sales_count.items(),key=lambda d:d[1],reverse=True))
    print('正在绘制直方图')
    picture=pygal.Bar()
    picture.title="各大品牌手机月销售量直方图   by社会主义接班人1号"
    picture.x_labels=sales_count.keys()
    sales_count.keys()
    picture.x_title="手机品牌"
    picture.y_title="月销售量"
    picture.add('淘宝',sales_count.values())
    picture.render_to_file('淘宝手机月销售量直方图.svg')
    print('绘制完成')
    print(sales_count)

def show2(sales_count):
    #按照手机销售量进行排序并绘图(图片版)
    sales_count=dict(sorted(sales_count.items(),key=lambda d:d[1],reverse=True))
    print('正在绘制直方图')
    x=[0,1,2,3,4,5,6,7,8,9,10]
    picture=plt.bar(x,sales_count.values(),width=0.4,tick_label=list(sales_count.keys()),fc='r')
    for rect in picture:
        h=rect.get_height()
        plt.text(rect.get_x()+rect.get_width()-0.6,1.03*h,'%d'% int(h))
    plt.xlabel('手机品牌')
    plt.ylabel('月销售量')
    plt.title('各大品牌手机月销售量直方图   by社会主义接班人1号')
    plt.savefig("淘宝手机月销售量直方图.jpg")
    print('绘制完成')
    plt.show()
    print(sales_count)
  • 主函数
    主函数如下:
def main():
    #初始化建立字典,key为手机品牌,value为月销量
    sales_count={'华为':0,'小米':0,'苹果':0,'vivo':0,'OPPO':0,'魅族':0,'纽曼':0,'尼凯恩':0,'诺基亚':0,'三星':0,'联想':0,'line':1}
    book = Workbook()
    #建立excel表格
    sheet = book.add_sheet('淘宝手机数据')
    sheet.write(0,0,'品牌')
    sheet.write(0,1,'价格')
    sheet.write(0,2,'月销售量')
    sheet.write(0,3,'配置')
    book.save('淘宝手机数据.xls')
    #k用于生成链接,每个链接的最后面的数字相差48.
    #sales_count['line']用于记录表格的数据行数,便于写入数据
    #end为结束页数,可通过end控制获取数据数量
    k = 0
    end=20
    for i in range(end+1):
        text = key_name( k + i * 48 )
        info = find_date(text)
        sales_count= manipulation_data( info ,sales_count, sheet )

        book.save('淘宝手机数据.xls')
        print('爬取第' + str(i) + '页数据完成,共'+str(end)+'页')
    del sales_count['line']
    #show(sales_count)
    show2(sales_count)
  • 运行结果
    这里写图片描述
    这里写图片描述
    这里写图片描述

爬取京东数据

京东的情况与淘宝略有不同,京东是搜索一页商品后,鼠标下滑加载下一页,因此需要用到webdriver模拟浏览器打开鼠标下滑操作,并且京东数据块也与淘宝有所不同。并且京东并没有月销量,只有评价人数。不同代码如下:

def key_name( driver,number ):
    #获取页面的内容并返回
    name = '手机'
    URL_1 = "https://search.jd.com/Search?keyword="
    URL_2 = "&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq="
    URL_3="&cid2=653&cid3=655&page="
    URL_4 = "&s=1&click=0"
    URL = ( URL_1 + name + URL_2 + name + URL_3+ str(number)+URL_4)
    #driver = webdriver.Firefox()
    #driver.implicitly_wait(3)
    driver.get(URL)

    # 模拟下滑到底部操作
    for i in range(1, 5):
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(1)

    # 将加载好的页面源码给bs4解析
    soup = BeautifulSoup(driver.page_source, "html.parser")
    t=0

    # 进行信息的抽取(商品名称,价格)
    goods_info = soup.select(".gl-item")
    #driver.close()
    return goods_info



def manipulation_data( goods_info, sales_count, sheet ):
    #解析获取的HTML源码,获取数据并对数据进行解析
    for info in goods_info:
        title = info.select(".p-name.p-name-type-2 a")[0].text.strip()
        price_str = info.select(".p-price")[0].text.strip()
        count_str = info.select(".p-commit")[0].text.strip()
        #print (title)
        price_start=price_str.find('¥')+1
        price_end=price_str.find('.')
        price=int(price_str[price_start:price_end])
        #print (price)
        if(count_str.find('\n'))>=0:
            count_start=count_str.find('\n')+1
        else:
            count_start=0
        if(count_str.find('万+'))>=0:
            count=float(count_str[count_start:count_str.find('万')])*10000
        elif(count_str.find('+'))>=0:
            count=int(count_str[count_start:count_str.find('+')])
        #print(count)
        sheet.write(sales_count['line'],0,title)
        sheet.write(sales_count['line'],1,int(price))
        sheet.write(sales_count['line'],2,int(count))
        for key in sales_count.keys():
            if str(title).find('荣耀')>=0:
                sales_count['华为']=sales_count['华为']+(int(count))
            elif str(title).find('Apple')>=0:
                sales_count['苹果']=sales_count['苹果']+(int(count))
            elif str(title).find(str(key))>=0:
                sales_count[key]=sales_count[key]+(int(count))
        sales_count['line']= sales_count['line'] + 1
    return sales_count



def main():
    sales_count={'华为':0,'小米':0,'苹果':0,'vivo':0,'OPPO':0,'魅族':0,'纽曼':0,'尼凯恩':0,'诺基亚':0,'三星':0,'联想':0,'line':1}
    book = Workbook()
    sheet = book.add_sheet('京东手机数据')
    sheet.write(0,0,'手机')
    sheet.write(0,1,'价格')
    sheet.write(0,2,'评价数量')
    book.save('京东手机数据.xls')
    driver = webdriver.Firefox()
    driver.implicitly_wait(3)
    end=30
    #sales_count['line']用于记录表格的数据行数,便于写入数据  
    for i in range(end):
        goods_info = key_name(driver,i*2)
        sales_count= manipulation_data( goods_info ,sales_count, sheet )    
        book.save('京东手机数据.xls')
        print('爬取第' + str(i+1) + '页数据完成,共'+str(end)+'页')
    del sales_count['line']
    #show(sales_count)
    show2(sales_count)
  • 运行结果
    这里写图片描述
    这里写图片描述
    这里写图片描述
    对比淘宝和京东数据发现,淘宝上华为一马当先,京东上几乎是华为、苹果各占半壁江山,都说华为赚钱,这次我信了。

爬取淘宝全部源代码https://download.csdn.net/download/weixin_42911616/10605090
爬取京东全部源代码https://download.csdn.net/download/weixin_42911616/10605100

本文完

1

  1. 部分代码来源网络,如有侵权,请联系

猜你喜欢

转载自blog.csdn.net/weixin_42911616/article/details/81506154