• Python 002- 爬虫爬取淘宝上耳机的信息


    参照:https://mp.weixin.qq.com/s/gwzym3Za-qQAiEnVP2eYjQ

    一般看源码就可以解决问题啦

      1 #-*- coding:utf-8 -*-
      2 import re
      3 import time
      4 import requests
      5 import pandas as pd
      6 from retrying import retry
      7 from concurrent.futures import ThreadPoolExecutor
      8  
      9 start = time.clock()     #计时-开始
     10  
     11 #plist 为1-100页的URL的编号num 
     12 plist = []           
     13 for i in range(1,101):   
     14     #淘宝的页数都是以下面这种形式来结束的,所以使用44
     15     #https://s.taobao.com/search?q=耳机&xxx&s=44
     16     #https://s.taobao.com/search?q=耳机&xxx&s=88
     17     j = 44*(i-1)
     18     plist.append(j)
     19  
     20 listno = plist
     21 datatmsp = pd.DataFrame(columns=[])
     22  
     23 while True: 
     24    @retry(stop_max_attempt_number = 8)     #设置最大重试次数
     25    def network_programming(num):   
     26          #将耳机转换为汉字编码%E8%80%B3%E6%9C%BA
     27       url='https://s.taobao.com/search?q=%E8%80%B3%E6%9C%BA&ssid=s5-e 
     28       &search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1 
     29       &ie=utf8&initiative_id=tbindexz_20170306&fs=1&filter_tianmao=tmall 
     30       &sort=sale-desc&filter=reserve_price%5B50%2C%5D&bcoffset=0 
     31       &p4ppushleft=%2C44&s=' + str(num)  
     32       web = requests.get(url, headers=headers)     
     33       web.encoding = 'utf-8'
     34       return web   
     35  
     36    #多线程       
     37    def multithreading():     
     38       number = listno        #每次爬取未爬取成功的页
     39       event = []
     40     
     41       with ThreadPoolExecutor(max_workers=10) as executor:
     42          for result in executor.map(network_programming,
     43                                     number, chunksize=10):
     44              event.append(result)   
     45       return event
     46     
     47    #隐藏:修改headers参数
     48    #因为淘宝可能会出现反爬虫,所以使用cookie,构建head是很有必要的。尽量把自己伪装成一个浏览器。  
     49    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) 
     50             AppleWebKit/537.36(KHTML, like Gecko)  
     51             Chrome/55.0.2883.87 Safari/537.36'}
     52     
     53    #多线程从json获取数据
     54    listpg = []
     55    event = multithreading()
     56    for i in event:
     57       json = re.findall('"auctions":(.*?),"recommendAuctions"', i.text)
     58       if len(json):
     59          table = pd.read_json(json[0])      
     60          datatmsp = pd.concat([datatmsp,table],axis=0,ignore_index=True)  
     61           
     62          pg = re.findall('"pageNum":(.*?),"p4pbottom_up"',i.text)[0]
     63          listpg.append(pg)      #记入每一次爬取成功的页码
     64     
     65    lists = []
     66    for a in listpg:   
     67        b = 44*(int(a)-1)
     68        lists.append(b)     #将爬取成功的页码转为url中的num值
     69     
     70    listn = listno
     71  
     72    #每次循环将爬取失败的数组清空
     73    listno = []       #将本次爬取失败的页记入列表中 用于循环爬取
     74    for p in listn:
     75        if p not in lists:
     76            listno.append(p)
     77             
     78    if len(listno) == 0:     #当未爬取页数为0时 终止循环!
     79       break
     80        
     81 datatmsp.to_excel('datatmsp1.xls', index=False)    #导出数据为Excel
     82  
     83 end = time.clock()    #计时-结束
     84 print ("爬取完成 用时:", end - start,'s')
     85 
     86 
     87 '''
     88 二、数据清洗、处理: (此步骤也可以在Excel中完成 再读入数据)
     89 '''
     90 datatmsp = pd.read_excel('datatmsp1.xls')     #读取爬取的数据 
     91 #datatmsp.shape   
     92   
     93 # 数据缺失值分析:
     94 # 安装模块:pip3 install missingno
     95 import missingno as msno
     96 msno.bar(datatmsp.sample(len(datatmsp)),figsize=(10,4))   
     97  
     98 # 删除缺失值过半的列
     99 half_count = len(datatmsp)/2
    100 datatmsp = datatmsp.dropna(thresh = half_count, axis=1)
    101  
    102 # 删除重复行:
    103 datatmsp = datatmsp.drop_duplicates()   
    104 
    105 '''
    106 说明:只取了 item_loc, raw_title, view_price, view_sales 这4列数据,
    107 上面的item_loc, raw_title, view_price, view_sales 都是从网页源代码中获取的标签信息
    108 主要对 标题、区域、价格、销量 进行分析,代码如下: 
    109 '''
    110 # 取出这4列数据:
    111 data = datatmsp[['item_loc','raw_title','view_price','view_sales']]   
    112 data.head()    #默认查看前5行数据
    113  
    114 # 对 item_loc 列的省份和城市 进行拆分 得出 province 和 city 两列:
    115 # 生成province列:
    116 # lambda表达式类似于一个没有声明的函数
    117 data['province'] = data.item_loc.apply(lambda x: x.split()[0])
    118  
    119 # 注:因直辖市的省份和城市相同 这里根据字符长度进行判断: 
    120 data['city'] = data.item_loc.apply(lambda x: x.split()[0]   
    121                                 if len(x) < 4 else x.split()[1])
    122  
    123 # 提取 view_sales 列中的数字,得到 sales 列:                                                
    124 #data['sales'] = data.view_sales.apply(lambda x: x.split('人')[0])  
    125  
    126 # 查看各列数据类型
    127 data.dtypes   
    128  
    129 # 将数据类型进行转换                                             
    130 #data['sales'] = data.sales.astype('int') 
    131 
    132 list_col = ['province','city']
    133 for i in  list_col:
    134     data[i] = data[i].astype('category') 
    135  
    136 # 删除不用的列:
    137 data = data.drop(['item_loc','view_sales'], axis=1) 
    138  
    139 
    140 '''
    141 三、数据挖掘与分析:
    142  
    143 【1】. 对 raw_title 列标题进行文本分析:
    144    使用结巴分词器,安装模块pip3 install jieba
    145 '''                 
    146 title = data.raw_title.values.tolist()    #转为list
    147  
    148 # 对每个标题进行分词:  使用lcut函数
    149 import jieba
    150 title_s = []
    151 for line in title:     
    152    title_cut = jieba.lcut(line)    
    153    title_s.append(title_cut)
    154 
    155 '''
    156 对 title_s(list of list 格式)中的每个list的元素(str)进行过滤 剔除不需要的词语,
    157 即 把停用词表stopwords中有的词语都剔除掉:
    158 '''
    159  
    160 # 导入停用词表:
    161 stopwords = pd.read_excel('stopwords.xlsx')        
    162 stopwords = stopwords.stopword.values.tolist()      
    163  
    164 # 剔除停用词:
    165 title_clean = []
    166 for line in title_s:
    167    line_clean = []
    168    for word in line:
    169       if word not in stopwords:
    170          line_clean.append(word)
    171    title_clean.append(line_clean)
    172  
    173 '''
    174 因为下面要统计每个词语的个数,所以 为了准确性 这里对过滤后的数据 title_clean 中的每个list的元素进行去重,
    175 即 每个标题被分割后的词语唯一。 
    176 '''
    177 title_clean_dist = []  
    178 for line in title_clean:   
    179    line_dist = []
    180    for word in line:
    181       if word not in line_dist:
    182          line_dist.append(word)
    183    title_clean_dist.append(line_dist)
    184  
    185  # 将 title_clean_dist 转化为一个list: allwords_clean_dist 
    186 allwords_clean_dist = []
    187 for line in title_clean_dist:
    188    for word in line:
    189       allwords_clean_dist.append(word)
    190  
    191  
    192 # 把列表 allwords_clean_dist 转为数据框: 
    193 df_allwords_clean_dist = pd.DataFrame({'allwords': allwords_clean_dist})
    194  
    195  
    196 # 对过滤_去重的词语 进行分类汇总:
    197 word_count = df_allwords_clean_dist.allwords.value_counts().reset_index()    
    198 word_count.columns = ['word','count']      #添加列名 
    199  
    200  
    201 '''
    202 观察 word_count 表中的词语,发现jieba默认的词典 无法满足需求: 
    203 有的词语(如 可拆洗、不可拆洗等)却被cut,这里根据需求对词典加入新词
    204 (也可以直接在词典dict.txt里面增删,然后载入修改过的dict.txt)
    205 '''
    206 add_words = pd.read_excel('add_words.xlsx')     #导入整理好的待添加词语
    207  
    208 # 添加词语: 
    209 for w in add_words.word:
    210    jieba.add_word(w , freq=1000)  
    211    
    212     
    213 #=======================================================================
    214 # 注:再将上面的 分词_过滤_去重_汇总 等代码执行一遍,得到新的 word_count表
    215 #=======================================================================
    216     
    217 #word_count.to_excel('word_count.xlsx', index=False)    #导出数据
    218  
    219 '''
    220 词云可视化: 见下<图2>
    221 安装模块 wordcloud  
    222 方法:pip3 install wordcloud  
    223 '''
    224 from wordcloud import WordCloud
    225 import matplotlib.pyplot as plt
    226 from scipy.misc import imread    
    227 plt.figure(figsize=(20,10))   
    228  
    229 pic = imread("shafa.png")   #读取图片,自定义‘沙发’形状
    230 w_c = WordCloud(font_path="semplice.ttf",background_color="white", 
    231                 mask=pic, max_font_size=60, margin=1)
    232 wc = w_c.fit_words({x[0]:x[1] for x in word_count.head(100).values})    
    233  
    234 plt.imshow(wc, interpolation='bilinear') 
    235 plt.axis("off")
    236 plt.show()
    237  
    238 '''
    239 以上注释:
    240 shafa.png 是透明背景图 将该图放在Python的项目路径下!
    241 "./data/simhei.ttf"   设置字体
    242 background_color   默认是黑色 这里设置成白色
    243 head(100)   取前100个词进行可视化! 
    244 max_font_size  字体最大字号 
    245 interpolation='bilinear'  图优化   
    246 "off"   去除边框
    247 '''
    248 
    249 '''
    250 不同省份的商品数量分布:
    251 ''' 
    252 plt.figure(figsize=(8,4))
    253 data.province.value_counts().plot(kind='bar',color='purple')
    254 plt.xticks(rotation= 0)       
    255 plt.xlabel('省份')
    256 plt.ylabel('数量')
    257 plt.title('不同省份的商品数量分布')
    258 plt.show()

    得到的结果:

  • 相关阅读:
    Spring AOP总结(三)
    Spring AOP源码解析(二)
    java9新特性
    BeanFactory和ApplicationContext的区别总结
    Elasticsearch7.X为什么移除类型(type)
    elasticsearch性能优化(二)
    elasticsearch性能优化(一)
    elasticsearch的master选举机制
    自动化构建和部署应用系统平台
    关系型数据库之mysql-01
  • 原文地址:https://www.cnblogs.com/hustcser/p/8744355.html
Copyright © 2020-2023  润新知