萌新小编用Python做网页爬虫!这个一看就像个老司机做的!

萌新小编用Python做网页爬虫!这个一看就像个老司机做的!,第1张

概述在本教程中,您将学习如何从web提取数据、使用Python的Pandas库 *** 作和清理数据,以及使用Python的Matplotlib库来实现数据可视化。

在本教程中,您将学习如何从web提取数据、使用Python的Pandas库 *** 作和清理数据,以及使用Python的Matplotlib库来实现数据可视化。

Web抓取是一个用来描述使用程序或算法从Web中提取和处理大量数据的术语。无论您是数据科学家、工程师还是分析大数据集的人,从web上获取数据的能力都是一项有用的技能。假设您从web中找到数据,并且没有直接的方法来下载它,使用Python进行web抓取是一种技巧,您可以使用它将数据提取到并导入到有用的表单中。

加\/X:mmp9972    即可获取数十套pdf哦!

在本教程中,您将了解以下内容:

使用Python Beautiful Soup模块从web中提取数据 使用Python的panda库进行数据 *** 作和清理 使用Python的Matplotlib库进行数据可视化

本教程中使用的数据集取自于发生在希尔斯伯勒2017年6月的10公里比赛。你将分析跑者的表现,并回答以下问题:

跑步者的平均完成时间是多少? 跑者的完成时间是否服从正态分布? 不同年龄段的男性和女性在表现上有什么不同吗?

使用Beautiful Soup进行网页抓取

在使用Jupyter Notebook 之前,你需要导入以下模块:

pandas,numpy,matplotlib.pyplot,seaborn。如果您还没有安装Jupyter笔记本,我建议您下载安装Anaconda Python发行版,因为这个确实太好用了,而且自带了很多模块。为了方便在程序中显示图表,请确保按如下所示的方式包含%mattplotlib 。

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns%matplotlib inline

要执行web抓取,还应该导入如下所示的库:urllib.request 模块用于打开url。这个Beautiful Soup用于从HTML文件中提取数据。模块中 Beautiful Soup 的别名(缩写)是 bs4,4 是第四个版本。

from urllib.request import urlopenfrom bs4 import BeautifulSoup
导入必要的模块后,指定包含数据集的URL, 并将其传递给 urlopen(), 得到返回的HTML。
url = "http://www.hubertiming.com/results/2017GPTR10K"HTML = urlopen(url)

获取页面HTML后,下一步就是从HTML 创建一个Beautiful Soup 对象,这很简单,将HTML 传给构造函数就行。 Beautiful Soup 的方法会解析HTML,分解为python 对象。第二个参数“lxml” 是HTML的解析器。只管用吧。

soup = BeautifulSoup(HTML,'lxml') type(soup)bs4.BeautifulSoup

soup对象允许您提取关于您正在抓取的网站的有趣信息,例如获得如下所示的页面标题。

# Get the TitleTitle = soup.Title print(Title)2017 Intel Great Place to Run 10K  Urban Clash Games Race Results

你也可以得到网页的文本,打印出来瞧瞧,检查它是否是你所期望的。

# Print texttext = soup.get_text()# Print (soup.text))

你可以在网页的任何地方右键单击并选择“查看源代码”来查看网页的HTML和我们输入的进行对比。

您可以使用soup的find_all()方法在网页中提取有用的HTML标记。有用标记的例子包括< a >用于超链接,

用于表行,< tr >用于表标题,< th >用于表单元格,< td >用于表单元格。下面的代码展示了如何提取网页中的所有超链接。

soup.find_all('a')[,,@L_502_1@,,,,,,]

