这些见解将包括但不限于以下内容!
- 最有贡献的作者
- 参与者的时间表(如何开始!)
- 比较投票与已发表文章的数量
要了解页面结构, 需要使用Chrome浏览器开发人员工具。这样做是为了识别将搜索以获得所需信息的类。
该页面将收集以下信息:
- 作者
- 发布日期
- 标题
- 描述
- 投票增加
我们将从导入必要的库开始, 如下所示:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import re
import time
from datetime import datetime
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
from urllib.request import urlopen
from bs4 import BeautifulSoup
确定要剪贴的页面
我们将循环并抓取的示例URL是以下https://www.srcmini.com?page=2。如我们所见, page = 2参数对于每个页面都会更改。为了遍历所有页面以获得必要的数据集, 我们需要找出页面数。
下面的代码行就是这样做的。
url = "https://www.srcmini.com"
html = urlopen(url)
soup = BeautifulSoup(html, 'html')pages = [i.text for i in soup.find_all('a') if 'community/tutorials?page=' in str(i)]
lastpage = pages[-1]
print(lastpage)
12
插图如下:
- 将网址指定为变量
- 使用先前导入的urlopen打开url
- 刮取指定的页面并将其分配给汤变量
- 使用列表推导识别页面上的所有超链接, 并针对其中包含社区/教程的用户进行过滤?
- 最后找到的网址的文本值是需要抓取的最后一页
description=[]
upvote=[]
author=[]
publishdate=[]
title=[]
进行实际刮擦
现在我们知道需要抓取多少页面并声明了变量, 现在我们将使用for循环并逐页浏览每个页面, 以获取感兴趣的字段, 如下所示。请注意, 我们最终将获得感兴趣的每一列的列表列表, 但是稍后我们将进一步展平该列表, 以便将其用于数据帧。
for cp in np.arange(1, int(lastpage)+1):
url = "https://www.srcmini.com?page=" + str(cp)
html = urlopen(url)
soup = BeautifulSoup(html, 'html')
description.append([i.text for i in soup.find_all(class_='jsx-379356511 blocText description')])
upvote.append([i.text for i in soup.find_all(class_='jsx-4192737526 voted')])
author.append([i.text for i in soup.find_all(class_='jsx-566588255 name')])
publishdate.append([i.text for i in soup.find_all(class_='jsx-566588255 date')])
title.append([i.text for i in soup.find_all(class_='jsx-379356511 blue')])
time.sleep(3)
print ("Done!")
Done!
这是上面的代码段中发生的事情
- 将网址设置为变量
- 使用先前导入的urlopen打开url
- 刮取指定的页面并将其分配给汤变量
- 通过使用相关的类名来标识和提取描述, 投票, 作者, 发布日期, 标题的值。这些类名称是使用开发人员工具找到的
- 这次, 时间功能已经很容易在网站上使用了:)
由于我们得到的值是列表列表, 因此现在将使用以下代码段对其进行展平:
descriptionflat = [y for x in description for y in x]
upvoteflat = [y for x in upvote for y in x]
authorflat = [y for x in author for y in x]
publishdateflat = [y for x in publishdate for y in x]
titleflat = [y for x in title for y in x]
publishdateformatted = [datetime.strptime(re.sub('rd, ', ', ', re.sub('st, ', ', ', re.sub('nd, ', ', ', re.sub('th, ', ', ', a)))), "%B %d, %Y") for a in publishdateflat]
上面单元格中的最后一条语句将日期值(当前为字符串格式)转换为DateTime。
制作数据框并另存为CSV文件
现在, 列表将被分组为字典, 并且将创建一个数据框以进行进一步分析。最后一条命令将数据框保存到CSV文件中, 以便以后使用。
cdata = http://www.srcmini.com/{"author":authorflat, "publishdate":publishdateformatted, "title":titleflat, "description":descriptionflat, "upvote":upvoteflat}
df = pd.DataFrame(data = http://www.srcmini.com/cdata)
df.to_csv("c:\\users\\ssalahuddin\\documents\\srcmini130818.csv", header=True, index=False)
读取CSV文件
现在, 我们尝试从刚刚创建的CSV文件中读取收集的数据集。
srcmini = pd.read_csv("c:\\users\\ssalahuddin\\documents\\srcmini130818.csv", parse_dates=["publishdate"], infer_datetime_format=True)
srcmini.shape
(176, 5)
上面的命令告诉我们, 我们正在处理一个176行5列的数据集。
srcmini.head()
作者 | 描述 | 发布日期 | 标题 | 赞成 | 出版ymm | |
---|---|---|---|---|---|---|
0 | 罗希特·皮萨(Rohit Peesa) | 本教程将演示你如何… | 2018-08-13 | 图像数据集 | 3 | 2018年8月 |
1 | 卢克·海登(Luke Hayden) | 在本教程中, 你将学习如何使用PCA … | 2018-08-09 | R中的主成分分析 | 14 | 2018年8月 |
2 | 塞贾尔·杰伊斯瓦尔 | 在本教程中, 你将专门学习… | 2018-08-08 | Python IF, ELIF和ELSE语句 | 3 | 2018年8月 |
3 | 阳武 | 了解如何执行探索性数据分析… | 2018-08-07 | 在Python中生成WordCloud | 14 | 2018年8月 |
4 | 基思·辛格尔顿 | 在本教程中, 你将学习如何拉数据。 | 2018-08-07 | MeetUp API –提取数据并将其写入JSON | 4 | 2018年8月 |
srcmini['publishyymm'] = srcmini['publishdate'].dt.strftime("%Y-%b")
srcmini["posts"] = 1
- 上面的代码部分的第一行将创建一个新列, 其发布日期的格式设置为Year-Month格式。
- 第二行将值1分配给以后使用的新列。
在这里, 我们将按年和月的时间表组织教程的数量:
srcmini.groupby([srcmini['publishdate'].dt.year, srcmini['publishdate'].dt.month]).size().plot(kind='bar', figsize=(15, 7), color='b')
<
matplotlib.axes._subplots.AxesSubplot at 0x1bd55d2cb70>
文章图片
自2017年1月
由于从2013年到2016年的持续时间所代表的职位很少, 因此我们从现在开始将其忽略, 并考虑从2017年1月开始的职位。将对此进行过滤, 如下所示
srcmini[srcmini["publishdate"]>
='2017-01-01'].sort_values(by="publishdate", ascending=True).groupby([srcmini['publishyymm']], sort=False).size().plot(kind='bar', figsize=(15, 7), color='b')
<
matplotlib.axes._subplots.AxesSubplot at 0x1bd55ca57f0>
文章图片
教程在2018年加快了步伐, 尤其是从3月开始以持续的步伐增长。由于此数据是在8月中旬提取的, 几乎超过了7月份的教程数量的中间值, 因此, 今年8月可能是今年迄今为止帖子数量最多的月份!
最佳作者图
当我们加快所有这些教程的进度时, 谁一直在为这些教程做出贡献?在这里, 我们用一个简单的条形图突出显示了这一事实。
srcmini[srcmini["publishdate"]>
='2017-01-01']["author"].value_counts(sort=True, ascending=False)[:10].plot(kind='bar')
<
matplotlib.axes._subplots.AxesSubplot at 0x1bd57ca4ba8>
文章图片
最佳作者列表
让我们同时建立一个清单。我们将在下面尽快使用它:
topauthors = srcmini[srcmini["publishdate"]>
='2017-01-01']["author"].value_counts(sort=True, ascending=False)[:10].index
这就是上面的代码部分中发生的事情。
- 自2017年1月起, 教程的结果有限
- 仅选择作者字段
- 使用value_counts函数汇总结果
- 将结果集按降序排序, 并将其限制在前10行
现在, 我们要重点关注的是因为这些十大贡献者何时以及以何种速度发布了教程。为此, 我们将使用刚创建的列表以及一些转换来得出所需的堆叠条形图。
dh = srcmini[srcmini["publishdate"]>
='2017-01-01'].sort_values(by="publishdate", ascending=True).set_index(["publishdate"])
dh["publishdateone"] = pd.to_datetime(dh.publishdate.astype(str).str[0:7]+'-01')
这就是上面的代码部分中发生的事情。
- 自2017年1月起, 教程的结果有限
- 按发布日期排序
- 将发布日期作为索引列
dhp = dh[dh["author"].isin(topauthors)].pivot_table(index="publishdateone", values="posts", columns="author", aggfunc=np.sum)
fig, ax = plt.subplots(figsize=(15, 7))
dhp.plot(ax=ax, kind='bar', stacked=True)
ticklabels = [item.strftime('%Y %b') for item in dhp.index]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
文章图片
这是我们可能从上述图表中获得的内容, 同时考虑了作者对教程数的早期可视化。
- 而Karlijn Willems一直是Tutorials榜首。她也是第一个将这一切开始的人!
- Sejal Jaiswal虽然排名第三, 但起步很快, 平均每月有1个职位。
- 如果在接下来的时间保持相同的速度, 阿迪蒂亚·夏尔马可能正在穿越塞贾尔。
当读者喜欢本教程时, 将分别发出赞成信号。
让我们看看谁成功获得了很多赞誉, 以及他们发布的教程数量!在这种情况下, 我们还将考虑排名前十的贡献者。这将通过使用散点图来完成。
upvotes = dh[dh["author"].isin(topauthors)].groupby(['author'], as_index=False).agg({'posts':"sum", 'upvote': "sum"})
sns.lmplot('posts', 'upvote', data=http://www.srcmini.com/upvotes, fit_reg=False, hue="author", scatter_kws={"marker": "D", "s": 100})
<
seaborn.axisgrid.FacetGrid at 0x1bd57cd69e8>
文章图片
尽管Karlijn Willems的发表数量几乎翻了一番, 但投票数量却高得令人难以置信!大约是雨果的支持数的3倍。 Sejal已成功排在第三, 而其他人则有足够的步伐可以跟上步伐。
总结
在本教程中, 我们设法实现了以下目标
- Scrape教程在所有页面中列出
- 创建一个数据框并将其另存为CSV, 以供以后参考和分析
- 使用Pandas和Matplotlib以及一些转换对其进行了探索
- 使用线, 条形图, 堆积条形图和散点图进行可视化
【使用Python BeautifulSoup抓取srcmini教程并进行分析】如果你想了解有关Python的更多信息, 请参加srcmini的” 使用Python进行数据可视化入门” 课程和” 在Python中导入数据” (第2部分)课程, 以了解BeautifulSoup。
推荐阅读
- Python客户细分简介
- Python中的文档字符串
- 在Pandas中加入DataFrames
- R Rstudio使用debugr进行调试
- 自动化机器学习(Python的TPOT库)
- 用Python揭开关键统计的神秘面纱
- R中的for循环用法
- 在R中创建列表
- 关于扑克牌的一些讨论——《Fluent Python 2》读书笔记