美文网首页python热爱者Python新世界
双十一不买吃亏 不买上当,Python采集京东商品信息并可视化!

双十一不买吃亏 不买上当,Python采集京东商品信息并可视化!

作者: 48e0a32026ae | 来源:发表于2018-11-09 16:06 被阅读1次

对于Ajax加载的网页已经分析了好几回,这回来说说利用selenium自动化获取网页信息。

通常对于异步加载的网页,我们需要查找网页的真正请求,并且去构造请求参数,最后才能得到真正的请求网址。而利用selenium通过模拟浏览器操作,则无需去考虑那么多,做到可见即可爬。

当然带来便捷的同时,也有着不利,比如说时间上会有所增加,效率降低。可是对于业余爬虫而言,更快的爬取,并不是那么的重要。

首先在电脑的PyCharm上安装selenium,然后下载与电脑上谷歌浏览器相对应版本的ChromeDriver。由于我的Mac系统版本较新,需要先关闭Rootless内核保护机制,才能够安装,所以也是折腾一番后才成功安装。

针对京东商城笔记本的网页进行分析,这回只要在网页源码上分析,就可以获取笔记本价格、标题、评论数、商家名称、商家性质。

爬取代码如下:

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.support.ui import WebDriverWait

from selenium.common.exceptions import TimeoutException

from selenium.webdriver.common.by import By

from selenium import webdriver

from bs4 import BeautifulSoup

import pymongo

import time

# 连接数据库

client = pymongo.MongoClient(host= localhost , port=27017)

db = client.JD_products

collection = db.products

# 启动浏览器

browser = webdriver.Chrome()

wait = WebDriverWait(browser, 50)

def to_mongodb(data):

# 存储数据信息

try:

collection.insert(data)

print("Insert The Data Successfully")

except:

print( Insert The Data Failed )

def search():

browser.get( https://www.jd.com/ )

try:

# 查找搜索框及搜索按钮,输入信息并点击按钮

input = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#key")))

submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#search > div > div.form > button")))

input[0].send_keys( 笔记本 )

submit.click()

# 查找笔记本按钮及销量按钮,依次点击按钮

button_1 = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_selector > div:nth-child(2) > div > div.sl-value > div.sl-v-list > ul > li:nth-child(1) > a")))

button_1.click()

button_2 = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_filter > div.f-line.top > div.f-sort > a:nth-child(2)")))

button_2.click()

# 获取总页数

page = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, #J_bottomPage > span.p-skip > em:nth-child(1) > b )))

return page[0].text

except TimeoutException:

search()

def next_page(page_number):

try:

# 滑动到网页底部,加载出所有商品信息

browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")

time.sleep(10)

html = browser.page_source

parse_html(html)

# 当网页到达100页时,下一页按钮失效,所以选择结束程序

while page_number == 101:

exit()

# 查找下一页按钮,并点击按钮

button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, #J_bottomPage > span.p-num > a.pn-next > em )))

button.click()

wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#J_goodsList > ul > li:nth-child(60)")))

# 判断翻页成功

wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, "#J_bottomPage > span.p-num > a.curr"), str(page_number)))

except TimeoutException:

return next_page(page_number)

def parse_html(html):

"""

解析商品列表网页

"""

data = {}

soup = BeautifulSoup(html, html.parser )

goods_info = soup.select( .gl-item )

# 查看当前页商品数量,了解是否还有未加载的商品

quantity = item: + str(len(goods_info))

print(quantity)

for info in goods_info:

# 获取商品标题信息

title = info.select( .p-name.p-name-type-2 a em )[0].text.strip()

title = title.replace( 爱心东东 , )

print("title: ", title)

data[ _id ] = title

# 获取商品价格信息

price = info.select( .p-price i )[0].text.strip()

price = int(float(price))

print("price: ", price)

data[ price ] = price

# 获取商品的评论数量

commit = info.select( .p-commit strong )[0].text.strip()

commit = commit.replace( 条评价 , )

if 万 in commit:

commit = commit.split("万")

commit = int(float(commit[0]) * 10000)

else:

commit = int(float(commit.replace( + , )))

print("commit: ", commit)

data[ commit ] = commit

# 获取商品的商店名称

shop_name = info.select( .p-shop a )

if (len(shop_name)) == 1:

print("shop_name: ", shop_name[0].text.strip())

data[ shop_name ] = shop_name[0].text.strip()

else:

print("shop_name: ", 京东 )

data[ shop_name ] = 京东

# 获取商品的商店属性

shop_property = info.select( .p-icons i )

if (len(shop_property)) >= 1:

message = shop_property[0].text.strip()

if message == 自营 :