从上面的输出例子可以看到,HTML标记有时带有class、src等属性。这些属性提供了关于HTML元素的附加信息。可以使用for循环和get('"href")方法只提取和打印超链接。

all_links = soup.find_all("a")for link in all_links: print(link.get("href"))/results/2017GPTRhttp://hubertiming.com/#indivIDual#teammailto:[email protected]#tabs-1NoneNonehttp://www.hubertiming.com/http://facebook.com/hubertiming/

如果仅打印表行,请在soup.find_all()中传递'tr'参数。

# Print the first 10 rows for sanity checkrows = soup.find_all('tr')print(rows[:10])[Place

本教程的目标是从网页中取出一张表格,并将其转换为dataframe,以便更容易地使用Python进行 *** 作。要做到这一点,您应该首先获得List表单中的所有表行,然后将该列表转换为dataframe。下面是一个for循环,它遍历表行并输出行单元格。

for row in rows: row_td = row.find_all('td')print(row_td)type(row_td)[

上面的输出显示每一行都是用嵌入在每一行中的HTML标记打印出来的。这不是我们想要的。可以使用Beautiful Soup或正则表达式删除HTML标记。

str_cells = str(row_td)cleantext = BeautifulSoup(str_cells,"lxml").get_text()print(cleantext)[14TH,INTEL TEAM M,04:43:23,00:58:59 - DANIELLE CASILLAS,01:02:06 - RAMYA MERUVA,01:17:06 - PALLAVI J SHINDE,01:25:11 - NAliNI MURARI]:正则表达式才是高手风范)。 

我们导入re(用于正则表达式)模块,下面的代码展示了如何构建一个正则表达式,该表达式查找< td > HTML标记中的所有字符,并为每个表行替换为空字符串。

首先,通过传递与re.compile()匹配的字符串来编译正则表达式。点、星号和问号(.*?) 将匹配一个开头的尖括号,后面跟着任何东西,后面跟着一个结尾的尖括号。它以非贪婪的方式匹配文本,也就是说,它匹配尽可能短的字符串。

如果省略问号,它将匹配第一个开始尖括号和最后一个结束尖括号之间的所有文本。

编译正则表达式后,可以使用re.sub()方法查找正则表达式匹配的所有子字符串,并用空字符串替换它们。

下面的完整代码生成一个空列表,提取每一行HTML标记之间的文本,并将其附加到指定的列表中。

import re List_rows = [] for row in rows:  cells = row.find_all('td')  str_cells = str(cells)  clean = re.compile('<.*?>')  clean2 = (re.sub(clean,'',str_cells))  List_rows.append(clean2)  print(clean2)  type(clean2)[14TH,01:25:11 - NAliNI MURARI]str

下一步是将列表转换为dataframe并使用panda快速查看前10行。

df = pd.DataFrame(List_rows) df.head(10)00   [Finishers:,577]1   [Male:,414]2   [Female:,163]3   []4   [1,814,JARED WILSON,M,TIGARD,OR,00:36:21...5   [2,573,NATHAN A SUSTERSIC,PORTLAND,...6   [3,687,FRANCISCO MAYA,00:3...7   [4,623,PAul MORROW,BEAVERTON,00:38:...8   [5,569,DEREK G OSBORNE,HILLSBORO,00...9   [6,642,JONATHON TRAN,00:39...

数据处理和清理

dataframe不是我们想要的格式。为了清理它,您应该在逗号位置将“0”列分割为多个列,通常我们使用str.split()方法实现的。

df1 = df[0].str.split(',',expand=True) df1.head(10)

这看起来清爽多了,但还有工作要做。dataframe的每行周围都有不需要的方括号。可以使用strip()方法删除列“0”上的左方括号。

df1[0] = df1[0].str.strip('[') df1.head(10)

上表缺少表标头。您可以使用find_all()方法获得表标头。

col_labels = soup.find_all('th')

与处理表类似,您可以使用Beautiful Soup提取表标题的HTML标记之间的文本。

all_header = []col_str = str(col_labels)cleantext2 = BeautifulSoup(col_str,"lxml").get_text()all_header.append(cleantext2)print(all_header)['[Place,Bib,name,Gender,City,State,Chip Time,Chip Pace,Gender Place,Age Group,Age Group Place,Time to Start,Gun Time,Team]']

然后,您可以将标题列表转换为pandas dataframe。

df2 = pd.DataFrame(all_header) df2.head()00   [Place,Chip T...

类似地,您可以在所有行的逗号位置将“0”列分割为多个列。

df3 = df2[0].str.split(',expand=True)df3.head()

frames = [df3,df1] df4 = pd.concat(frames) df4.head(10)

下面显示了如何将第一行分配为表标头。

df5 = df4.rename(columns=df4.iloc[0]) df5.head()

至此,这个表的格式几乎完全正确。对于分析,您可以从以下数据的概述开始。

df5.info()df5.shapeInt64Index: 597 entrIEs,0 to 595Data columns (total 14 columns):[Place 597 non-null objectBib 596 non-null objectname 593 non-null objectGender 593 non-null objectCity 593 non-null objectState 593 non-null objectChip Time 593 non-null objectChip Pace 578 non-null objectGender Place 578 non-null objectAge Group 578 non-null objectAge Group Place 578 non-null objectTime to Start 578 non-null objectGun Time 578 non-null objectTeam] 578 non-null objectdtypes: object(14)memory usage: 70.0+ KB(597,14)

该表有597行和14列。您可以删除所有缺少值的行。

df6 = df5.dropna(axis=0,how='any')

另外,请注意如何将表头复制为df5中的第一行。 可以使用以下代码行删除它。

df7 = df6.drop(df6.index[0]) df7.head()

您可以通过重新命名'[Place' and ' Team]'列来执行更多的数据清理。Python对空格非常挑剔。确保在“Team]”中在引号之后加上空格。

df7.rename(columns={'[Place': 'Place'},inplace=True) df7.rename(columns={' Team]': 'Team'},inplace=True) df7.head()

最后的数据清理步骤包括删除“Team”列中的单元格的右括号。

df7['Team'] = df7['Team'].str.strip(']') df7.head()

到这里为止我们花了一段很长时间,也得到了我们想要的dataframe。现在您可以进入令人兴奋的部分,开始绘制数据并计算有趣的统计数据。

数据分析和可视化

首先要回答的问题是,跑步者的平均完成时间(以分钟为单位)是多少?您需要将列“Chip Time”转换为几分钟形式。一种方法是首先将列转换为列表进行 *** 作。

time_List = df7[' Chip Time'].toList()# You can use a for loop to convert 'Chip Time' to minutestime_mins = []for i in time_List: h,m,s = i.split(':') math = (int(h) * 3600 + int(m) * 60 + int(s))/60 time_mins.append(math)#print(time_mins)

下一步是将列表转换回dataframe,并立即为跑步者 Chip Time 创建一个新的列(“Runner_mins”)。

df7['Runner_mins'] = time_mins df7.head()

下面的代码显示了,在dataframe中计算数字列的统计信息。

df7.describe(include=[np.number])Runner_minscount   577.000000mean    60.035933std 11.970623min 36.35000025% 51.00000050% 59.01666775% 67.266667max 101.300000

有趣的是,所有跑步者的平均chip time 是大约60分钟。最快的10K跑者跑完36.35分钟,最慢的跑者跑完101.30分钟。

Boxplot是另一个有用的工具,用于可视化汇总统计信息(最大值、最小值、中等值、第一四分位数、第三四分位数,包括异常值)。下面是在箱线图中显示的跑步者的数据汇总统计数据。为了实现数据可视化,可以方便地首先从matplotlib附带的pylab模块导入参数,并为所有图形设置相同的大小,以避免为每个图形设置相同的大小。

from pylab import rcParams rcParams['figure.figsize'] = 15,5df7.Boxplot(column='Runner_mins') plt.grID(True,axis='y') plt.ylabel('Chip Time') plt.xticks([1],['Runners'])([],)

要回答的第二个问题是:跑者的完成时间是否服从正态分布?

下面是使用seaborn库绘制的跑步者chip times分布图。分布看起来几乎是正常的。

x = df7['Runner_mins']ax = sns.distplot(x,hist=True,kde=True,rug=False,color='m',bins=25,hist_kws={'edgecolor':'black'})plt.show()

第三个问题是关于不同年龄段的男性和女性是否有表现上的差异。

下面是男性和女性芯片时间的分布图。

f_fuko = df7.loc[df7[' Gender']==' F']['Runner_mins']m_fuko = df7.loc[df7[' Gender']==' M']['Runner_mins']sns.distplot(f_fuko,hist_kws={'edgecolor':'black'},label='Female')sns.distplot(m_fuko,hist=False,label='Male')plt.legend()

这一分布表明女性的平均速度比男性慢。您可以使用groupby()方法分别计算男性和女性的汇总统计信息,如下所示。

g_stats = df7.groupby(" Gender",as_index=True).describe()print(g_stats) Runner_mins  count mean std min 25% 50%  Gender  F 163.0 66.119223 12.184440 43.766667 58.758333 64.616667  M 414.0 57.640821 11.011857 36.350000 49.395833 55.791667  75% max  Gender  F 72.058333 101.300000  M 64.804167 98.516667

所有女性和男性的平均芯片时间分别为约66分钟和约58分钟。

那么下面是男性和女性完成时间的并排箱线图比较。

df7.Boxplot(column='Runner_mins',by=' Gender')plt.ylabel('Chip Time')plt.supTitle("")C:UseRSSmasangoAppDataLocalContinuumanaconda3libsite-packagesumpycoreromnumeric.py:57: FutureWarning: reshape is deprecated and will raise in a subsequent release. Please use .values.reshape(...) instead return getattr(obj,method)(*args,**kwds)Text(0.5,0.98,'')

结论

在本教程中,您使用Python执行了Web抓取。 您使用Beautiful Soup库来解析HTML数据并将其转换为可用于分析的表单。 您在Python中执行了数据清理并创建了有用的图表(箱形图,条形图和分布图),用Python的matplotlib和seaborn库来显示有趣的趋势。 在本教程之后,您应该能够使用Python轻松地从Web抓取数据,应用清理技术并从数据中提取有用的见解。

总结

以上是内存溢出为你收集整理的萌新小编用Python做网页爬虫!这个一看就像个老司机做的!全部内容,希望文章能够帮你解决萌新小编用Python做网页爬虫!这个一看就像个老司机做的!所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1208711.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

BibnameGenderCityStateChip TimeChip PaceGender PlaceAge GroupAge Group PlaceTime to StartGun TimeTeam