目录
- 一、需求
- 二、需求分析
- 一级页面数据定位
- 二级页面数据定位
- 小结
- 三、python实现:爬取【应用】需求数据
- 四、python实现:爬取【游戏】需求数据
- 五、【应用】信息翻页问题处理实现
- 小结
一、需求
针对华为应用商城的app信息,获取各层级分类下对应的app信息。本博文暂时只获取一级分类、二级分类及对应的app名称。网站信息如下图所示。
二、需求分析
其实我们就是爬取华为应用商城上的app信息,即手机app商城的信息,将页面转换为手机样式,界面如下所示,这是app的一级分类信息:
随便点击一个分类,以【购物比价】为例,进入下一个页面,如下图所示,就是二级标签信息。
为了获取全部app信息,我们需要点击【更多】,以【热门】的【更多】为例,页面跳转到如下界面:
通过上述分析可知,页面会经过这么几次的跳转,我们需要或者对应的这些页面中的指定数据。下面我们分析如何定位我们想要的数据位置。
一级页面数据定位
首先我们清除请求的数据,然后刷新,点击以“zh_CN”结尾的文件,可以对比页面信息是否是我们对应的数据页面。
将Respose部分的json数据,通过在线的json格式化工具 https://www.sojson , 将json数据格式化为我们易于查看的形式。图下图所示:
将结果保存本地,方便我们查找定位数据位置。
如下图所示,这是我们想要的一级页面数据的位置。
对应的URL地址查看如下图所示
二级页面数据定位
原理同一级定位数据的过程,我们获取Response URL信息,格式化json数据信息。
小结
其实通过定位数据的过程发现,通过其实就是从json数据中,提取我们想要的数据信息。通过对比分析各级的URL地址发现,就是修改我们框定的部分信息,就可以获取各个页面指定的信息。
而对于待修改的地址部分内容,在json数据中找到“detailId”键对应的值进行替换即可。
通过上述分析,下面我们通过代码,直接来感受下。
三、python实现:爬取【应用】需求数据
import requests
import json
import pandas as pd
url = "https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&reqPageNum=1&uri=34789c86f4654624ba9e63cf1353c860&maxResults=25&locale=zh_CN"
def getUrlText(url):
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"}
'''
爬取网页的通用代码框架
'''
try:
r = requests.get(url,headers=headers,timeout=30)
r.raise_for_status() # 如果status_code不等于200,就抛出异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
first_url_text = getUrlText(url)
first_data = json.loads(first_url_text)
first_levels = first_data['layoutData'][1]['dataList']
col_num = 0 # 用来记录存取数据的行数
result = pd.DataFrame(columns=['一级标签','二级标签','app名称']) # 用来存放结果
for i in range(len(first_levels)):
first_level = first_levels[i]['name'] # 一级标签
# 游戏单独处理
if first_level != "游戏":
first_detailId = first_levels[i]['detailId']
second_url = r"https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri="+first_detailId+"&maxResults=25&reqPageNum=1&locale=zh_CN"
second_url_text = getUrlText(second_url)
second_data = json.loads(second_url_text)
second_levels = second_data['layoutData']
for j in range(len(second_levels)):
second_level = second_levels[j]['name'] # 二级标签
second_detailId = second_levels[j]['detailId']
third_url = "https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri="+second_detailId+"&maxResults=25&reqPageNum=1&locale=zh_CN"
third_url_text = getUrlText(third_url)
third_data = json.loads(third_url_text)
third_levels = third_data['layoutData'][0]['dataList']
for k in range(len(third_levels)):
app_name = third_levels[k]['name'] # 对应的app
result = result.append(pd.DataFrame({'一级标签':[first_level],'二级标签':[second_level],'app名称':[app_name]}))
col_num +=1
if col_num%100==1:
print(col_num)
result.to_excel('result2.xlsx',sheet_name='应用',encoding='utf-8',index=False)
结果在文件result2.xlsx中,截图如下:
四、python实现:爬取【游戏】需求数据
【游戏】部分的app信息获取比【应用】部分多一个层级,过程类似,直接上代码感受下:
import panda as pd
import requests
import json
# from bs4 import BeautifulSoup
url = "https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&reqPageNum=1&uri=34789c86f4654624ba9e63cf1353c860&maxResults=25&locale=zh_CN"
def getUrlText(url):
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"}
'''
爬取网页的通用代码框架
'''
try:
r = requests.get(url,headers=headers,timeout=30)
r.raise_for_status() # 如果status_code不等于200,就抛出异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
first_url_text = getUrlText(url)
first_data = json.loads(first_url_text)
first_levels = first_data['layoutData'][1]['dataList']
col_num = 0 # 用来记录存取数据的行数
result = pd.DataFrame(columns=['一级标签','二级标签','三级标签','app名称']) # 用来存放结果
for i in range(len(first_levels)):
first_level = first_levels[i]['name'] # 一级标签
# 游戏单独处理
if first_level == "游戏":
second_detailId = first_levels[i]['detailId']
second_url = r"https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri="+second_detailId+"&maxResults=25&reqPageNum=1&locale=zh_CN"
second_url_text = getUrlText(second_url)
second_data = json.loads(second_url_text)
second_levels = second_data['layoutData'][0]['dataList']
for j in range(len(second_levels)):
third_detailId = second_levels[j]['detailId']
second_level = second_levels[j]['name'] # 二级标签
third_url = r"https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri="+third_detailId+"&maxResults=25&reqPageNum=1&locale=zh_CN"
third_url_text = getUrlText(third_url)
third_data = json.loads(third_url_text)
third_levels = third_data['layoutData']
for k in range(len(third_levels)):
third_level = third_levels[k]['dataList'][0]['name'] # 三级标签
four_detailId = third_levels[k]['dataList'][0]['detailId']
four_url = r"https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri=" +four_detailId+"&maxResults=25&reqPageNum=1&locale=zh_CN"
four_url_text = getUrlText(four_url)
four_data = json.loads(four_url_text)
four_levels = four_data['layoutData'][0]['dataList']
for h in range(len(four_levels)):
app_name = four_levels[h]['name'] # 对应的app
# print([first_level,second_level,third_level,app_name])
result = result.append(pd.DataFrame({'一级标签':[first_level],'二级标签':[second_level],
'三级标签':[third_level],'app名称':[app_name]}))
col_num +=1
if col_num%100==1:
print(col_num)
result.to_excel('result.xlsx',sheet_name='游戏',encoding='utf-8',index=False)
结果部分截图如下所示。
代码本身还有很多要改进的地方,好几处其实是重复应用的,暂且这样过程化梳理;还有一些翻页等等问题。
五、【应用】信息翻页问题处理实现
对第三部分的实现进行了打包处理和部分优化。具体程序如下:
# -*- coding: utf-8 -*-
"""
Created on Sun Jun 21 09:36:17 2020
@author: Administrator
"""
import time
from xlrd import open_workbook
from xlutils.copy import copy
import requests
import json
import pandas as pd
#写入excel,xlutils可以写入到已存在的excel中,xlwt只能每次都重写
def write_xls(filename,row,first_level, second_level, app_name):
rb=open_workbook(filename)
wb=copy(rb)
ws=wb.get_sheet(0)
ws.write(row,0,first_level)
ws.write(row,1,second_level)
ws.write(row,2,app_name)
wb.save(filename)
def getUrlText(url):
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"}
'''
爬取网页的通用代码框架
'''
try:
r = requests.get(url,headers=headers,timeout=30)
r.raise_for_status() # 如果status_code不等于200,就抛出异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
def getAppLabels():
time_start=time.time() # 500个结果开始计时
flag_second = True
flag_third = True
url = "https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&reqPageNum=1&uri=34789c86f4654624ba9e63cf1353c860&maxResults=25&locale=zh_CN"
com_left_url = r"https://appgallery.cloud.huawei/uowap/index?method=internal.getTabDetail&serviceType=13&uri="
com_center_url = r"&maxResults=25&reqPageNum="
com_right_url = r"&locale=zh_CN"
first_url_text = getUrlText(url)
first_data = json.loads(first_url_text)
first_levels = first_data['layoutData'][1]['dataList']
# row = 0 # 用来记录存取数据的行数
global row
# result = pd.DataFrame(columns=['一级标签','二级标签','app名称']) # 用来存放结果
result = []
for i in range(len(first_levels)):
first_level = first_levels[i]['name'] # 一级标签
# 游戏单独处理
if first_level != "游戏":
first_detailId = first_levels[i]['detailId']
# 获取二级标签对应的多页数据
second_page_num = 1 # 页面初值设为1
while flag_second:
second_url = com_left_url + first_detailId + com_center_url+str(second_page_num)+com_right_url
second_url_text = getUrlText(second_url)
second_data = json.loads(second_url_text)
second_levels = second_data['layoutData']
if second_levels == []:#无数据
flag_second = False # 结束循环
else:
second_page_num +=1 # 二级页面自加1
for j in range(len(second_levels)):
second_level = second_levels[j]['name'] # 二级标签
second_detailId = second_levels[j]['detailId']
# 获取三级对应的多页app信息
third_page_num = 1 # 页面初值设为1
while flag_third:
third_url = com_left_url + second_detailId + com_center_url + str(third_page_num) + com_right_url
third_url_text = getUrlText(third_url)
third_data = json.loads(third_url_text)
third_levels = third_data['layoutData']
if third_levels ==[] :#无数据
flag_third=False
else:
third_page_num +=1 # 三级页面自加1
third_levels = third_levels[0]['dataList']
for k in range(len(third_levels)):
app_name = third_levels[k]['name'] # 对应的app
# write_xls('test.xlsx',row,first_level, second_level, app_name)
result.append([first_level, second_level, app_name])
# result = result.append(pd.DataFrame({'一级标签':[first_level],'二级标签':[second_level],'app名称':[app_name]}))
row +=1
if row%500==1:
time_end=time.time() # 500个结果结束计时
print('time cost:%.3f'%(time_end-time_start),'s')
time_start = time.time()
print(row)
print(first_level,": ",second_level)
flag_third = True # 恢复初值
flag_second = True # 恢复初值
return result
# 主程序
if __name__ =="__main__":
row = 0 # 用来记录存取数据的行数
result = getAppLabels()
result = pd.DataFrame(result,columns=['一级标签','二级标签','app名称'])
result.to_excel('result2.xlsx',sheet_name='应用',encoding='utf-8',index=False)
结果示例
我方了,不看不知道,一看吓一跳,这两级标签打下来,7w+应用app;app去重后,单独的应用app数也有近5w个,还不算【游戏】的app数。
注意:最后送大家一套2020最新企业Pyhon项目实战视频教程,点击此处 免费获取一起进步哦!
小结
尝试了几种将结果保存的方式:
- 每次结果直接写入【文件】
- 每次结果添加到【列表】中
- 每次结果添加到【数据框】
简单做了下计时对比,列表和数据框的方式效率差不多,不过对比文件读写方式,优势就体现出来了。
列表 | 数据框 | 文件 |
---|---|---|
鉴于很多博友索要爬虫的结果,遂放置个人微信公众号二维码,关注回复关键词【华为商城】 获取爬虫结果。完整的代码,博文中便是。
博主写博文就是方便对自己所学所做的事做一备份记录或回顾总结。因此原始的代码文件可能保留在不同的电脑或者什么位置,再去溯源可能不太方便,敬请谅解。另外,博文的代码,可能随着时间的推移,网站结构的变动,也可能运行会报错。具体问题,欢迎留言,我们具体沟通解决。
刚开始接触,请多指教,欢迎留言交流!
更多推荐
python爬取华为应用商城app的标签信息
发布评论