手把手教你用Python进行Web抓取(附代码)

news2024/12/24 11:41:41

本教程以在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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CAN总线的错误类型

前言 CAN总线的错误类型主要包括&#xff1a;位错误、填充错误、格式错误、ACK错误和CRC错误。这里一定要做好CAN总线的错误类型、错误帧类型、节点状态之间的区别。 错误类型是帧传输出错的原因类型&#xff1b;错误帧类型&#xff08;主动错误帧、被动错误帧&#xff09;是帧…

实习问题(配置文件获取参数)

Java中用SpringBoot框架&#xff0c;当我们要获取配置文件yml里的参数时&#xff0c;用Value注解获取 如果配置文件中没有srvSealUploadPath这个参数的话&#xff0c;可以用Value("${srvSealUploadPath:data/idoc/temp}")&#xff0c;这个的意思是&#xff0c;如果配…

【Python入门】20个Python自动化脚本,解放双手、事半功倍

如果你正在学习Python&#xff0c;那么你需要的话可以&#xff0c;点击这里&#x1f449;Python重磅福利&#xff1a;入门&进阶全套学习资料、电子书、软件包、项目源码等等免费分享&#xff01; 在当今的快节奏工作环境中&#xff0c;自动化不再是一种奢侈&#xff0c;而是…

谷歌浏览器完美清除缓存

1.在页面上按下键盘的F12&#xff0c;打开控制台。 2.鼠标放到刷新图标上&#xff0c;点击鼠标右键&#xff0c;选择‘清空缓存并硬性重新加载’。 这样浏览器对网站页面的缓存就彻底被清理干净了。 目前支持该操作方式的浏览器有谷歌和Edge浏览器。 有的浏览器不支持该方式操…

线上热迁移数据库

1、背景 在线平台用的是公司自己的服务器上面搭建的 MongoDB&#xff0c;测试那边反馈珊瑚海平台 MongoDB 有时会掉线&#xff0c;于是计划将本地数据库迁移到云平台。 2、问题所在 1、因为平台测试的同事还在正在使用平台进行测试工作&#xff0c;所以不可能把平台停掉&…

Web认识 -- 第一课

文章目录 前言一、HTML是什么&#xff1f;二、了解Web1. 基本概念2.Web标准3. Web构成1.前端1. HTML2.CSS3. javaScript4.常见浏览器介绍 2.Web标签构成1.结构标准2.表现标准 -- css3. 行为标准 -- javaScript 总结 前言 这里是我们进入前端学习的开端,在本次更新之后我会陆续…

VUE前后端分离毕业设计题目项目有哪些,VUE程序开发常见毕业论文设计推荐

目录 0 为什么选择Vue.js 1 Vue.js 的主要特点 2 前后端分离毕业设计项目推荐 3 后端推荐 4 总结 0 为什么选择Vue.js 使用Vue.js开发计算机毕业设计是一个很好的选择&#xff0c;因为它不仅具有现代前端框架的所有优点&#xff0c;还能让你专注于构建高性能、高可用性的W…

【C++】map和set的介绍和使用

1.序列式容器与关联式容器 序列式容器&#xff1a; 底层为线性序列的数据结构&#xff0c; 里面存储的是元素本身 。如vector/list/string/deque/forward_list。 关联式容器&#xff1a; 也是用来存储数据的&#xff0c;于序列式容器不同的是&#xff0c; 里面存储的是<key&…

一文详解WebRTC、RTSP、RTMP、SRT

背景 好多开发者&#xff0c;希望对WebRTC、RTSP、RTMP、SRT有个初步的了解&#xff0c;知道什么场景该做怎样的方案选择&#xff0c;本文就四者区别做个大概的介绍。 WebRTC 提到WebRTC&#xff0c;相信好多开发者第一件事想到的就是低延迟&#xff0c;WebRTC&#xff08;W…

基于IntraWeb的数据表格的多选实现

