作者:Kerry Parker

翻译:田晓宁

校对:丁楠雅

本文约2900字,建议阅读10分钟

本教程以在Fast Track上收集百强公司的数据为例,教你抓取网页信息。

作为一名数据科学家,我在工作中所做的第一件事就是网络数据采集。使用代码从网站收集数据,当时对我来说是一个完全陌生的概念,但它是最合理、最容易获取的数据来源之一。经过几次尝试,网络抓取已经成为我的第二天性,也是我几乎每天使用的技能之一。

在本教程中,我将介绍一个简单的例子,说明如何抓取一个网站,我将从Fast Track上收集2018年百强公司的数据:

Fast Track:

http://www.fasttrack.co.uk/

使用网络爬虫将此过程自动化,避免了手工收集数据,节省了时间,还可以让所有数据都放在一个结构化文件中。

用Python实现一个简单的网络爬虫的快速示例,您可以在GitHub上找到本教程中所介绍的完整代码。

GitHub链接:

https://github.com/kaparker/tutorials/blob/master/pythonscraper/websitescrapefasttrack.py

以下是本文使用Python进行网页抓取的简短教程概述:

  • 连接到网页

  • 使用BeautifulSoup解析html

  • 循环通过soup对象找到元素

  • 执行一些简单的数据清理

  • 将数据写入csv

准备开始


在开始使用任何Python应用程序之前,要问的第一个问题是:我需要哪些库?


对于web抓取,有一些不同的库需要考虑,包括:

  • Beautiful Soup

  • Requests

  • Scrapy

  • Selenium

在本例中我们使用Beautiful Soup。你可以使用Python包管理器 pip 安装Beautiful Soup:

pip install BeautifulSoup4

安装好这些库之后,让我们开始吧!

检查网页


要知道在Python代码中需要定位哪些元素,首先需要检查网页。

要从Tech Track Top 100 companies收集数据,可以通过右键单击感兴趣的元素来检查页面,然后选择检查。这将打开HTML代码,我们可以在其中看到每个字段包含在其中的元素。

Tech Track Top 100 companies链接:

http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/

右键单击感兴趣的元素并选择“Inspect”,显示html元素。

由于数据存储在一个表中,因此只需几行代码就可以直接获取数据。如果您想练习抓取网站,这是一个很好的例子,也是一个好的开始,但请记住,它并不总是那么简单!

所有100个结果都包含在<tr> 元素的行中,并且这些在一页上都可见。情况并非总是如此,当结果跨越多个页面时,您可能需要更改网页上显示的结果数量,或者遍历所有页面以收集所有信息。

League Table网页上显示了包含100个结果的表。检查页面时,很容易在html中看到一个模式。结果包含在表格中的行中:

<table class="tableSorter">

重复的行<tr> 将通过在Python中使用循环来查找数据并写入文件来保持我们的代码最小化!

附注:可以做的另一项检查是网站上是否发出了HTTP GET请求,该请求可能已经将结果作为结构化响应(如JSON或XML格式)返回。您可以在检查工具的网络选项卡中进行检查,通常在XHR选项卡中进行检查。刷新页面后,它将在加载时显示请求,如果响应包含格式化结构,则使用REST客户端(如Insomnia)返回输出通常更容易。

刷新网页后,页面检查工具的网络选项卡

使用Beautiful Soup解析网页html


现在您已经查看了html的结构并熟悉了将要抓取的内容,是时候开始使用Python了!

第一步是导入将用于网络爬虫的库。我们已经讨论过上面的BeautifulSoup,它有助于我们处理html。我们导入的下一个库是urllib,它连接到网页。最后,我们将输出写入csv,因此我们还需要导入csv 库。作为替代方案,可以在此处使用json库。

# import libraries
from bs4 import BeautifulSoup
import urllib.request
import csv

下一步是定义您正在抓取的网址。如上一节所述,此网页在一个页面上显示所有结果,因此此处给出了地址栏中的完整url:

# specify the url
urlpage =  'http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/'

然后我们建立与网页的连接,我们可以使用BeautifulSoup解析html,将对象存储在变量'soup'中:

# query the website and return the html to the variable 'page'
page = urllib.request.urlopen(urlpage)
# parse the html using beautiful soup and store in variable 'soup'
soup = BeautifulSoup(page, 'html.parser')

我们可以在这个阶段打印soup变量,它应该返回我们请求网页的完整解析的html。

print(soup)

如果存在错误或变量为空,则请求可能不成功。可以使用urllib.error模块在此时实现错误处理。

搜索html元素

由于所有结果都包含在表中,我们可以使用find 方法搜索表的soup对象。然后我们可以使用find_all 方法查找表中的每一行。

如果我们打印行数,我们应该得到101的结果,100行加上标题。

# find results within table
table = soup.find('table', attrs={'class': 'tableSorter'})
results = table.find_all('tr')
print('Number of results', len(results))

因此,我们可以对结果进行循环以收集数据。

打印soup对象的前两行,我们可以看到每行的结构是:

<tr>
<th>Rank</th>
<th>Company</th>
<th class="">Location</th>
<th>Year end</th>
<th class="" style="text-align:right;">Annual sales rise over 3 years</th>
<th class="" style="text-align:right;">Latest sales £000s</th>
<th class="" style="text-align:right;">Staff</th>
<th class="">Comment</th>
<!--                            <th>FYE</th>-->
</tr>
<tr>
<td>1</td>
<td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td>
<td>East London</td>
<td>Apr-17</td>
<td style="text-align:right;">294.27%</td>
<td style="text-align:right;">*25,860</td>
<td style="text-align:right;">80</td>
<td>Has sold nearly 3m customisable children’s books in 200 countries</td>
<!--                                            <td>Apr-17</td>-->
</tr>

表格中有8栏:Rank,Company,Location,Year End,Annual Sales Rise,Latest Sales, Staff and Comments,所有这些都是我们可以保存的感兴趣的数据。

网页的所有行的结构都是一致的(对于所有网站来说可能并非总是如此!)。因此,我们可以再次使用find_all 方法将每一列分配给一个变量,那么我们可以通过搜索<td> 元素来写入csv或JSON。

循环遍历元素并保存变量

在Python中,将结果附加到一个列表中是很有用的,然后将数据写到一个文件中。我们应该在循环之前声明列表并设置csv的头文件,如下所示:

# create and write headers to a list 
rows = []
rows.append(['Rank', 'Company Name', 'Webpage', 'Description', 'Location', 'Year end', 'Annual sales rise over 3 years', 'Sales £000s', 'Staff', 'Comments'])
print(rows)

这将打印出我们添加到包含标题的列表的第一行。

你可能会注意到表格中有一些额外的字段Webpage和Description不是列名,但是如果你仔细看看我们打印上面的soup变量时的html,那么第二行不仅仅包含公司名称。我们可以使用一些进一步的提取来获取这些额外信息。

下一步是循环结果,处理数据并附加到可以写入csv的rows。

在循环中查找结果:

# loop over results
for result in results:
    # find all columns per result
    data = result.find_all('td')
    # check that columns have data 
    if len(data) == 0: 
        continue

由于表中的第一行仅包含标题,因此我们可以跳过此结果,如上所示。它也不包含任何<td>元素,因此在搜索元素时,不会返回任何内容。然后,我们可以通过要求数据的长度为非零来检查是否只处理包含数据的结果。

然后我们可以开始处理数据并保存到变量中。

# write columns to variables
    rank = data[0].getText()
    company = data[1].getText()
    location = data[2].getText()
    yearend = data[3].getText()
    salesrise = data[4].getText()
    sales = data[5].getText()
    staff = data[6].getText()
    comments = data[7].getText()

以上只是从每个列获取文本并保存到变量。但是,其中一些数据需要进一步清理以删除不需要的字符或提取更多信息。

数据清理


如果我们打印出变量company,该文本不仅包含公司名称,还包含描述。我们然后打印sales,它包含不需要的字符,如脚注符号,最好删除。

print('Company is', company)
    # Company is WonderblyPersonalised children's books          
    print('Sales', sales)
    # Sales *25,860

