京公网安备 11010802034615号
经营许可证编号:京B2-20210330
R爬虫之京东商城手机信息批量获取
人手一部智能手机的移动互联网时代,智能手机对很多人来说,它就像我们身上生长出来的一个器官那样重要。如果你不能对各大品牌的『卖点』和『受众』侃上一阵,很可能会被怀疑不是地球人。
今天我们来探索一下,如何从『京东商城』爬取各大品牌的手机信息。
1.预备知识
R爬虫需要掌握的技能包括:
基本的网页知识,如html,XML文件的解析
分析XPath
使用网页开发工具
异常捕捉的处理
字符串的处理
正则表达式的使用
数据库的基本操作
不过不要担心,目前只需要掌握前三项技能,即可开始练习。
前三项技能的掌握可以参考 Automated Data Collection with R 一书。正常情况下,一天之内大致即可掌握。
2.页面分析
(待完善)
3.提取各大品牌的链接
#### packages we need ####
## ----------------------------------------------------------------------- ##
require(stringr)
require(XML)
require(RCurl)
library(Rwebdriver)
setwd("JDDownload")
BaseUrl<-"http://search.jd.com"
quit_session()
start_session(root = "http://localhost:4444/wd/hub/",browser = "firefox")
# post Base Url
post.url(url = BaseUrl)
SearchField<-element_xpath_find(value = '//*[@id="keyword"]')
SearchButton<-element_xpath_find(value = '//*[@id="gwd_360buy"]/body/div[2]/form/input[3]')
#keyword for search
keywords<-'手机'
element_click(SearchField)
keys(keywords)
element_click(SearchButton)
Sys.sleep(1)
#test
get.url()
pageSource<-page_source()
parsedSourcePage<-htmlParse(pageSource, encoding = 'UTF-8')
## Download Search Results
fname <- paste0(keywords, " SearchPage 1.html")
writeLines(pageSource, fname)
#get all the brand url
Brand<-'//*[@id="J_selector"]/div[1]/div/div[2]/div[3]/ul/li/a/@href'
BrandLinks<-xpathSApply(doc = parsedSourcePage, path = Brand)
View(data.frame(BrandLinks))
BrandLinks<-sapply(BrandLinks,function(x){
paste0(BaseUrl,"/",x)
})
save(BrandLinks,file = 'BrandLinks.rda')
4.访问每个品牌的页面,抓取每个品牌下的商品链接
##############Function 1 #################################3##
### 对各品牌的手机页面进行抓取 ########3#
getBrandPage<-function(BrandUrl,foreDownload = T){
#获取某品牌搜索页面
post.url(BrandUrl)
Brand_pageSource<-page_source()
#parse
parsedSourcePage<-htmlParse(Brand_pageSource, encoding = 'UTF-8')
#get brand name
BrandNamePath<-'//*[@id="J_crumbsBar"]/div[2]/div/a/em'
BrandName<-xpathSApply(doc = parsedSourcePage, path = BrandNamePath, fun = xmlValue)
#Save the page
BrandPageName<-paste0(BrandName,'_PageSource.html')
#Create a file
if(!file.exists(BrandName)) dir.create(BrandName)
# save
writeLines(text = Brand_pageSource, con = paste0(BrandName,'/',BrandPageName))
# get the product page url
#path
Brand_AllProductPath<-'//*[@id="J_goodsList"]/ul/li/div/div[4]/a/@href'
#url
Brand_AllProductLinks<-xpathSApply(doc = parsedSourcePage, path = Brand_AllProductPath)
# #remove some false url
# FalseLink<-grep(x = Brand_AllProductLinks,pattern = 'https',fixed = TRUE)
# Brand_AllProductLinks<-Brand_AllProductLinks[-FalseLink]
# add a head
Brand_AllProductLinks<-str_c('http:',Brand_AllProductLinks)
#save and return the url
save(Brand_AllProductLinks,file = paste0(BrandName,'_AllProductLinks.rda'))
return(Brand_AllProductLinks)
}
# test
BrandUrl<-BrandLinks[1]
getBrandPage(BrandUrl)
#get all the links
Brand_ProductLink<-list()
for(i in 1:length(BrandLinks)){
Sys.sleep(10)
Brand_ProductLink[[i]]<-getBrandPage(BrandUrl = BrandLinks[i])
}
#clean the links
All_ProductLink<-lapply(Brand_ProductLink,function(x){
TrueLink<-grep(x = x,pattern = 'http://item.jd.com/',fixed = TRUE,value = FALSE)
return(x[TrueLink])
})
# save the links
save(All_ProductLink,file = 'All_ProductLink.rda')
5.访问每个商品页面,提取有用信息
我们初步提取如下指标:标题(Title),卖点(KeyCount),价格(Price),评论数(commentCount),尺寸(Size),后置摄像头像素(BackBit),后置摄像头像素(ForwardBit),核数(Core),分辨率(Resolution),品牌(Brand),上架时间(onSaleTime).
#################################################
######## Function2 :访问每个商品页面,提取有用信息 ########
Product<-function(ProductLink){
post.url(ProductLink)
Sys.sleep(4)
# get the page
Product_pageSource<-page_source()
#parse
Parsed_product_Page<-htmlParse(Product_pageSource, encoding = 'UTF-8')
# get title,,key count,price,CommentCount and so on
#PATH
TitlePath<-'//*[@id="name"]/h1'
KeyCountPath<-'//*[@id="p-ad"]'
PricePath<-'//*[@id="jd-price"]'
commentCountPath<-'//*[@id="comment-count"]/a'
SizePath<-'//*[@id="parameter1"]/li[1]/div/p[1]'
BackBitPath<-'//*[@id="parameter1"]/li[2]/div/p[1]'
ForwardBitPath<-'//*[@id="parameter1"]/li[2]/div/p[2]'
CorePath<-'//*[@id="parameter1"]/li[3]/div/p[1]'
NamePath<-'//*[@id="parameter2"]/li[1]'
CodePath<-'//*[@id="parameter2"]/li[2]'
BrandPath<-'//*[@id="parameter2"]/li[3]'
onSaleTimePath<-'//*[@id="parameter2"]/li[4]'
ResolutionPath<-'//*[@id="parameter1"]/li[1]/div/p[2]'
Title<-xpathSApply(doc = Parsed_product_Page,path = TitlePath,xmlValue)
KeyCount<-xpathSApply(doc = Parsed_product_Page,path = KeyCountPath,xmlValue)
Price<-xpathSApply(doc = Parsed_product_Page,path = PricePath,xmlValue)
commentCount<-xpathSApply(doc = Parsed_product_Page,path = commentCountPath,xmlValue)
Size<-xpathSApply(doc = Parsed_product_Page,path = SizePath,xmlValue)
BackBit<-xpathSApply(doc = Parsed_product_Page,path = BackBitPath,xmlValue)
ForwardBit<-xpathSApply(doc = Parsed_product_Page,path = ForwardBitPath,xmlValue)
Core<-xpathSApply(doc = Parsed_product_Page,path = CorePath,xmlValue)
Name<-xpathSApply(doc = Parsed_product_Page,path = NamePath,xmlValue)
Code<-xpathSApply(doc = Parsed_product_Page,path = CodePath,xmlValue)
Resolution<-xpathSApply(doc = Parsed_product_Page,path = ResolutionPath,xmlValue)
Brand<-xpathSApply(doc = Parsed_product_Page,path = BrandPath,xmlValue)
onSaleTime<-xpathSApply(doc = Parsed_product_Page,path = onSaleTimePath,xmlValue)
# 整理成data frame
mydata<-data.frame(Title = Title,KeyCount = KeyCount, Price = Price,
commentCount = commentCount, Size = Size, BackBit = BackBit,
ForwardBit = ForwardBit, Core = Core, Name = Name,Code = Code,
Resolution = Resolution,
Brand = Brand, onSaleTime = onSaleTime)
#save the page
FileName<-paste0('Product/',Brand,Code,'_pageSource.html')
writeLines(text = Product_pageSource,con = FileName)
#return the data
return(mydata)
}
# test
quit_session()
start_session(root = "http://localhost:4444/wd/hub/",browser = "firefox")
load(file = 'All_ProductLink.rda')
ProductLink1<-All_ProductLink[[40]][1]
testData<-Product(ProductLink = ProductLink1)
#定义tryCatch
mySpider<-function(ProductLink){
out<-tryCatch(
{
message('This is the try part:')
Product(ProductLink = ProductLink)
},
error=function(e){
message(e)
return(NA)
},
finally = {
message("The end!")
}
)
return(out)
}
## loop
# get all data
ProductInformation<-list()
k <-0
for(i in 1:length(All_ProductLink)){
for(j in 1:length(All_ProductLink[[i]])){
k<-k+1
ProductInformation[[k]]<-mySpider(ProductLink = All_ProductLink[[i]][j])
}
}
# save my data
MobilePhoneInformation<-do.call(rbind,ProductInformation)
View(MobilePhoneInformation)
save(MobilePhoneInformation,file = 'MobilePhoneInformation.rda')
nrow(na.omit(MobilePhoneInformation))
View(MobilePhoneInformation)
最终,获得800多行的信息,除去缺失值,剩下600多行数据,还不赖。 最后的数据可以在这里获得。
不过,数据还需要进一步清洗方能进行分析。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在 MySQL 实际应用中,“频繁写入同一表” 是常见场景 —— 如实时日志存储(用户操作日志、系统运行日志)、高频交易记录(支付 ...
2025-10-30为帮助教育工作者、研究者科学分析 “班级规模” 与 “平均成绩” 的关联关系,我将从相关系数的核心定义与类型切入,详解 “数 ...
2025-10-30对 CDA(Certified Data Analyst)数据分析师而言,“相关系数” 不是简单的数字计算,而是 “从业务问题出发,量化变量间关联强 ...
2025-10-30在构建前向神经网络(Feedforward Neural Network,简称 FNN)时,“隐藏层数目设多少?每个隐藏层该放多少个神经元?” 是每个 ...
2025-10-29这个问题切中了 Excel 用户的常见困惑 —— 将 “数据可视化工具” 与 “数据挖掘算法” 的功能边界混淆。核心结论是:Excel 透 ...
2025-10-29在 CDA(Certified Data Analyst)数据分析师的工作中,“多组数据差异验证” 是高频需求 —— 例如 “3 家门店的销售额是否有显 ...
2025-10-29在数据分析中,“正态分布” 是许多统计方法(如 t 检验、方差分析、线性回归)的核心假设 —— 数据符合正态分布时,统计检验的 ...
2025-10-28箱线图(Box Plot)作为展示数据分布的核心统计图表,能直观呈现数据的中位数、四分位数、离散程度与异常值,是质量控制、实验分 ...
2025-10-28在 CDA(Certified Data Analyst)数据分析师的工作中,“分类变量关联分析” 是高频需求 —— 例如 “用户性别是否影响支付方式 ...
2025-10-28在数据可视化领域,单一图表往往难以承载多维度信息 —— 力导向图擅长展现节点间的关联结构与空间分布,却无法直观呈现 “流量 ...
2025-10-27这个问题问到了 Tableau 中两个核心行级函数的经典组合,理解它能帮你快速实现 “相对位置占比” 的分析需求。“index ()/size ( ...
2025-10-27对 CDA(Certified Data Analyst)数据分析师而言,“假设检验” 绝非 “套用统计公式的机械操作”,而是 “将模糊的业务猜想转 ...
2025-10-27在数字化运营中,“凭感觉做决策” 早已成为过去式 —— 运营指标作为业务增长的 “晴雨表” 与 “导航仪”,直接决定了运营动作 ...
2025-10-24在卷积神经网络(CNN)的训练中,“卷积层(Conv)后是否添加归一化(如 BN、LN)和激活函数(如 ReLU、GELU)” 是每个开发者都 ...
2025-10-24在数据决策链条中,“统计分析” 是挖掘数据规律的核心,“可视化” 是呈现规律的桥梁 ——CDA(Certified Data Analyst)数据分 ...
2025-10-24在 “神经网络与卡尔曼滤波融合” 的理论基础上,Python 凭借其丰富的科学计算库(NumPy、FilterPy)、深度学习框架(PyTorch、T ...
2025-10-23在工业控制、自动驾驶、机器人导航、气象预测等领域,“状态估计” 是核心任务 —— 即从含噪声的观测数据中,精准推断系统的真 ...
2025-10-23在数据分析全流程中,“数据清洗” 恰似烹饪前的食材处理:若食材(数据)腐烂变质、混杂异物(脏数据),即便拥有精湛的烹饪技 ...
2025-10-23在人工智能领域,“大模型” 已成为近年来的热点标签:从参数超 1750 亿的 GPT-3,到万亿级参数的 PaLM,再到多模态大模型 GPT-4 ...
2025-10-22在 MySQL 数据库的日常运维与开发中,“更新数据是否会影响读数据” 是一个高频疑问。这个问题的答案并非简单的 “是” 或 “否 ...
2025-10-22