在python数据分析析方面,比起python,excel的局限性在哪

《数据科学与大数据技术》训练营: 初级以统计分析为主,工具是R语言;中级是大数据处理+算法+python 课程以实战为主,30%的内容是案例和练习,学完就可以上手/Blog/archives/45839
> R语言与Excel之数据分析功能比较
我从事数据分析工作已经有十年之久。最初是出于工作需要,我的经理给我一堆数据,我需要处理这些数据。当时我一直使用的工具是 Exce,因为这是我熟练掌握的一款工具。三年前,我开始接触到 R,一开始因为功能太多而坚决抵制使用。后来我开始琢磨如何使用。现在我基本不怎么使用 Excel 了。这只是我个人的观点,但是如果你要分析数据,R 更胜任这项任务。下面来说说为什么 R 更适合数据分析。
这两款工具的使用方法截然不同。使用 Excel 时,可以通过鼠标点击完成大部分工作,你可以访问界面内不同位置的各种工具。因此 Excel 非常便于使用(熟能生巧),但是用 Excel 处理数据非常费时,而且如果接手一个新项目,你必须单调地重复这些流程。使用 R 时,则通过代码完成所有操作。你把数据载入内存,然后运行脚本来研究并处理数据。这个工具可能不够人性化,但是有以下几点好处。
我认为,从概念上来说,R 更便于使用。如果你在处理多列数据,虽然你只是在处理单个任务,但是却会看到所有的数据。而使用 R 时,数据都在内存中,只有调出数据才能看到。如果你在转换或计算,你会处理相关列或行的子集,其他所有数据都在后台。我觉得这样更便于关注手头的任务。完成任务后,可将其保存在某个数据帧中,其中只包含所需的列或行数据。你建立了正确的数据集,可解决当前的问题。这样做看似无关紧要,但实际上大受裨益。
借助 R,就可以对其他数据集轻松重复相同的操作。因为所有数据都是通过代码进行处理和研究,因此对新的数据集执行相同的操作也就轻而易举了。使用 Excel 时,大多数操作都是通过鼠标点击实现,虽然用户体验不错,但对新的数据重复操作却非常费时而枯燥。而 R 只需载入新的数据集,然后再次运行脚本即可。
实际上,用代码操作也便于诊断并共享你的分析结果。使用 Excel 时,大多数的分析结果都基于内存(数据透视表在这里,公式编辑器在另一个表格上等)。而在 R 中,通过代码执行所有操作,一目了然。如果你在修正一个错误,你很清楚在哪里操作,而如果你需要共享分析结果,只需复制粘贴代码即可。在线查找帮助时,你能准确说明所用数据,并提出具体的问题。事实上,大多数时候,你在线提问时,人们都是直接贴出准确的代码,来解决你的问题。
R 中的项目组织更简单。在 Excel 中,我要准备一系列表格,可能还要准备多个工作簿,然后适当命名,而且各文件名不得重复。我的项目备注分别保存在各个文件中。我的R语言项目组织单独设有一个文件夹,我处理过的所有内容都放在其中。清理数据、探索性图表及模型。这样便于我理解和查找,也为与我一起工作的其他人提供方便。当然,Excel 也能做到井井有条。我觉得 R 的简洁性更便于使用。
上述几点只能说是锦上添花,而并不是必不可少。在没有这些功能之前,我也用了好几年 Excel,你应该也一样。现在,我想讲讲 R 和 Excel 真正的区别。我想说的是,除了以上那些花哨的小优势之外,R 更适合用于数据分析。原因如下。
你可以把任何数据载入 R。数据的保存位置或保存形式并不重要。你可以载入 CSV 文件,也可以读取 JSON,或者执行 SQL 查询,抑或提取网站。你甚至还可以在 R 中通过 Hadoop 处理大数据。
R 是一个完整的工具集,使用的是数据包。在分析数据时,R 比 Excel 更实用。你可使用 R 执行数据管理、分类和回归,也可以处理图片,并执行其他所有操作。如果机器学习是你的专业,那能想到的任何算法都是小菜一碟。目前,R 可用的数据包逾 5,000 个,因此无论你要处理什么类型的数据,R 都能应付自如。
R 的数据可视化效果非常卓越。说句实话,Excel 的图表非常出色,简单易懂。但 R 的效果更好。我觉得这是 R 最实用的功能之一。借助 ggplot2,你可以快速创建所需的各种图表,并根据图表形状自行调整。在你熟悉了如何用 ggplot2 创建一个图表后,任何其他图表都不在话下。ggplot2 还能制作更多类型的图表。你能用 Excel 创建 散点图矩阵吗?用 R 就能轻松创建这种矩阵,CDF plot 也是如此。Excel 棋差一招。
Git 版本控制。我一向习惯保存多个版本的分析结果。Git 是至今为止我找到的最好用的工具。 用 RStudio 作为编辑器,其支持项目。创建一个项目仓库,然后你就能跟踪数据研究的不同版本。你可以创建不同版本的 Excel 文件,但是这些保存的二进制文件无法显示相互之间的更改部分。而 R 非常简单。 我已经说了很多理由。总之,Excel 是一款不错的数据分析工具。我相信它能不负众望完成所有任务。但是,如果你只有这一款工具,则会大大影响你的工作效率。相比之下,R 更好用,而且提供的工具集模块更完整。而缺点在于不是非常易于上手,用户一开始相对要花很多时间学习使用。如果坚持下去,就会有所收获,不仅对数据更了解,还提高了自己的能力。
作者:Chris Leonard
转载请注明: &
or分享 (0)在数据分析方面,比起python,excel的局限性在哪? - 知乎25被浏览3919分享邀请回答import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import time
import seaborn as sns
%matplotlib inline
df_train = pd.read_csv("E:/facebook/train.csv")
df_test = pd.read_csv("E:/facebook/test.csv")
df_train.head()
df_train_sample = df_train.sample(n=1000000)
df_test_sample = df_test.sample(n=1000000)
counts1, bins1 = np.histogram(df_train["accuracy"], bins=50)
binsc1 = bins1[:-1] + np.diff(bins1)/2.
counts2, bins2 = np.histogram(df_test["accuracy"], bins=50)
binsc2 = bins2[:-1] + np.diff(bins2)/2.
plt.figure(0, figsize=(14,4))
plt.style.use('ggplot')
plt.subplot(121)
plt.bar(binsc1, counts1/(counts1.sum()*1.0), width=np.diff(bins1)[0])
plt.grid(True)
plt.xlabel("Accuracy")
plt.ylabel("Fraction")
plt.title("Train")
plt.subplot(122)
plt.bar(binsc2, counts2/(counts2.sum()*1.0), width=np.diff(bins2)[0])
plt.grid(True)
plt.xlabel("Accuracy")
plt.ylabel("Fraction")
plt.title("Test")
plt.show()
current_palette = sns.color_palette()
counts1, bins1 = np.histogram(df_train["time"], bins=50)
binsc1 = bins1[:-1] + np.diff(bins1)/2.
counts2, bins2 = np.histogram(df_test["time"], bins=50)
binsc2 = bins2[:-1] + np.diff(bins2)/2.
plt.figure(1, figsize=(12,3))
plt.subplot(121)
plt.bar(binsc1, counts1/(counts1.sum()*1.0), width=np.diff(bins1)[0], color=current_palette[0])
plt.grid(True)
plt.xlabel("Time")
plt.ylabel("Fraction")
plt.title("Train")
plt.subplot(122)
plt.bar(binsc2, counts2/(counts2.sum()*1.0), width=np.diff(bins2)[0], color=current_palette[1])
plt.grid(True)
plt.xlabel("Time")
plt.ylabel("Fraction")
plt.title("Test")
plt.show()
plt.figure(2, figsize=(12,3))
plt.bar(binsc1, counts1/(counts1.sum()*1.0), width=np.diff(bins1)[0], color=current_palette[0], label="Train")
plt.bar(binsc2, counts2/(counts2.sum()*1.0), width=np.diff(bins2)[0], color=current_palette[1], label="Test")
plt.grid(True)
plt.xlabel("Time")
plt.ylabel("Fraction")
plt.title("Test")
plt.legend()
plt.show()
df_placecounts = df_train["place_id"].value_counts()
counts, bins = np.histogram(df_placecounts.values, bins=50)
binsc = bins[:-1] + np.diff(bins)/2.
plt.figure(3, figsize=(12,6))
plt.bar(binsc, counts/(counts.sum()*1.0), width=np.diff(bins)[0])
plt.grid(True)
plt.xlabel("Number of place occurances")
plt.ylabel("Fraction")
plt.title("Train")
plt.show()
plt.figure(4, figsize=(12,10))
plt.subplot(211)
plt.scatter(df_train_sample["time"], df_train_sample["accuracy"], s=1, c='k', lw=0, alpha=0.1)
plt.xlabel("Time")
plt.ylabel("Accuracy")
plt.xlim(df_train_sample["time"].min(), df_train_sample["time"].max())
plt.ylim(df_train_sample["accuracy"].min(), df_train_sample["accuracy"].max())
plt.title("Train")
plt.subplot(212)
plt.scatter(df_test_sample["time"], df_test_sample["accuracy"], s=1, c='k', lw=0, alpha=0.1)
plt.xlabel("Time")
plt.ylabel("Accuracy")
plt.xlim(df_test_sample["time"].min(), df_test_sample["time"].max())
plt.ylim(df_test_sample["accuracy"].min(), df_test_sample["accuracy"].max())
plt.title("Test")
plt.show()
df_train_sample["xround"] = df_train_sample["x"].round(decimals=1)
df_train_sample["yround"] = df_train_sample["y"].round(decimals=1)
df_groupxy = df_train_sample.groupby(["xround", "yround"]).agg({"accuracy":[np.mean, np.std]})
df_groupxy.head()
idx = np.asarray(list(df_groupxy.index.values))
plt.figure(5, figsize=(14,6))
plt.subplot(121)
plt.scatter(idx[:,0], idx[:,1], s=20, c=df_groupxy["accuracy", "mean"], marker='s', lw=0, cmap=plt.cm.viridis)
plt.colorbar().set_label("Mean accuracy")
plt.grid(True)
plt.xlabel("X")
plt.ylabel("Y")
plt.xlim(0,10)
plt.ylim(0,10)
plt.subplot(122)
plt.scatter(idx[:,0], idx[:,1], s=20, c=df_groupxy["accuracy", "std"], marker='s', lw=0, cmap=plt.cm.viridis)
plt.colorbar().set_label("Std accuracy")
plt.grid(True)
plt.xlabel("X")
plt.ylabel("Y")
plt.xlim(0,10)
plt.ylim(0,10)
plt.tight_layout()
plt.show()
df_topplaces = df_placecounts.iloc[0:20]
l_topplaces = list(df_topplaces.index)
print(l_topplaces)
plt.figure(6, figsize=(14,10))
for i in range(len(l_topplaces)):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
counts, bins = np.histogram(df_place["time"], bins=50, range=[df_train["time"].min(), df_train["time"].max()])
binsc = bins[:-1] + np.diff(bins)/2.
plt.subplot(5,4,i+1)
plt.bar(binsc, counts/(counts.sum()*1.0), width=np.diff(bins)[0])
plt.xlim(df_train["time"].min(), df_train["time"].max())
plt.grid(True)
plt.xlabel("Time")
plt.ylabel("Fraction")
plt.gca().get_xaxis().set_ticks([])
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
plt.figure(7, figsize=(14,10))
for i in range(len(l_topplaces)):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
# Try % 3600*24 to see daily trend assuming it's in seconds
60*24 if minutes
counts, bins = np.histogram(df_place["time"]%(60*24), bins=50)
binsc = bins[:-1] + np.diff(bins)/2.
plt.subplot(5,4,i+1)
plt.bar(binsc, counts/(counts.sum()*1.0), width=np.diff(bins)[0])
plt.grid(True)
plt.xlabel("Time")
plt.ylabel("Fraction")
plt.gca().get_xaxis().set_ticks([])
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
df_train["hour"] = (df_train["time"]%(60*24))/60.
df_train["dayofweek"] = np.ceil((df_train["time"]%(60*24*7))/(60.*24))
df_train["dayofyear"] = np.ceil((df_train["time"]%(60*24*365))/(60.*24))
df_train.head()
df_train_sample["hour"] = (df_train_sample["time"]%(60*24))/60.
df_train_sample["dayofweek"] = np.ceil((df_train_sample["time"]%(60*24*7))/(60.*24))
df_train_sample["dayofyear"] = np.ceil((df_train_sample["time"]%(60*24*365))/(60.*24))
plt.figure(8, figsize=(14,10))
for i in range(20):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
# Group by weekday
df_groupday = df_place.groupby("dayofweek").agg("count")
plt.subplot(5,4,i+1)
plt.bar(df_groupday.index.values-0.5, df_groupday["time"], width=1)
plt.grid(True)
plt.xlabel("Day")
plt.ylabel("Count")
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
plt.figure(9, figsize=(14,10))
for i in range(20):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
# Add some colums
df_place = df_place[df_place["time"]&(60*24*365)] # Restrict to 1 year so the counts don't double up
df_groupday = df_place.groupby("dayofyear").agg("count")
plt.subplot(5,4,i+1)
plt.bar(df_groupday.index.values-0.5, df_groupday["time"], width=1)
plt.grid(True)
plt.xlabel("Day of year")
plt.ylabel("Count")
plt.xlim(0,365)
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
plt.figure(10, figsize=(14,16))
cmapm = plt.cm.viridis
cmapm.set_bad("0.5",1.)
for i in range(len(l_topplaces)):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
counts, binsX, binsY = np.histogram2d(df_place["x"], df_place["y"], bins=100)
extent = [binsX.min(),binsX.max(),binsY.min(),binsY.max()]
plt.subplot(5,4,i+1)
plt.imshow(np.log10(counts.T),
interpolation='none',
origin='lower',
extent=extent,
aspect="auto",
cmap=cmapm)
plt.grid(True, c='0.6', lw=0.5)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
plt.figure(11, figsize=(14,16))
for i in range(len(l_topplaces)):
plt.subplot(5,4,i+1)
plt.gca().set_axis_bgcolor("0.5")
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
plt.scatter(df_place["x"], df_place["y"], s=10, c=df_place["accuracy"], lw=0, cmap=plt.cm.viridis)
plt.grid(True, c='0.6', lw=0.5)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
plt.figure(12, figsize=(14,16))
for i in range(len(l_topplaces)):
plt.subplot(5,4,i+1)
plt.gca().set_axis_bgcolor("0.5")
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
plt.scatter(df_place["x"], df_place["y"], s=10, c=df_place["hour"], lw=0, cmap=plt.cm.viridis)
plt.grid(True, c='0.6', lw=0.5)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.tight_layout()
plt.show()
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
xmin, xmax = df_place["x"].min(), df_place["x"].max()
ymin, ymax = df_place["y"].min(), df_place["y"].max()
df_noise = df_train[(df_train["x"]&xmin) &
(df_train["x"]&xmax) &
(df_train["y"]&ymin) &
(df_train["y"]&ymax)]
plt.figure(13, figsize=(8,4))
plt.subplot(121)
plt.gca().set_axis_bgcolor("0.5")
plt.scatter(df_noise["x"], df_noise["y"], s=10, c='k', lw=0, alpha=0.005)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
plt.grid(True, c='0.6', lw=0.5)
plt.subplot(122)
plt.gca().set_axis_bgcolor("0.5")
plt.scatter(df_noise["x"], df_noise["y"], s=10, c='k', lw=0, alpha=0.005)
plt.scatter(df_place["x"], df_place["y"], s=10, c=current_palette[5], lw=0, alpha=0.5)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
plt.grid(True, c='0.6', lw=0.5)
plt.tight_layout()
plt.show()
plt.figure(14, figsize=(12,12))
for i in range(20):
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
plt.scatter(df_place["x"], df_place["y"], s=3, alpha=0.5, c=plt.cm.viridis(int(i*(255/20.))), lw=0)
plt.grid(True)
plt.xlabel("X")
plt.ylabel("Y")
plt.tight_layout()
plt.xlim(0,10)
plt.ylim(0,10)
plt.show()
df_groupplace = df_train.groupby("place_id").agg({"time":"count", "x":"std", "y":"std"})
df_groupplace.sort_values(by="time", inplace=True, ascending=False)
df_groupplace.head()
gkde_stddevx = gaussian_kde(df_groupplace["x"][~df_groupplace["x"].isnull()].values)
gkde_stddevy = gaussian_kde(df_groupplace["y"][~df_groupplace["y"].isnull()].values)
# Compute the functions
rangeX = np.linspace(0, 3, 100)
x_density = gkde_stddevx(rangeX)
y_density = gkde_stddevy(rangeX)
plt.figure(15, figsize=(12,6))
plt.subplot(111)
plt.plot(rangeX, x_density, c=current_palette[0], ls="-", alpha=0.75)
plt.plot(rangeX, y_density, c=current_palette[1], ls="-", alpha=0.75)
plt.gca().fill_between(rangeX, 0, x_density, facecolor=current_palette[0], alpha=0.2)
plt.gca().fill_between(rangeX, 0, y_density, facecolor=current_palette[1], alpha=0.2)
plt.ylabel("Density")
plt.xlabel("Std dev")
plt.plot([], [], c=current_palette[0], alpha=0.2, linewidth=10, label="stddev x")
plt.plot([], [], c=current_palette[1], alpha=0.2, linewidth=10, label="stddev y")
plt.legend()
plt.grid(True)
plt.figure(19, figsize=(12,6))
plt.scatter(df_train_sample["hour"], df_train_sample["accuracy"], s=1, c='k', lw=0, alpha=0.05)
plt.xlabel("Hour")
plt.ylabel("Accuracy")
plt.xlim(df_train_sample["hour"].min(), df_train_sample["hour"].max())
plt.ylim(df_train_sample["accuracy"].min(), df_train_sample["accuracy"].max())
plt.title("Train")
plt.show()
place = l_topplaces[i]
df_place = df_train[df_train["place_id"]==place]
xmin, xmax = df_place["x"].min(), df_place["x"].max()
ymin, ymax = df_place["y"].min(), df_place["y"].max()
# Calculate the KDE
res = 200 # resolution
gkde_place = gaussian_kde(np.asarray((df_place["x"], df_place["y"])))
x_flat = np.linspace(xmin, xmax, res)
y_flat = np.linspace(ymin, ymax, res)
x, y = np.meshgrid(x_flat,y_flat)
grid_coords = np.append(x.reshape(-1,1),y.reshape(-1,1),axis=1)
z = gkde_place(grid_coords.T)
z = z.reshape(res,res)
extent = [xmin,xmax,ymin,ymax]
plt.figure(20, figsize=(12,6))
# KDE only
plt.subplot(121)
plt.imshow(z[::-1,:],
extent=extent,
aspect="auto",
cmap=plt.cm.viridis,
interpolation="bilinear")
plt.grid(False)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
# Overplot the points
plt.subplot(122)
plt.imshow(z[::-1,:],
extent=extent,
aspect="auto",
cmap=plt.cm.viridis,
interpolation="bilinear")
plt.colorbar().set_label("density")
plt.scatter(df_place["x"], df_place["y"], s=10, c='k', lw=0, alpha=0.5)
plt.grid(False)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
plt.tight_layout()
plt.show()
pids = [0,8,9,10,11,14] # A few places
plt.figure(21, figsize=(14,5))
for i in range(len(pids)):
place = l_topplaces[pids[i]]
df_place = df_train[df_train["place_id"]==place]
xmin, xmax = df_place["x"].min(), df_place["x"].max()
ymin, ymax = df_place["y"].min(), df_place["y"].max()
# Calculate the KDE
res = 50 # resolution
gkde_place = gaussian_kde(np.asarray((df_place["x"], df_place["y"])))
kdes.append(gkde_place) # Keep these KDEs for later
x_flat = np.linspace(xmin, xmax, res)
y_flat = np.linspace(ymin, ymax, res)
x, y = np.meshgrid(x_flat,y_flat)
grid_coords = np.append(x.reshape(-1,1),y.reshape(-1,1),axis=1)
z = gkde_place(grid_coords.T)
z = z.reshape(res,res)
extent = [xmin,xmax,ymin,ymax]
# KDE only
plt.subplot(2,6,i+1)
plt.imshow(z[::-1,:],
extent=extent,
aspect="auto",
cmap=plt.cm.viridis,
interpolation="bilinear")
plt.grid(False)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
# Overplot the points
plt.subplot(2,6,i+7)
plt.imshow(z[::-1,:],
extent=extent,
aspect="auto",
cmap=plt.cm.viridis,
interpolation="bilinear")
plt.scatter(df_place["x"], df_place["y"], s=5, c='k', lw=0, alpha=0.5)
plt.grid(False)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("pid: " + str(place))
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
plt.tight_layout()
plt.show()
终于写完了,呼!如果知乎上不好看的话,代码已上传到github,不过由于github中打开.ipynb文件特别慢所以我通过jupyter nbviewer来展示这样会更快一点终于写完了,呼!如果知乎上不好看的话,代码已上传到github,不过由于github中打开.ipynb文件特别慢所以我通过jupyter nbviewer来展示这样会更快一点还有我的excel2016版的最多也就只能加载100多万行记录,而pandas则可以较为容易的处理5T以下的数据。162 条评论分享收藏感谢收起12 条评论分享收藏感谢收起本文利用Python3爬虫抓取豆瓣图书Top250,并利用xlwt模块将其存储至excel文件,图片下载到相应目录。旨在进行更多的爬虫实践练习以及模块学习。
1.Python 3.5
2.BeautifulSoup、xlwt模块
首先查看目标网页的url:&/top250?start=0, 然后我尝试了在代码里直接通过字符串连接仅改变&start=&后面的数字的方法来遍历所有的250/25 = 10页内容,但是后来发现不行,那样的话出来的永远是第一页,于是通过浏览器的F12开发者工具检查,发现start是要post上去的,如下图:
所以建立一个postData的dict:
postData = {"start": i}
#i为0,25,...225
每次将其post上去即可解决返回都是第一页的问题。
分析网页可知,一本书的罗列信息以及要爬取的点如下图:
从上到下需要爬取的信息有:
1.图书链接地址
2.封面图片链接 & &我到时候会将此链接打开,下载图片到本地 (download_img函数)
3.书名 & &要注意的是这里书名取title的内容而不去a标签中的string信息,因为string信息可能包含诸如空格、换行符之类的字符,给处理造成麻烦,直接取title格式正确且无需额外处理。
4.别名 & &这里主要是副标题或者是外文名,有的书没有这项,那么我们就写入一个&无&,千万不可以写入一个空串,否则的话会出现故障,我下面会提到。
5.出版信息 &如作者、译者、出版社、出版年份、价格, 这也是重要信息之一,否则有多本书名字一致可能会无法分辨
7.评价人数
除此之外,我还爬取一个&标签&信息,它在图书链接打开之后的网页中,找到它的位置如下:
爬到标签以后将它们用逗号连接起来作为标签值。
好了,既然明确了要爬的指标,以及了解了网页结构以及指标所在的html中的位置,那么就可以写出如下代码:
geturl = url + "/start=" + str(i)
#要获取的页面地址
print("Now to get " + geturl)
postData = {"start":i}
res = s.post(url,data = postData,headers = header)
soup = BeautifulSoup(res.content,"html.parser")
#BeautifulSoup解析
table = soup.findAll('table',{"width":"100%"})
#找到所有图书信息的table
sz = len(table)
#sz = 25,每页列出25篇文章
for j in range(1,sz+1):
sp = BeautifulSoup(str(table[j-1]),"html.parser") #解析每本图书的信息
#print(sp.div)
imageurl = sp.img['src']
#找图片链接
bookurl = sp.a['href']
#找图书链接
bookName = sp.div.a['title']
nickname = sp.div.span
if(nickname):
#如果有别名则存储别名否则存&无&
nickname = nickname.string.strip()
nickname = "None"
#print(type(imageurl),imageurl)
#print(type(bookurl),bookurl)
#print(type(bookName),bookName)
#print(type(nickname),nickname)
notion = str(sp.find('p',{"class":"pl"}).string)
#抓取出版信息,注意里面的.string还不是真的str类型
#print(type(notion),notion)
rating = str(sp.find('span',{"class":"rating_nums"}).string)
#抓取平分数据
nums = sp.find('span',{"class":"pl"}).string
#抓取评分人数
nums = nums.replace('(','').replace(')','').replace('\n','').strip()
nums = re.findall('(\d+)人评价',nums)[0]
#print(type(rating),rating)
#print(type(nums),nums)
download_img(imageurl,bookName)
book = requests.get(bookurl)
#打开该图书的网页
sp3 = BeautifulSoup(book.content,"html.parser")
taglist = sp3.find_all('a',{"class":"
#找标签信息
for tagurl in taglist:
sp4 = BeautifulSoup(str(tagurl),"html.parser")
#解析每个标签
lis.append(str(sp4.a.string))
tag = ','.join(lis)
if tag == "":
#如果标签为空,置"无"
tag = "None"
通过xlwt模块存入xls文件及其问题
爬取下来了以后当然要考虑存储,这时我想试试把它存到Excel文件(.xls)中,于是搜得python操作excel可以使用xlwt,xlrd模块,虽然他们暂时只支持到excel2003,但是足够了。xlwt为Python生成.xls文件的模块,而xlrd为读取的。由于我想的是直接生成xls文件,不需用到xlrd,所以先安装xlwt。
直接进入Python目录使用如下命令即可安装xlwt:
pip3 install xlwt
安装完后写出操作代码,这里同时也写入txt文件,方便比较:
#建立Excel
workbook = xlwt.Workbook(encoding='utf-8')
sheet = workbook.add_sheet('book_top250',cell_overwrite_ok=True)
item = ['书名','别称','评分','评价人数','封面','图书链接','出版信息','标签']
for i in range(1,9):
sheet.write(0,i,item[i-1])
for j in range(1,sz+1):
writelist = [i+j,bookName,nickname,float(rating),int(nums),"I:\\douban\\image\\"+bookName+".jpg",bookurl,notion,tag]
for k in range(0,9):
sheet.write(i+j,k,writelist[k])
txtfile.write(str(writelist[k]))
txtfile.write('\t')
txtfile.write(u'\r\n')
workbook.save("I:\\douban\\booktop250.xls")...
满以为这样就可以了,但是还是出现了一些错误。
比如曾经出现了写着写着就写不下去了的情况(以下并非以上代码产生的结果):
这时我把不是str的都改成str了,不该str的尽量用数字(int,float),然后又遇到了下面的情况:
写到第64项又写不下去了,但是那些int,float都写完了,&无&也是断断续续显示几个,我想,既然找不到问题,那么慢慢套吧。首先极大可能是中文编码的问题,因为我把一些可以不为str类型的都赋成非str类型以后都正确地显示了,而且上图中的显示在图片路径名那里断了,所以我让那一列都不显示,居然,成功了!
如图,除了不显示的那一列,其它完全正常,可以断定就是下面这里出现的错误:
writelist=[i+j,bookName,nickname,float(rating),int(nums),"I:\\douban\\image\\"+bookName+".jpg",bookurl,notion,tag]
我的图片路径那里是直接字符串拼接而成的,所以可能会有编码的错误。那么稍微改一下试试:
imgpath = str("I:\\douban\\image\\"+bookName+".jpg");
writelist=[i+j,bookName,nickname,float(rating),int(nums),imgpath,bookurl,notion,tag]
好吧,还是不行,还是出现图5的问题,但是打印在Python IDLE里面又都是正确的。
既然如此,把图片链接全部改成一样的英文试一下:
imgpath = str("I:\\douban\\image\\"+"a"+".jpg")
writelist=[i+j,bookName,nickname,float(rating),int(nums),imgpath,bookurl,notion,tag]
&又是正确的:('无'已改为'None')
所以说,还是图片路径的问题,那我们索性将图片路径那列换成图片链接,采取消极应对方法,反正这项是图片链接还是图片路径无关紧要,反正图片路径里面有图片就可以了。此外我还加了一个计时的代码,计算总爬取时间,因为我觉得这样干爬太慢了,没有个将近10分钟完不成,考虑利用多线程去爬,这里先记录一下时间以观后效。然后发现还是不行!现在成了只要imageurl固定(中文也行),就能够顺利输出到xls中,否则就不行。很诡异。于是我又尝试了缩短imageurl,实验得知,当取imageurl[:-6]时是可以的,但imageurl[:-5]就不行了。后面又干脆不写入imageurl这一列,可以,不写入别名或者不写入图书链接都是正常的,但是不写入标号就不行。至今仍不得解。初步猜测莫非是写入的字符数受限制了?还得靠更多的实验才能确定。而且也说不定就是Windows下的编码问题,这又得靠在Linux下进行实验判断。所以要做的事情还很多,这里先把正确的绝大部分工作做了再说。
于是干脆不要图书地址一列,最后得出如下最终代码:
# -*- coding:utf-8 -*-
import requests
import xlwt
from bs4 import BeautifulSoup
from datetime import datetime
import codecs
now = datetime.now()
print(now)
txtfile = codecs.open("top250.txt",'w','utf-8')
url = "/top250?"
header = { "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.13 Safari/537.36",
"Referer": "/"
image_dir = "I:\\douban\\image\\"
def download_img(imageurl,imageName = "xxx.jpg"):
rsp = requests.get(imageurl, stream=True)
image = rsp.content
path = image_dir + imageName +'.jpg'
#print(path)
with open(path,'wb') as file:
file.write(image)
#建立Excel
workbook = xlwt.Workbook(encoding='utf-8')
sheet = workbook.add_sheet('book_top250',cell_overwrite_ok=True)
item = ['书名','别称','评分','评价人数','封面','图书链接','出版信息','标签']
for i in range(1,9):
sheet.write(0,i,item[i-1])
s = requests.Session()
s.get(url,headers=header)
for i in range(0,250,25):
geturl = url + "/start=" + str(i)
#要获取的页面地址
print("Now to get " + geturl)
postData = {"start":i}
res = s.post(url,data = postData,headers = header)
soup = BeautifulSoup(res.content.decode(),"html.parser")
#BeautifulSoup解析
table = soup.findAll('table',{"width":"100%"})
#找到所有图书信息的table
sz = len(table)
#sz = 25,每页列出25篇文章
for j in range(1,sz+1):
sp = BeautifulSoup(str(table[j-1]),"html.parser") #解析每本图书的信息
#print(sp.div)
imageurl = sp.img['src']
#找图片链接
bookurl = sp.a['href']
#找图书链接
bookName = sp.div.a['title']
nickname = sp.div.span
if(nickname):
#如果有别名则存储别名否则存&无&
nickname = nickname.string.strip()
nickname = "None"
#print(type(imageurl),imageurl)
#print(type(bookurl),bookurl)
#print(type(bookName),bookName)
#print(type(nickname),nickname)
notion = str(sp.find('p',{"class":"pl"}).string)
#抓取出版信息,注意里面的.string还不是真的str类型
#print(type(notion),notion)
rating = str(sp.find('span',{"class":"rating_nums"}).string)
#抓取平分数据
nums = sp.find('span',{"class":"pl"}).string
#抓取评分人数
nums = nums.replace('(','').replace(')','').replace('\n','').strip()
nums = re.findall('(\d+)人评价',nums)[0]
#print(type(rating),rating)
#print(type(nums),nums)
download_img(imageurl,bookName)
book = requests.get(bookurl)
#打开该图书的网页
sp3 = BeautifulSoup(book.content,"html.parser")
taglist = sp3.find_all('a',{"class":"
#找标签信息
for tagurl in taglist:
sp4 = BeautifulSoup(str(tagurl),"html.parser")
#解析每个标签
lis.append(str(sp4.a.string))
tag = ','.join(lis)
if tag == "":
#如果标签为空,置"无"
tag = "None"
writelist=[i+j,bookName,nickname,float(rating),int(nums),imageurl,bookurl,notion,tag]
for k in range(0,9):
if(k == 5):
sheet.write(i+j,k,writelist[k])
txtfile.write(str(writelist[k]))
txtfile.write('\t')
txtfile.write(u'\r\n')
workbook.save("I:\\douban\\booktop250.xls")
end = datetime.now()
print(end)
print("程序耗时: " + str(end-now))
txtfile.close()
运行(7分多钟):
还是断了,那就真不知道怎么办才好了。再改变方法,先写到TXT文本文件再导入到xls中,就先不管本文标题了。
21:47:17.914149
Now to get /top250?/start=0
Now to get /top250?/start=25
Now to get /top250?/start=50
Now to get /top250?/start=75
Now to get /top250?/start=100
Now to get /top250?/start=125
Now to get /top250?/start=150
Now to get /top250?/start=175
Now to get /top250?/start=200
Now to get /top250?/start=225
21:56:16.046792
程序耗时: 0:08:58.132643
在.txt中是正确的:
然后在xls文件中选择数据-&导入数据即可得到最终结果:
封面图片:
问题先解决到这,后面的问题有待深入研究。
后期可改进
1.采用多进程/多线程加快爬取速度
2.可考虑采用xlutis模块分多步写入到excel中
3.可考虑改换excel处理模块
3.考虑在Linux环境下进行试验
------------------------------------------------------------------------------------------------------
听人说数据分析绝大部分时间都花在数据采集与清洗,以前不怎么觉得,现在终于有一点感受了,任重道远啊..
如果您对我的方法有什么看法,欢迎留下您的评论:-)
阅读(...) 评论()}

我要回帖

更多关于 python数据分析 pdf 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信