我们希望将company 分为公司名称和描述,我们可以用几行代码实现。再看一下html,对于这个列,有一个 <span> 元素只包含公司名称。此列中还有一个链接指向网站上的另一个页面,其中包含有关该公司的更多详细信息。我们将在稍后使用它!

<td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td>

要将company 分成两个字段,我们可以使用find方法保存<span>元素,然后使用strip 或replace 从company 变量中删除公司名称,这样它只留下描述。

要从sales中删除不需要的字符,我们可以再次使用strip和replace 方法!

# extract description from the name
    companyname = data[1].find('span', attrs={'class':'company-name'}).getText()    
    description = company.replace(companyname, '')
    
    # remove unwanted characters
    sales = sales.strip('*').strip('†').replace(',','')

我们要保存的最后一个变量是公司网站。如上所述,第二列包含指向另一个页面的链接,该页面具有每个公司的概述。 每个公司页面都有自己的表格,大部分时间都包含公司网站。

检查公司页面上的url元素

要从每个表中抓取url并将其保存为变量,我们需要使用与上面相同的步骤:

  • 在fast track网站上找到具有公司页面网址的元素

  • 向每个公司页面网址发出请求

  • 使用Beautifulsoup解析html

  • 找到感兴趣的元素

查看一些公司页面,如上面的屏幕截图所示,网址位于表格的最后一行,因此我们可以在最后一行内搜索<a>元素。

# go to link and extract company website
    url = data[1].find('a').get('href')
    page = urllib.request.urlopen(url)
    # parse the html 
    soup = BeautifulSoup(page, 'html.parser')
    # find the last result in the table and get the link
    try:
        tableRow = soup.find('table').find_all('tr')[-1]
        webpage = tableRow.find('a').get('href')
    except:
        webpage = None

也有可能出现公司网站未显示的情况,因此我们可以使用try except条件,以防万一找不到网址。

一旦我们将所有数据保存到变量中,我们可以在循环中将每个结果添加到列表rows。

# write each result to rows
    rows.append([rank, company, webpage, description, location, yearend, salesrise, sales, staff, comments])

print(rows)

然后可以试着在循环外打印变量,在将其写入文件之前检查它是否符合您的预期!

写入输出文件

如果想保存此数据以进行分析,可以用Python从我们列表中非常简单地实现。

# Create csv and write rows to output file
with open('techtrack100.csv','w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerows(rows)

运行Python脚本时,将生成包含100行结果的输出文件,您可以更详细地查看这些结果!

尾语

这是我的第一个教程,如果您有任何问题或意见或者不清楚的地方,请告诉我!

  • Web Development

    https://towardsdatascience.com/tagged/web-development?source=post

  • Python

    https://towardsdatascience.com/tagged/python?source=post

  • Web Scraping

    https://towardsdatascience.com/tagged/web-scraping?source=post

  • Data Science

    https://towardsdatascience.com/tagged/data-science?source=post

  • Programming

    https://towardsdatascience.com/tagged/programming?source=post

原文标题:

Data Science Skills: Web scraping using python

原文链接:

https://towardsdatascience.com/data-science-skills-web-scraping-using-python-d1a85ef607ed

译者简介

田晓宁,质量管理专家,国际认证精益六西格玛黑带,19年从业经验;软件工程专家,拥有CMMI ATM证书,曾主导公司通过CMMI 5级评估;精通ISO9000和ISO27000体系,长期担任公司质量和信息安全主任审核员,每年审核超过50个项目或部门;拥有PMP证书,担任公司项目管理内训师,具有项目管理和系统开发实战经验。

翻译组招募信息

工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

点击文末“阅读原文”加入数据派团队~

转载须知

如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:datapi),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。

发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。

点击“阅读原文”拥抱组织