print("shop_property: ", message)

data[ shop_property ] = message

else:

print("shop_property: ", 非自营 )

data[ shop_property ] = 非自营

else:

print("shop_property: ", 非自营 )

data[ shop_property ] = 非自营

to_mongodb(data)

print(data)

print("

")

def main():

total = int(search())

print(total)

for i in range(2, total+2):

time.sleep(20)

print("第", i-1, "页:")

next_page(i)

if __name__ == "__main__":

main()

虽然一开始就是以笔记本这个关键词去搜索,但是这里还是需要再点击一次笔记本按钮,这是因为直接搜索笔记本会出现平常上课做笔记的那种笔记本,导致会获取无用信息。所以利用京东自身更加详细的归类,得到我们想要的信息。

其中每一个网页有60条商品数据,那么按道理应该有6000条的笔记本商品信息,但是最后却只获取了5992条。

估计两个原因:

1⃣️在MongoDB中商品的标题为主键,商品标题出现重复

2⃣️网页未能加载完所有的商品信息

最后成功获取商品信息

读取MongoDB中数据进行可视化分析

from pyecharts import Bar

import pandas as pd

import numpy as np

import pymongo

client = pymongo.MongoClient( localhost , 27017)

db = client.JD_products

table = db.products

df = pd.DataFrame(list(table.find()))

shop_message = df[df.shop_property == 自营 ].groupby([ shop_name ])

shop_com = shop_message[ shop_name ].agg([ count ])

shop_com.reset_index(inplace=True)

shop_com_last = shop_com.sort_values( count , ascending=False)[:12]

attr = np.array(shop_com_last[ shop_name ])

v1 = np.array(shop_com_last[ count ])

attr = ["{}".format(i.replace( 京东 , ).replace( 旗舰店 , ).replace( 自营 , ).replace( 官方 , ).replace( 京东 , ).replace( 电脑 , ).replace( 产品专营店 , ).replace( 工作站 , ).replace( 笔记本 , )) for i in attr]

v1 = ["{}".format(i) for i in v1]

bar = Bar("京东自营商店笔记本种类排行", title_pos= center , title_top= 18 , width=800, height=400)

bar.add("商家", attr, v1, is_convert=True, xaxis_min=10, yaxis_label_textsize=12, is_yaxis_boundarygap=True, yaxis_interval=0, is_label_show=True, is_legend_show=False, label_pos= right , is_yaxis_inverse=True, is_splitline_show=False)

bar.render("京东自营商店笔记本种类排行.html")

从上面可以看出,ThinkPad位居榜首,也与后面的词云图有所呼应。商务、办公,因为它就是一款以商务办公为主打品牌的笔记本。此外国内品牌联想、华硕、宏碁、华为也在榜上,支持国货!!!

from pyecharts import Bar

import pandas as pd

import pymongo

client = pymongo.MongoClient( localhost , 27017)

db = client.JD_products

table = db.products

df = pd.DataFrame(list(table.find()))

price_info = df[ price ]

bins = [0, 2000, 2500, 3000, 3500, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 16000, 19000, 200000]

level = [ 0-2000 , 2000-2500 , 2500-3000 , 3000-3500 , 3500-4000 , 4000-5000 , 5000-6000 , 6000-7000 , 7000-8000 , 8000-9000 , 9000-10000 , 10000-12000 , 12000-14000 , 14000-16000 , 16000-19000 , 19000以上 ]

price_stage = pd.cut(price_info, bins=bins, labels=level).value_counts().sort_index()

attr = price_stage.index

v1 = price_stage.values

bar = Bar( 笔记本价格分布柱状图 , title_pos= center , title_top= 10 , width=800, height=400)

bar.add( , attr, v1, is_stack=True, xaxis_rotate=30, yaxis_min=0, xaxis_interval=0, is_splitline_show=False, is_label_show=True)

bar.render( 笔记本价格分布柱状图.html )

笔记本价格区间在4000-6000有较大的集中,也一定程度反应出了现在笔记本的中间价位,记得刚上大学那会,价格在5000+的笔记本就能有着不错的配置,LOL特效全开。

from pyecharts import Pie

import pandas as pd

import pymongo

client = pymongo.MongoClient( localhost , 27017)

db = client.JD_products

table = db.products

df = pd.DataFrame(list(table.find()))

shop_message = df.groupby([ shop_property ])

shop_com = shop_message[ shop_property ].agg([ count ])

shop_com.reset_index(inplace=True)

shop_com_last = shop_com.sort_values( count , ascending=False)

attr = shop_com_last[ shop_property ]

v1 = shop_com_last[ count ]

pie = Pie( 商店性质 , title_pos= center , width=800, height=400)

pie.add( , attr, v1, radius=[40, 75], label_text_color=None, is_label_show=True, legend_orient= vertical , legend_pos= left )

pie.render( 商店性质.html )

统计下来自营与非自营,还是小巫见大巫。京东和淘宝最大的区别就是京东有自营产品,送货也快。虽说自营的也有假货,但是还是小概率事件。购买电子产品时,比如手机、电脑等,对于我这种小白而言,我第一选择就是去官网或者京东自营店购买,我是绝对不会去电子城和奸商们斗智斗勇的,即使可能价格会低点。但是官网一般快递比较慢,需要个3-5天,而京东可能只需1-2天,所以京东算是我购买的最优选择。

from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator

import matplotlib.pyplot as plt

import pandas as pd

import pymongo

import jieba

import re

client = pymongo.MongoClient( localhost , 27017)

db = client.JD_products

table = db.products

data = pd.DataFrame(list(table.find()))

data = data[[ _id ]]

text =

for line in data[ _id ]:

r = [a-zA-Z0-9’!"#$%& ()*+,-./:;<=>?@,。?★、…【】《》?“”‘’![]^_`{|}~]+

line = re.sub(r, , line.replace( 笔记本电脑 , ).replace( 英寸 , ))

text += .join(jieba.cut(line, cut_all=False))

backgroud_Image = plt.imread( computer.jpeg )

wc = WordCloud(

background_color= white ,

mask=backgroud_Image,

font_path= msyh.ttf ,

max_words=2000,

stopwords=STOPWORDS,

max_font_size=130,

random_state=30

)

wc.generate_from_text(text)

img_colors = ImageColorGenerator(backgroud_Image)

wc.recolor(color_func=img_colors)

plt.imshow(wc)

plt.axis( off )

wc.to_file("computer.jpg")

print("生成词云成功")

这里把标题中笔记本配置参数全部用正则筛选掉。虽说笔记本参数决定了笔记本的性能,不过真正的去购买一台笔记本时,最重要的还是根据自己的需求和预算,然后再去考虑笔记本参数,最后选择一部适合自己的笔记本。一般的笔记本参数如下:

CPU:酷睿系列i3、i5、i7,标压M与低压U

硬盘:500G、1T、2T

显卡:AMD,NVIDIA

内存:4G,8G

相关文章

  • 双十一不买吃亏 不买上当,Python采集京东商品信息并可视化!

    对于Ajax加载的网页已经分析了好几回,这回来说说利用selenium自动化获取网页信息。 通常对于异步加载的网页...

  • 永远都要对抗囤积欲

    双十一不买,亏了。 双十二不买,亏了。 怕吃亏怕吃亏,永远有一堆洗衣液、沐浴乳、牙膏和面巾纸。 到底在怕什么? 最...

  • 炸金花,推锅子腿走不动

    不就那个摊子,不看,不买,结果就不会上当,知道自己的弱点,长期观察自己。不会上当!

  • 11.11,几家欢喜几家忧

    又是一年双十一,又该剁手了。你的手还在吗? 虽然嘴上说着不买不买,坚决不剁手,身体却很诚实的点开某宝,挑选、放购物...

  • 双十一又来了,是否应该买买买?

    双十一又来了,是否应该买买买? 正方:买买买 反方:不买,不买,不买 以下为反方观点:大家好,我是今天的反方辩手,...

  • 不买不买就不买

    生活中的诱惑有很多,希望自己能够不被迷惑,能规避的就规避,因为一直相信自己的自制力总是会有不靠谱的时候,再说又何必...

  • 《猎场》:胡歌版的挪威森林、盖茨比、肖申克救赎?

    双11,周边人都在谈购物,我不买好像吃亏了,也去淘宝上扫荡,各种无门槛红包、火炬红包、口令红包、定金膨胀翻倍、尾款...

  • 大厨

    双十一之际,我和小三姐嘴上说着不买不买,手上刷着淘宝,偷偷加了十几样购物车,花掉了一半的工资,并美名其曰囤货。虽然...

  • 京东商品评论爬虫

    抓取京东商城商品评论信息,并对这些评论信息进行分析和可视化。下面是要抓取的商品信息,一款女士文胸。这个商品共有红色...

  • 不一样的双十一

    往年的双十一,很少买东西,小孩子都会问我:双十一都不买点东西吗?双十一耶,都不买东西?? 今年想趁这优惠的机会给家...

网友评论

    本文标题:双十一不买吃亏 不买上当,Python采集京东商品信息并可视化!

    本文链接:https://www.haomeiwen.com/subject/eveoxqtx.html