歡迎光臨
每天分享高質量文章

Python資料解讀京東上最受歡迎的麵包

來自:資料森麟(微訊號:shujusenlin)

作者:黃超 就職頂新集團智慧科技公司 資料從業者

前言

什麼樣的麵包品牌最好賣?什麼樣的口感最受歡迎?相信每一位喜歡麵包的朋友都會關心這些問題。本文透過爬取京東麵包類資料,一方面回答大家關於此前關於麵包的各種問題,另一方面也帶大家瞭解一份完整的資料報告,可以從中有所借鑒。

資料爬取(部分程式碼)

構建解析詳情頁的代理

def disguiser():
'''
構建解析詳情頁的代理
'''
try:
req = request.Request('http://www.agent.cn/xdaili-api//greatRecharge/getGreatIp?spiderId=8f75fb741de34cfb95adf347910db7a9&orderno;=YZ20191169208Yi1jmu&returnType;=2&count;=1')
resp = request.urlopen(req)
jsonIP = resp.read().decode()
jsonIP = re.sub(' ','',jsonIP)
ipList = re.findall('"ip":"(.*?)"',jsonIP)
portList = re.findall('"port":"(.*?)"',jsonIP)
value = list(map(lambda x,y : x + ':' + y,ipList, portList))
key = ['http']
ipDict = {key[index] : value[index] for index in range(len(key))}
print(ipDict)
# 1. 使用ProxyHandler,傳入代理構建一個handler
handler = request.ProxyHandler(ipDict) # key: http/https val: ip:port
# 2. 使用上面建立的handler構建一個opener
opener = request.build_opener(handler)
print(opener)
except:
time.sleep(6)
req = request.Request('http://www.agent.cn/xdaili-api//greatRecharge/getGreatIp?spiderId=8f75fb741de34cfb95adf347910db7a9&orderno;=YZ20191169208Yi1jmu&returnType;=2&count;=1')
resp = request.urlopen(req)
jsonIP = resp.read().decode()
jsonIP = re.sub(' ','',jsonIP)
ipList = re.findall('"ip":"(.*?)"',jsonIP)
portList = re.findall('"port":"(.*?)"',jsonIP)
value = list(map(lambda x,y : x + ':' + y,ipList, portList))
key = ['http']
ipDict = {key[index] : value[index] for index in range(len(key))}
print(ipDict)
# 1. 使用ProxyHandler,傳入代理構建一個handler
handler = request.ProxyHandler(ipDict) # key: http/https val: ip:port
# 2. 使用上面建立的handler構建一個opener
opener = request.build_opener(handler)
return opener

解析詳情頁的內容

def parser(pageQueue, uaPool, priceRequestDoc, PRICEBASEURL, detailRequestDoc, open):
'''
解析詳情頁的內容
'''
detailUrl = pageQueue.get()[1]
print(detailUrl)
# 價格
PRICEURL = PRICEBASEURL + re.search('d+',detailUrl).group()
priceRequestDoc = re.sub(r' ','',priceRequestDoc)
essay-headers_for_price = dict(re.findall('([-wd]*?):(.*)',priceRequestDoc))
essay-headers_for_price.update(uaPool[random.randint(0,len(uaPool)-1)]) # 獲取商品價格資訊請求的essay-headers資訊
req = request.Request(PRICEURL, essay-headers = essay-headers_for_price)
resp = open(req) #第一次響應
print(PRICEURL,'商品價格頁請求響應碼:',resp.getcode())
if resp.getcode() == 200:
info = resp.read().decode()
elif SERVER_ERROR_MIN <= response.status_code < SERVER_ERROR_MAX:
for i in range(5):
time.sleep(i**i) #可以繼續最佳化,第一次1秒,第二次10秒,第三次100秒...
resp = open(req)
if resp.getcode() == 200:
break
elif SERVER_ERROR_MIN <= response.status_code < SERVER_ERROR_MAX:
if response.status_code == 404:
print('page not found')
elif response.status_code == 403:
print('have no right')
else:
pass
info = json.loads(info)
item_price = info[0]['p']

# 名稱 品牌 是否含糖 保質期 配料 包裝 商品產地...
detailRequestDoc = re.sub(r' ','',detailRequestDoc)
essay-headers_for_detail = dict(re.findall('([-wd:]*):(.*)',detailRequestDoc))
essay-headers_for_detail.update(uaPool[random.randint(0,9)]) # 獲取商品價格資訊請求的essay-headers資訊
req = request.Request(detailUrl, essay-headers = essay-headers_for_detail)
resp = open(req) # 第二個響應
print(detailUrl,'詳情頁請求響應:',resp.getcode())
if resp.getcode() == 200:
pass
elif SERVER_ERROR_MIN <= response.status_code < SERVER_ERROR_MAX:
for i in range(5):
time.sleep(i**i) #可以繼續最佳化,第一次1秒,第二次10秒,第三次100秒...
resp = open(req)
if resp.getcode() == 200:
break
elif SERVER_ERROR_MIN <= response.status_code < SERVER_ERROR_MAX:
if response.status_code == 404:
print(detailUrl,'page not found')
elif response.status_code == 403:
print(detailUrl,'have no right')
else:
pass
parser = etree.HTMLParser(encoding = 'gbk')
html = etree.parse(resp, parser = parser)
print(html)
elements = html.xpath("//ul[@class='parameter2 p-parameter-list']//text() | //dl[@class='clearfix']//text()")
detailInfo = list(filter(lambda msg : len(msg.strip()) > 0 and msg, elements))
detailInfo = ('#').join(detailInfo)
try:
item_name = re.search('商品名稱:(.*?)#',detailInfo).group(1)
except AttributeError:
# print('商品沒有 item_name 資訊')
item_name = 'n'
try:
item_id = re.search('d+',detailUrl).group()
except AttributeError:
# print('商品沒有 item_id 資訊')
item_id = 'n'
# 大商品名稱
elementTitle = html.xpath("//title//text()")[0]
elementTitle = elementTitle.strip()
item_fullName = re.search('(【.*】)*(.*)?【',elementTitle).group(2)
# 品牌
elementBrand = html.xpath("//*[@id='crumb-wrap']/div/div[1]/div[7]/div/div/div[1]/a/text()")
elementBrand = list(filter(lambda msg : len(msg.strip()) > 0 and msg, elementBrand))
try:
item_brand = elementBrand[0]
except IndexError:
item_brand = 'npl'
yield {
'item_id':item_id,
'item_fullName':item_fullName,
'item_name':item_name,
'item_price':item_price,
'item_brand':item_brand,
'gross_weight':gross_weight,
'item_origin':item_origin,
'item_certification':item_certification,
'processing_technology':processing_technology,
'packing_unit':packing_unit,
'is_suger':is_suger
}

由於公眾號篇幅有限,無法展示本文全部程式碼,我們已將程式碼放入百度雲盤。後臺回覆“0030”,可以獲取本文程式碼。

分析正文

  後臺回覆“0030”,可以獲取本文程式碼

萬水千山總是情,點個「好看」行不行。

    贊(0)

    分享創造快樂