独家 | 手把手教你用Python进行Web抓取(附代码)相关推荐

  1. 推荐 :手把手教你用Python进行Web抓取(附代码)

    作者:Kerry Parker :翻译:田晓宁:校对:丁楠雅: 本文约2900字,建议阅读10分钟. 本教程以在Fast Track上收集百强公司的数据为例,教你抓取网页信息. 作为一名数据科学家,我 ...

  2. python代码示例图形-纯干货:手把手教你用Python做数据可视化(附代码)

    原标题:纯干货:手把手教你用Python做数据可视化(附代码) 导读:制作提供信息的可视化(有时称为绘图)是数据分析中的最重要任务之一.可视化可能是探索过程的一部分,例如,帮助识别异常值或所需的数据转 ...

  3. python画图代码大全-纯干货:手把手教你用Python做数据可视化(附代码)

    原标题:纯干货:手把手教你用Python做数据可视化(附代码) 导读:制作提供信息的可视化(有时称为绘图)是数据分析中的最重要任务之一.可视化可能是探索过程的一部分,例如,帮助识别异常值或所需的数据转 ...

  4. 独家 | 手把手教你组织数据科学项目!(附代码)

    作者:kdnuggets 翻译:和中华 校对:丁楠雅 本文约4200字,建议阅读10分钟. 本文介绍了一个工具可以帮助迅速构建一个标准但灵活的数据科学项目结构,便于实施和分享数据科学工作. 由Driv ...

  5. python lxml使用_使用lxml和Python进行Web抓取的简介

    python lxml使用 by Timber.io 由Timber.io 使用lxml和Python进行Web抓取的简介 (An Intro to Web Scraping with lxml an ...

  6. python爬虫爬取房源_手把手教你用Python网络爬虫爬取新房数据

    项目背景 大家好,我是J哥. 新房数据,对于房地产置业者来说是买房的重要参考依据,对于房地产开发商来说,也是分析竞争对手项目的绝佳途径,对于房地产代理来说,是踩盘前的重要准备. 今天J哥以「惠民之家」 ...

  7. python人脸识别门禁系统毕设_开源|手把手教你用Python进行人脸识别(附源代码)...

    原标题:开源|手把手教你用Python进行人脸识别(附源代码) 全球人工智能 来源:Github 翻译:黄玮 想要了解目前世界上最简洁的人脸识别库吗?现在小编带大家来学习使用Python语言或命令行进 ...

  8. 如何用 Python 实现 Web 抓取?

    [编者按]本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正 ...

  9. 使用python进行web抓取

    http://cxy.liuzhihengseo.com/462.html 原文出处:  磁针石    本文摘要自Web Scraping with Python – 2015 书籍下载地址:http ...

最新文章

  1. VTK:IO之FindAllArrayNames
  2. pic单片机低电压检测_pic单片机汇编语言讲解(上)
  3. D:\我的文档\收藏夹
  4. 记事本linux命令换行符,Windows 10版记事本应用终于支持Linux/Mac换行符 排版不再辣眼睛...
  5. leetcode题解72-编辑距离
  6. eclipse git拉取失败_Git(四):分支
  7. 通向架构师的道路(第八天)之weblogic与apache的整合与调优 转
  8. Android常用提示框(dialog和popuwindow)
  9. R plot图片背景设置为透明_R语言(绘图入门)
  10. wps下一步快捷键_WPS快捷键大全
  11. 单晶X射线衍射法和粉末X射线衍射法有哪些不同?
  12. 2023-2029年中国LED产业园区行业市场深度监测及战略咨询研究报告
  13. Python修改Word文件设置所有图片都居中对齐
  14. 如何增加百度收录量和友好度
  15. js实现kmp算法_基于KMP算法JavaScript的实现方法分析
  16. 软件界面原型设计工具 Web Axure RP
  17. vb中线性拟合_VB做曲线拟合
  18. 推荐几个 VS Code 扩展、主题和字体!
  19. java中按学号查找_Java课程设计---浏览学生(实现根据姓名查询)
  20. 为什么要使用堆栈? sp和fp的解释

热门文章

  1. AngularJS中选择样式
  2. keepalived_nginx实现discuz负载均衡和高可用
  3. Loadrunner日志设置与查看
  4. [Everyday Mathematics]20150222
  5. [笔记]解决m2eclipse给项目添加maven依赖管理时可能不给项目的build path...
  6. MegaCli常用命令详细介绍
  7. IIS6的PHP最佳配置方法
  8. 操作系统信号量与P、V操作 初步认识整理
  9. mysqluc安装MYSQL_安装mysql几种方法
  10. 基于朴素贝叶斯的垃圾分类算法(Python实现)