基于IntraWeb的数据表格的多选实现 既可以单条操作&#xff0c;也可以多选操作。 delphi源代码。 BS开发Web网站开发&#xff0c;不需要安装服务器&#xff0c;Apache和IIS都不需要&#xff0c;自带企业级服务器。 运行exe服务器就架好了&#xff0c;直接打开手机浏览器或者…

技术成神之路:设计模式(十八)适配器模式

介绍 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许接口不兼容的类可以协同工作&#xff0c;通过将一个类的接口转换成客户端所期望的另一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的类可以一起工作。 1.定义 适配…

防止错误输入!Excel单元格限制输入内容的三种有效方式

在Excel中&#xff0c;限制单元格输入内容可以帮助避免数据输入错误&#xff0c;确保数据的一致性和准确性。今天小编分享三种方法&#xff0c;可以轻松限制Excel单元格的输入内容&#xff0c;确保数据输入符合预期要求&#xff0c;一起来看看吧&#xff01; 方法一&#xff1a…

超声波清洗机哪家好用又实惠?2024热门超声波清洗机选择推荐!

经过长时间在眼镜清洁领域的深耕&#xff0c;超声波清洗技术已积累广泛用户群体的信任。市场虽繁荣&#xff0c;但也暴露出产品质量的多样性问题&#xff0c;特别是那些依赖营销手段走红的网络品牌或跨行业巨头&#xff0c;它们倾向于强化市场推广而忽视了核心技术的研发。这导…

AI日常绘画【国庆海报】:盛世迎华诞,Flux国庆节海报制作教程

大家好我是极可菌&#xff01;&#xff01;&#xff01; 马上就要到祖国母亲的节日了&#xff0c;想想心里都美滋滋的&#xff0c;终于可以放松一下了。相信AI绘画关于国庆主题肯定也会精彩纷呈吧&#xff0c;今天和大家分享几组关于国庆海报的制作教程。 本文使用基于Flux的相…

一款好用的图像处理软件:Photoshop

Photoshop 常被简称为PS&#xff0c;是图像处理领域里最常用也是很重要的一个工具。在平面广告设计、印刷出版等各领域有有着重要的作用。利用Photoshop图像处理软件&#xff0c;可以设计制作报纸、杂志、书籍、招贴广告、海报、建筑效果图、网页等各种精美的作品&#xff0c;普…

基于大数据技术的共享单车数据分析与辅助管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

mybatis-plus ==> 入门教程

文章目录 为什么要学呢&#xff1f;注意事项 简单入门案例配置日志雪花算法更改 ID 的方法 CRUD插入&#xff08;不解释了&#xff0c;代码非常简单&#xff09;更新查询&#xff08;批量查询&#xff09;按条件查询分页查询删除&#xff08;批量、通过条件、逻辑删除&#xff…

汇川AM400脉冲速度轴(轴控功能块ST源代码)

1、汇川AM400脉冲轴位置控制功能块 汇川AM400脉冲轴控制(轴控功能块ST源代码)-CSDN博客文章浏览阅读292次。汇川AM400电子齿轮指令详细应用介绍(CODESYS ST代码)_汇川plc am400 案例-CSDN博客文章浏览阅读146次。本文介绍了在使用汇川AM400电子齿轮指令前需要理解的比例随动概…

【SQLite】基础操作

数据查询 SELECT 查询所有数据 SELECT *FROM tableName使用AND操作符 SELECT * FROM tableName WHERE id=? AND name=?使用OR操作符 SELECT * FROM tableName WHERE id=? OR name=?组合使用AND和OR SELECT * FROM tableName WHERE (id=? AND name=?) OR status=?多表查询…

Python基础知识---入门概念

有些人不属于自己&#xff0c;但是遇见了也弥足珍贵。 -- 青山刚昌 《名侦探柯南》 安装python解释器 下载官网&#xff1a; Welcome to Python.org 安装pycharm编辑器 下载官网&#xff1a;Download PyCharm: The Python IDE for data science and web development by Je…