TowardsDataScience 博客中文翻译 2020(九百六十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

利用 CityGML 城市模型实现基于 Web 的三维数据可视化

原文:https://towardsdatascience.com/web-based-3d-data-visualization-with-ciytgml-city-models-f0796b37e9f5?source=collection_archive---------26-----------------------

3D 数据可视化基本指南

分步指南-可视化纽约市曼哈顿的 3D 城市模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

插图作者:金彩云

在这篇文章中,我将向您展示一种在基于 web 的应用程序上使用 Node.js铯. js web globe 库可视化 CityGML 3D 城市模型的简单方法,并以曼哈顿纽约市区域为例。在本简短教程结束时,您将能够构建一个看起来或多或少像这样的 web 应用程序:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关于铯应用的纽约曼哈顿 3D 城市模型(现场演示:

CityGML 简介

在我们开始之前,我想向您介绍一下 CityGML 3D 城市模型。 CityGML 是一种开放的标准化数据模型和交换格式,用于存储 OGC(开放地理空间联盟)推出的城市和景观的数字 3D 模型。CityGML 的特殊之处在于它是一个语义城市模型,包含属性和几何数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CityGML 德国慕尼黑带有属性数据的语义 3D 城市模型。(现场演示:3D 德国

CityGML 模型的几何形状和属性允许各种模拟建筑能源需求、光伏潜力等等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 CityGML 对德国路德维希堡—格伦布尔的建筑能源需求进行建模的示例(能源建模使用 SimStadt2 软件进行计算)

好消息!!世界上有几个城市有自己的 CityGML,其中许多城市都以开源数据集的形式提供了它们的 CityGML。

从 CityGML 构建基于网络的 3D 应用程序

1.准备 3D 数据集

纽约市 DoITT 以 CityGML 格式发布了纽约市的语义 3D 城市模型,包括纽约市的每一栋建筑。在这里随意下载。从这个数据集中,我们将只关注曼哈顿地区(DA12 _ 3D _ Buildings _ merged . GML~ 48,000 栋建筑),并使用它来创建 3D web 应用程序。

虽然 CityGML 适合交换和存储 3D 建筑模型,但它不能直接在 web 上可视化。因为我们将在我们的 web 应用程序中使用铯,所以我们需要将 CityGML 转换为 3D Tiles 格式。FME 工作台是我所知道的最好的工具,对学生和开源研究项目也是免费的。

或者,你可以跳过这一步,从下面我的 GitHub 项目中下载已经转换好的 3D 图片。

2.设置 Web 服务器

对于 web 服务器,使用以下依赖项创建一个项目文件夹和 Node.js 项目:

$ **npm init** #initiate node project
$ **npm install express** #install express framework
$ **npm install compression** #install compression 

然后,用 Express 为 Node.js 创建一个简单的 server.js 文件。

带有 Express Framework 的简单 Node.js 示例

您可以通过$ node server.js命令来试运行您的服务器。

3.使用 CesiumJS 的 3D 应用程序

我们将使用 CesiumJS 来渲染我们的 3D 建筑模型。这是一个开源的 JavaScript 库,用于 web 浏览器中的 3D 地球仪和 2D 地图。

现在,让我们在public文件夹中创建一个index.html文件,并放置以下代码:

index.html(用于铯 3D 纽约应用)

这个 HTML 基本上从 cesium.com 加载铯依赖项,并创建一个铯容器。变量tileset通常指的是 3D 瓦片数据集。只需在此处用您的本地零件替换url值即可转换为 3D 图块。搞定了。

从这里,当你运行$ node server.js并前往http://localhost:3000,你已经可以看到曼哈顿的 3D 模型了。如果你想要一些建筑模型的颜色/样式,可以通过 tileset 样式添加。下面的示例脚本显示了如何基于建筑高度设置建筑模型的样式。

colorbyHeight.js(按建筑高度设置 3D 图块样式)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

耶!我们对纽约城市模型的最终应用

差不多就是这样!我为挑选功能添加了一些代码,如果你感兴趣,可以从我的 GitHub 这里查看全部代码:

[## JoeThunyathep/NYC3D_CesiumJS

纽约市三维城市模型。在…上创建一个帐户,为 JoeThunyathep/NYC3D_CesiumJS 的发展做出贡献

github.com](https://github.com/JoeThunyathep/NYC3D_CesiumJS)

奖金

如果你想继续开发这个应用程序,你可以用铯和 3D 城市模型做更多很酷的事情。请在此查看一些资源:

  • CesiumJS API 文档:链接 /一些好看的展示:链接
  • 掌握你的铯式表情文档:链接
  • 开放 CityGML 数据
    -美国纽约市所有建筑的 CityGML【LOD 2】(链接 )
    -美国所有建筑的 City GML!!!!【LOD 1】(链接 )
    -德国北莱茵-威斯特伐利亚州所有建筑的 CityGML【LOD 1,2】(链接)
    -TU-Delft 多个城市开放 CityGML 数据列表(链接 )
    )【无 city GML,无忧。查看 FME 的《城市地图指南》
  • 3DCityDB :开源地理数据库,用于存储、表示和管理虚拟 3D 城市模型:(链接)
  • 更多关于 OGCcity GML的信息(链接)
  • 真实世界应用:请查看 VCS 公司提供的使用铯+ CityGML( 链接)的智能 Cites 解决方案

作者消息:

总的来说,本教程涵盖了使用铯. js 和 3D 城市模型创建 3D 基于 web 的应用程序的基础。我希望你喜欢这篇文章,并发现它对你的日常工作或项目有用。

关于我&查看我所有的博客内容:链接

安全健康健康**!💪**

感谢您的阅读。📚

带有洛杉矶公寓和社区搜索工具的网络搜索工具

原文:https://towardsdatascience.com/web-scraper-with-search-tool-for-los-angeles-apartments-neighborhoods-4b1958ef7500?source=collection_archive---------40-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

概念验证公寓和邻居指标

作为一名洛杉矶的常住居民,我发现在这个城市找到符合你要求的出租房可能会很棘手。在像 Craigslist 和 apartments 这样的网络数据库中,帖子包含了关于公寓本身的丰富信息。然而,缺少邻居数据… 为了全面了解公寓邻居,用户必须建立单独的邻居数据库,并手动交叉引用公寓列表。另一个障碍是,像 Craigslist 和 Apartments.com这样的网站不提供每套公寓的指标或邻居基准,这使得用户在选择他们在洛杉矶想要的公寓和邻居时,无法做出完全知情的决定

拟议解决方案

为了解决洛杉矶出租房屋信息的缺口,我创建了一个 Craigslist 公寓搜索工具和增强的搜索工具。该项目使用 Python & SQLite 构建,将洛杉矶 Craigslist 公寓与社区经济和无家可归者指标相结合。概念验证(POC)现已在我的 Github 页面上提供用户友好的指南- > 此处

POC 目前包括:

  • Python 脚本的存储库,它执行 web 抓取、数据库生成和测试查询。
  • Python Jupyter Notebook ,它显示查询结果、一些简单的生成指标散点图,以及对这些指标的数据进行排序的可能性

下面我将提供 python 代码每个组件设计背后的一些细节,突出优点和缺点。该项目基于 2019 年秋季南加州大学维特比工程学院应用数据科学硕士项目的一门课程的作业,由 Jeremy Abramson 教授提供建议。我也从 Julio Malegria 的 python-craigslist 模块Riley PredumCraigslist 网页抓取教程中获得了灵感。我从这些已有的知识中学到了很多,并希望能在此基础上更上一层楼!

脚本驱动程序

为了给 python 脚本和结果数据库创建一些组织,我用两个子文件夹构建了存储库:

  • src —保存用于生成数据库的所有脚本,包括:驱动文件、python 模块需求、公寓刮刀、邻居刮刀和测试查询
  • 数据 —保存 SQLite 数据库,该数据库包含公寓和邻居抓取脚本的结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

python 脚本、数据、查询和图形的报告结构

使用驱动程序获取数据

下载存储库并导航到终端内的“src”文件夹后,用户可以使用远程或本地数据调用驱动程序文件“LA_Apartment_Analysis.py”。可以输入的两个命令是:

$ python3 LA_Apartment_Analysis.py local
$ python3 LA_Apartment_Analysis.py remote
  • 本地 —用本地数据库(缓存)运行程序,如果有的话。如果本地数据库不存在,您将需要远程运行程序,以便在分析(也称为查询)完成之前生成一个本地数据库。
  • remote —首先从‘neighborhoods _ API . py’和‘apartments _ scrape . py’中的远程 web 源创建数据库,然后运行程序。

从命令行调用的驱动程序文件“LA_Apartment_Analysis.py”,用于调用抓取器和查询

Craigslist 网页抓取

司机调用公寓抓取器‘apartments _ scrape . py’后,Craigslist 公寓抓取就开始了。代码被彻底地注释了,所以人们可以在那里回顾每一步,但是我在下面强调了 scraper 的主要步骤。这里使用的主要 python 库是:requests、BeautifulSoup、pandas 和 sqlite3。

步骤 1:创建一个 craigslist 公寓搜索查询,并获得所有公寓链接的列表。

为了验证概念,我的默认搜索是洛杉矶有照片的公寓,今天发布的租金价格在 1800-2800 美元之间,距离邮政编码 90036(贝弗利-费尔法克斯区)3 英里。如果用户的查询有超过 120 个结果,应该激活第 201–212 行,以便从包含许多公寓列表的多个页面中获取链接。

get_link_list(url_query)生成包含嵌入公寓链接的 html 对象列表

步骤 2:对于每个公寓链接,从链接的 html 对象中解析公寓属性,并存储在字典列表中。

名为‘process _ links(link _ list)’的函数获取每个链接,并发送一个对该链接的 html 对象的请求。请求成功完成后,代码提取嵌入在 hmtl 对象中的有意义的公寓属性,比如:卧室、浴室、价格、平方英尺、纬度和经度。

在当前代码中,大约 70–80%的公寓列表的公寓抓取是成功的。如果一个单元属性不能被抓取,代码继续尝试抓取下一个单元。这就是为什么我们在处理请求时实现了大量的异常处理。在未来的迭代中,我希望将所有公寓房源的成功率提高到 100%。

处理链接的速度可以接受,但是速度可以通过 python 并发 来提高。使用 python 实现并发性将允许在同一台计算机的多个处理器中同时执行任务。这应该是提高处理速度的可行途径,但我们也必须尊重 Craigslist 的限速政策,以避免该网站可能维持的任何 IP 禁止政策。

process_links(link_list)接受一个链接列表,并为每个单元链接创建一个一行的单元属性表

步骤 3:对于每个公寓纬度&经度,获取人口普查区域 ID。

这一步对于实现到洛杉矶邻居表的连接至关重要。为此,我们必须在一个 GET API 请求中向 geocoding.geo.census.gov 发送每个公寓的纬度和经度。由于 census 提供的这个 API 的性能较慢,这个步骤比 Craigslist 抓取花费的时间要长得多…在未来的版本中,我将实现一些 python 并发来减少处理时间。这仍然不会对人口普查地理编码器 API 的缓慢产生影响。

request _ tractid(apt _ tractid _ URL _ list)接受一个人口普查 api urls 列表,并返回具有 apartment tract_id 的相关 json 对象。

步骤 4:在 SQLite 表中存储公寓属性和人口普查区域 id。

为了序列化收集的数据,代码获取字典列表,并将它们转换成 pandas 数据帧。接下来,代码移动到/data 存储库中,并创建名为“la_apartments.db”的 SQLite 数据库和一个名为“apartment”的表。最后,公寓数据帧的每一行都被复制到“公寓”表中。

存储熊猫数据帧中的公寓表

洛杉矶邻里 API

在这一步中,我们使用“neighborhoods_api.py”脚本构建一个邻域表。邻域表将包含每年每个人口普查区域 ID 的一行。邻域属性从两个独立的站点获取,都是通过 API 功能。由于这些站点提供 API 服务来获取数据,因此创建“邻居”表所需的时间比创建“公寓”表要少得多。

用于收集邻域数据的两个来源如下:

  • 洛杉矶市— 该站点包含基本的社区属性,如 TRACT_ID、COUNTY、YEAR、POPULATION。到数据集和 API 文档的链接是 这里是
  • 南加州大学社会创新价格中心— 该网站包含一系列不同的社区数据集,按人口普查区域 ID 排列。使用的主要数据集:平均租金价格数据集— 此处;无家可归数据集— 此处

通过 API 收集邻域数据后,“neighborhoods_api.py”使用 pandas 来转换数据,以组合来自三个来源的属性。然后,该表作为“邻居”表写入 SQLite 数据库。

存储熊猫数据帧中的邻居表

查询和散点图

在数据库中创建了“公寓”和“邻居”表之后,驱动程序从“查询 _ 来自 _ 终端. py”中调用测试查询。结果显示在终端中,显示一些关于关系数据库的基本查询。

如果用户愿意,他们可以通过 Jupyter 笔记本“mann_mark.ipynb”查看查询结果和一些额外的散点图。查询和绘图提供了对公寓搜索过程至关重要的先前未回答的问题的洞察力。最终,这个数据库和查询可以构建到单页面 web 应用程序中的交互式搜索工具中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Jupyter 笔记本“mann_mark.ipynb ”,显示计算指标,如“价格每平方英尺”和“无家可归者每平方英尺”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

散点图展示了如何根据计算出的指标可视化公寓数据

未来版本

将来,我希望创建一个连接到这个公寓和邻居数据库的 web 应用程序。在 web 应用程序中,用户可以查询他们自己对洛杉矶公寓的偏好。将有一个选项供用户设置重复工作(每天,每周,每月)和发送电子邮件时,数据被刷新。还可以选择从数据库下载标准化报告,或者公寓和邻居表本身。

突出显示人口普查区域和公寓位置的地图工具也会有所帮助。在这个工具中,用户可以根据邻居的度量标准,比如每平方英里无家可归的人数,来给邻居着色。下面是一个工具的例子,我想在未来创造。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每平方英里的无家可归者地图,每个区域 id。使用 datawrapper [ 链接创建的映射

如果你已经做到这一步,感谢你的阅读!我乐于接受问题、评论或反馈。

原载于 2020 年 1 月 9 日【https://medium.com】

网页抓取 101

原文:https://towardsdatascience.com/web-scraping-101-d9170e880117?source=collection_archive---------11-----------------------

如何制作一个简单的机器人在任何投票或竞争中获胜

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

斯科特·格雷厄姆Unsplash 上拍照

网络抓取是一个在网上检索数据和执行特定操作的过程。它通常由机器人来完成,以便自动化某些重复的任务。这是一个相当大的研究领域,你可以用它做很多有趣的事情。开始并不一定是缓慢和困难的。在本文中,我将向您介绍一个创建机器人的简单过程,以及将来如何对其进行扩展。不需要以前的经验,只需要 Python 和互联网连接。

入门指南

本教程适用于任何编程水平的初学者,所有内容都将尽可能清晰明了地解释。我将使用一个随机的民俗比赛来演示投票。你可以使用任何你喜欢的网站,并在此基础上进行调整。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(作者截图)

在直接进入编码之前,我们必须设置两件事情。

第一步。安装 IDE

首先,我们需要一个地方来写代码,如果你还没有的话。我更喜欢使用 Visual Studio 代码,因为它简单并且提供你需要的任何东西。只需搜索“Visual Studio 代码”并下载最新版本。

安装完成后,单击扩展按钮并安装 Python。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(作者截图)

第二步。下载 ChromeDriver

我们需要一个模块,能够与谷歌浏览器。这一步相当短。搜索“ChromeDriver Chromium”并下载最新版本。下载完成后,解压文件。

*对于 Windows,*复制文件,创建一个文件夹,如“C:\webdrivers”并放在那里。现在,转到路径设置,并在那里添加文件夹路径(如果你不知道这是在哪里,在谷歌有大量的解释)。

*对于 Mac 和 Linux,*打开终端并键入

mv ~/Downloads/chromedriver /usr/local/bin

制作机器人

第一步。准备文件和包

太好了,现在我们已经设置好了,可以开始了!让我们创建一个新文件夹,命名为“网络抓取”。现在,打开 Visual Studio 代码,创建一个名为“vote_bot.py”的新文件。

在终端窗口中键入:

python -m venv venv

这将创建一个虚拟环境,它基本上允许我们在不修改您的系统软件包的情况下安装软件包。要激活它:

source venv/Scripts/activate

接下来,我们需要一个软件包,它将帮助我们使用 web 浏览器。类型:

pip install selenium

第二步。开始编码

用 VS 代码打开我们的 vote_bot 文件。我们要使用的第一行是:

from selenium import webdriver
import time

这将为我们的项目添加 web 驱动程序支持,并在后面的步骤中帮助我们。此外,我们导入时间只是为了能够让页面打开更长时间。

接下来,我们将定义一个机器人。这个机器人将为我们工作。类定义基本上是描述一个我们想要的对象。例如,狗具有某些特征,例如腿、高度、速度和年龄。和机器人一样,我们需要输入它的特征。在本教程中,我试图使它尽可能简单,所以我们需要的唯一定义是我们将用于浏览器的驱动程序。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")

现在,当我们创建一个机器人时,首先要做的是定义驱动程序。我们可以实际尝试一下,看看效果如何。通过键入 python vote_bot.py,我们可以运行该程序。如果加上“-i”,就可以直接和代码交互了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(作者截图)

重复上述步骤后,应该会打开一个新的浏览器窗口。如果你没有看到一个新的 Chrome 窗口,请确保你已经正确安装了 ChromeDriver 和 selenium,这在前面的步骤中有解释。

我们需要一个函数来完成投票。这里的投票过程只是打开一个链接,所以说我们选择第二个参赛者,我们只是复制投票的链接。下面的代码将打开投票页面,保持打开 1 秒钟,然后关闭。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")def vote(self):
    self.driver.get('[https://eaff.eu/bg/online-festival-vote-choice/30](https://eaff.eu/bg/online-festival-vote-choice/15)')
    time.sleep(1)
    self.driver.close()

现在,我们已经完成了我们的机器人。我们只需要添加一个循环,这样我们就可以生成无限量的投票并测试它。完整代码附后。

class VoteBot():
  def __init__(self):
      self.driver = webdriver.Chrome("C:\webdrivers\chromedriver.exe")def vote(self):
    self.driver.get('[https://eaff.eu/bg/online-festival-vote-choice/30](https://eaff.eu/bg/online-festival-vote-choice/15)')
    time.sleep(1)
    self.driver.close()while True:
  bot = VoteBot()
  bot.vote()

第三步。坐下来享受吧

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(作者截图)

只需在您的终端中键入“python vote_bot.py ”,然后观察机器人多次重复该任务。正如你所看到的,机器人将投票,关闭窗口,并再次投票。

最后的话

本教程是为刚刚开始编程和网络抓取的人编写的。对于任何问题,请随时在这个帖子中留下你的问题,我会尽我所能帮助你。为了进一步实验,尝试使用不同类型的按钮和登录序列,更多的我将很快摆姿势。保持冷静,继续编码!

面向自然语言处理的网页抓取和预处理

原文:https://towardsdatascience.com/web-scraping-and-pre-processing-for-nlp-2e78810b40f1?source=collection_archive---------24-----------------------

冥想项目

使用 Python 抓取和处理 web 上的文本数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 timJUnsplash 上拍摄

对于自然语言处理,干净的数据很重要。当数据来自网络时更是如此。在这篇文章中,我们将通过一个斯多葛派哲学文本生成器的 web 抓取和数据预处理的真实例子。

我们将使用的数据是由流亡的罗马参议员塞内卡在斯托晚期写的《致卢西留斯的道德书》。

书信

这些信件来源于维基资源,这里是。这一页包括所有 124 封信的列表。其中每个字母都包含在它自己的页面中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先,我们必须从这个内容页面中提取 HTML。为此,我们使用 Python 的requestsBeautifulSoup库。

这给了我们一个漂亮的 Soup 对象,它包含了我们通过html给出的原始 html。让我们看看这是什么样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这种情况下,我们必须提取每个字母的本地路径。BeautifulSoup 对象允许我们用soup.find_all('a')提取所有的<a>元素。然而,这将返回所有的 <a>元素,所以我们需要过滤那些链接到字母的元素。

我们使用正则表达式来实现这一点,这非常简单,我们构建正则表达式来搜索任何以Letter开头,后跟一个或多个空格\s+,最后以一到三位数\d{1,3}结尾的内容。这给了我们re.compile(r"^Letter\s+\d{1,3}$")

通过将这个正则表达式应用于 BeautifulSoup 提供的<a>元素列表,我们将得到如下结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

麻痹性鼻出血

现在我们需要定义一个函数来解析每个页面的 HTML。这实际上非常简单,因为字母文本全部包含在页面上仅有的<p>元素中。

因此,与之前类似,我们提取所有的<p>元素。然后,在返回信件文本之前,我们进行少量的格式化,使文本更具可读性。

Omnis 书信

通过我们的pull_letter功能和letters_regex,我们可以阅读所有的信件,我们将把它们放在moral_letters中。

此时我们已经得到了所有需要的数据,整齐地存储在moral_letters中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

准备工作

将我们的数据格式化成 NLP 友好的格式要简单得多,尽管抽象得多。

我们需要将当前的文本转换成数字,创建数据的数字表示,我们称之为data_idx

为此,我们将创建一个char2idx字典,代表字符索引。顾名思义,这将字符'a', 'b', 'c'转换为索引0, 1, 2

char2idx中的每个字符也必须映射到一个唯一的索引。为此,我们必须在数据中创建所有字符的集合(集合只是列出唯一的值)。这组字符被称为词汇表,我们将把它定义为vocab

现在,让我们用新的格式来读塞内加的第一封信。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

虽然这看起来很荒谬,但这正是我们在为 NLP 格式化文本数据时想要的。

现在剩下的就是对我们的数据进行切片和洗牌,然后就可以输入到模型中了。在我们的例子中,我们使用的是tensorflow

单形世界

TensorFlow 允许我们使用[tf.data.Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset),一个我们可以用来简化数据集转换过程的 API。为了从我们的 Numpy 数组data_idx创建数据集,我们使用tf.data.Dataset.from_tensor_slices

在训练中,我们一次只会看一段文字。为了将数据分割成序列,我们使用Dataset .batch方法。

由于这是一个文本生成器,我们的目标数据将只包含输入数据,向前移动一个字符。为此,我们将定义一个名为split_xy的函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我们再次使用.batch创建 64 个序列的批次,然后使用.shuffle将它们混洗。

dataset里面,我们有 175 个批次*(由于* *len(txt) / (SEQLEN * BATCHSIZE)* ) 。每个批处理都包含一个由split_xy函数构建的输入和目标数组。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些数据现在已经完全准备好了,可以输入到模型中进行训练。

结论是什么

尽管外表复杂。机器学习的实现不再是一项庞大的任务,只留给我们这个时代最聪明的人。

我们现在生活在这样一个时代,我们可以教计算机从人类历史上一些最伟大的头脑中复制哲学。我们不仅能做到,而且非常容易做到。

这是一个迷人的时代,我希望我们都能充分利用这个时代。

感谢阅读!

我以前写过设计神经网络来重现斯多葛派哲学。如果你感兴趣,你可以在这里阅读:

[## 斯多葛派哲学——由算法构建

再现历史上最有权势的人之一所写的斯多葛派哲学

towardsdatascience.com](/stoic-philosophy-built-by-algorithms-9cff7b91dcbd)

For anyone that is curious, here are my (attempted) Latin translations of the article headers.**Epistulae**: Letters
**Unum Epistula Legimus**: We read one letter
**Omnis Epistulae**: All letters
**Praeparatio**: Preparation (eg preparing the data)
**Simplex Munditiis**: Elegance through simplicity
**Qui Conclusioni**: Here concludes / the conclusion

网页抓取基础知识

原文:https://towardsdatascience.com/web-scraping-basics-82f8b5acd45c?source=collection_archive---------0-----------------------

如何用 Python 从网站上抓取数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由弗朗克五世从 Unsplash

在数据科学中,我们总是说“垃圾进垃圾出”。如果你没有好的质量和数量的数据,很可能你不会从中获得很多见解。Web 抓取是自动检索第三方数据的重要方法之一。在这篇文章中,我将介绍 web 抓取的基础知识,并用两个例子来说明用 Python 实现 web 抓取的两种不同方式。

什么是网络抓取

Web 抓取是一种从网站检索非结构化数据并以结构化格式存储它们的自动方式。比如你想分析什么样的面膜能在新加坡卖的更好,你可能想在 Lazada 这样的电商网站上把所有的面膜信息都刮下来。

你能从所有的网站上搜集信息吗?

抓取使网站流量激增,并可能导致网站服务器崩溃。因此,并不是所有的网站都允许人们刮。如何知道哪些网站是允许的,哪些是不允许的?你可以看看网站的‘robots . txt’文件。你只需简单地把 robots.txt 放在你想抓取的网址后面,你就会看到网站主机是否允许你抓取网站的信息。

以 Google.com 为例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Google.com 的 robots.txt 文件

你可以看到谷歌不允许它的许多子网站进行网络抓取。然而,它允许像“/m/finance”这样的路径,因此如果你想收集金融信息,这是一个完全合法的地方。

另一个注意事项是,您可以从 User-agent 上的第一行看到。在这里,谷歌为所有用户代理指定了规则,但网站可能会给某些用户代理特殊权限,所以你可能想参考那里的信息。

网页抓取是如何工作的?

网络抓取就像一个机器人浏览网站的不同页面,并复制粘贴所有的内容。当您运行代码时,它将向服务器发送一个请求,数据包含在您得到的响应中。然后您要做的是解析响应数据并提取出您想要的部分。

我们如何做网页抓取?

好了,我们终于到了。根据网站内容的结构,有两种不同的方法来抓取网页。

方法 1: 如果网站将所有信息都存储在 HTML 前端,你可以直接用代码下载 HTML 内容,从中提取有用的信息。

大致有以下 5 个步骤:

  1. 检查您要爬网的网站 HTML
  2. 使用代码访问网站的 URL,并下载页面上的所有 HTML 内容
  3. 将下载的内容格式化为可读格式
  4. 提取有用的信息,并将其保存为结构化格式
  5. 对于显示在网站多个页面上的信息,您可能需要重复步骤 2-4 以获得完整的信息。

这种方法的利弊:简单直接。然而,如果网站的前端结构发生变化,那么你需要相应地调整你的代码。

**方法二:**如果网站将数据存储在 API 中,用户每次访问网站时网站都会查询 API,那么您可以模拟请求,直接从 API 中查询数据

步骤:

  1. 检查您要爬网的 URL 的 XHR 网络部分
  2. 找出为您提供所需数据的请求-响应
  3. 根据请求的类型(post 或 get)以及请求头和负载,在您的代码中模拟请求并从 API 中检索数据。通常,从 API 获得的数据格式非常简洁。
  4. 提取出你需要的有用信息
  5. 对于对查询大小有限制的 API,您需要使用“For 循环”来重复检索所有数据

**这种方法的利与弊:**如果您能找到 API 请求,这绝对是一种首选方法。你收到的数据会更加结构化,更加稳定。这是因为与网站前端相比,公司不太可能改变其后端 API。但是,它比第一种方法稍微复杂一些,尤其是在需要身份验证或令牌的情况下。

web 抓取的不同工具和库

有许多不同的不需要任何编码的抓取工具。然而,大多数人仍然使用 Python 库来做 web 抓取,因为它易于使用,而且你可以在它的大社区中找到答案。

Python 中网页抓取最常用的库是美汤、请求、硒

Beautiful Soup: 它帮助您将 HTML 或 XML 文档解析成可读的格式。它允许您在文档中搜索不同的元素,并帮助您更快地检索所需的信息。

**请求:**这是一个 Python 模块,您可以在其中发送 HTTP 请求来检索内容。它通过发送 Get 或 Post 请求来帮助您访问网站 HTML 内容或 API。

Selenium: 它广泛用于网站测试,它允许你自动化网站上的不同事件(点击、滚动等)以获得你想要的结果。

你要么用 Requests +美汤,要么用 Selenium 做网页抓取。如果你需要与网站交互(JavaScript 事件),Selenium 是首选,如果不是,我会首选请求+漂亮的汤,因为它更快更容易

网页抓取示例:

**问题陈述:**我想了解一下当地的面膜市场。我对网上面膜的价格、折扣、评分、销售量等很感兴趣。

方法 1 示例(下载所有页面的 HTML)—laza da:

第一步:检查网站(如果使用 Chrome,可以右键单击并选择检查)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

检查 Chrome 上的 Lazada 页面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Lazada 上价格的 HTML 结果

我可以看到我需要数据都用惟一的类名包装在 HTML 元素中。

第二步:使用代码访问网站的 URL,下载页面上所有的 HTML 内容

# import library
from bs4 import BeautifulSoup
import requests# Request to website and download HTML contents
url='https://www.lazada.sg/catalog/?_keyori=ss&from=input&q=mask'
req=requests.get(url)
content=req.text

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在应用美丽的汤之前请求内容

我使用请求库从一个网站获取数据。你可以看到,到目前为止,我们得到的是无结构的文本。

第三步:将下载的内容格式化为可读格式

soup=BeautifulSoup(content)

这一步非常简单,我们所做的只是将非结构化的文本解析成漂亮的汤,你得到的如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用美汤后的 HTML 内容

输出是一种可读性更强的格式,您可以在其中搜索不同的 HTML 元素或类。

第四步:提取出有用的信息并保存成结构化的格式

这一步需要一些时间来理解网站结构,并找出数据存储的确切位置。对于 Lazada,它以 JSON 格式存储在脚本部分。

raw=soup.findAll('script')[3].text
page=pd.read_json(raw.split("window.pageData=")[1],orient='records')
#Store data
for item in page.loc['listItems','mods']:
    brand_name.append(item['brandName'])
    price.append(item['price'])
    location.append(item['location'])
    description.append(ifnull(item['description'],0))
    rating_score.append(ifnull(item['ratingScore'],0))

我创建了 5 个不同的列表来存储我需要的不同字段的数据。我在这里使用了 for 循环来遍历内部 JSON 文档中的项目列表。之后,我将这 5 列合并到输出文件中。

#save data into an output
output=pd.DataFrame({'brandName':brand_name,'price':price,'location':location,'description':description,'rating score':rating_score})

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Python 数据帧格式的最终输出

步骤 5:对于显示在网站多个页面上的信息,您可能需要重复步骤 2-4 以获得完整的信息。

如果你想收集所有的数据。首先,你应该了解卖家的总数。然后,您应该通过使用有效负载到 URL 传递递增的页码来遍历页面。下面是我收集的完整代码,我循环了前 50 页来获取这些页面上的内容。

for i in range(1,50):
    time.sleep(max(random.gauss(5,1),2))
    print('page'+str(i))
    payload['page']=i
    req=requests.get(url,params=payload)
    content=req.text
    soup=BeautifulSoup(content)
    raw=soup.findAll('script')[3].text
    page=pd.read_json(raw.split("window.pageData=")[1],orient='records')
    for item in page.loc['listItems','mods']:
        brand_name.append(item['brandName'])
        price.append(item['price'])
        location.append(item['location'])
        description.append(ifnull(item['description'],0))
        rating_score.append(ifnull(item['ratingScore'],0))

方法 2 示例(直接从 API 查询数据)— Ezbuy:

第一步:检查您想要抓取的 URL 的 XHR 网络部分,并找出提供您想要的数据的请求-响应

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

网络下的 XHR 部分—产品列表 API 请求和响应

我从网络上看到,所有的产品信息都列在这个叫做‘按条件列出产品’的 API 里。该响应提供了我需要的所有数据,并且是一个 POST 请求。

步骤 2:根据请求的类型(post 或 get)以及请求头&有效负载,在您的代码中模拟请求并从 API 中检索数据。通常,从 API 获得的数据格式非常简洁。

s=requests.session()#Define API url
url_search='[https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition'](https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition')#Define **header** for the post request
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}#Define **payload** for the request form
data={
    "searchCondition": 
        {"categoryId":0,"freeShippingType":0,"filter: [],"keyWords":"mask"},
        "limit":100,
        "offset":0,
        "language":"en",
        "dataType":"new"
    }req=s.post(url_search,headers=headers,json=data)

这里我使用请求库创建 HTTP POST 请求。对于 post 请求,您需要定义请求头(请求的设置)和有效负载(与这个 post 请求一起发送的数据)。有时这里需要令牌或身份验证,在发送 POST 请求之前,您需要先请求令牌。这里不需要检索令牌,通常只需遵循网络中请求有效载荷的内容,并为报头定义“用户代理”。

这里要注意的另一件事是,在有效负载中,我将 limit 指定为 100,offset 指定为 0,因为我发现它一次只允许我查询 100 个数据行。因此,我们稍后可以做的是使用 for 循环来改变偏移量并查询更多的数据点。

第三步:提取出你需要的有用信息

#read the data back as json file
j=req.json()# Store data into the fields 
for item in j['products']:
    price.append(item['price'])
    location.append(item['originCode'])
    name.append(item['name'])
    ratingScore.append(item['leftView']['rateScore'])
    quantity.append(item['rightView']['text'].split(' Sold')[0]#Combine all the columns together
output=pd.DataFrame({'Name':name,'price':price,'location':location,'Rating Score':ratingScore,'Quantity Sold':quantity})

来自 API 的数据通常非常整洁和结构化,因此我所做的只是以 JSON 格式读取它。之后,我将有用的数据提取到不同的列中,并将它们组合在一起作为输出。您可以在下面看到数据输出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EZbuy 面罩数据输出

第四步:对于查询大小有限制的 API,您需要使用‘For 循环’来重复检索所有数据

#Define API url
url_search='[https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition'](https://sg-en-web-api.ezbuy.sg/api/EzCategory/ListProductsByCondition')#Define header for the post request
headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}for i in range(0,14000,100):
    time.sleep(max(random.gauss(3,1),2))
    print(i)
    data={
        "searchCondition":
       {"categoryId":0,"freeShippingType":0,"filters":
        [],"keyWords":"mask"},
        "limit":100,
        "offset":i,
        "language":"en",
        "dataType":"new"
    }
    req=s.post(url_search,headers=headers,json=data)
    j=req.json()
    for item in j['products']:
        price.append(item['price'])
        location.append(item['originCode'])
        name.append(item['name'])
        ratingScore.append(item['leftView']['rateScore'])
        quantity.append(item['rightView']['text'].split(' Sold')[0])#Combine all the columns together
output=pd.DataFrame({'Name':name,'price':price,'location':location,'Rating Score':ratingScore,'Quantity Sold':quantity})

下面是在 Ezbuy 中抓取所有面膜数据行的完整代码。我发现总行数是 14k,因此我编写了一个 for 循环来遍历增量偏移量以查询所有结果。这里需要注意的另一件重要事情是,我在每个循环的开始放置了一个随机超时。这是因为我不希望非常频繁的 HTTP 请求损害网站的流量,并被网站发现。

最后,推荐

如果你想抓取一个网站,我建议先用 inspect 在网络部分检查 API 的存在。如果您可以找到对请求的响应,并为您提供所需的所有数据,那么您就可以构建一个稳定而简洁的解决方案。如果在网络中找不到数据,应该尝试使用 requests 或 Selenium 下载 HTML 内容,并使用 Beautiful Soup 格式化数据。最后,请使用超时来避免过于频繁地访问网站或 API。这可以防止你被网站屏蔽,有助于缓解网站的流量。

如果你有兴趣了解更多关于使用 Python 中的 Scrapy 进行网络抓取的知识,可以参考我下面的最新文章

[## Python 中使用 Scrapy 的 Web 抓取

如何检索新加坡的二手车信息

songhaowu.medium.com](https://songhaowu.medium.com/web-scraping-in-scrapy-c2d87796f677)

使用 Selenium、BeautifulSoup、Requests、lxml 和 Scrapy 的网络抓取 Boardgamegeek.com

原文:https://towardsdatascience.com/web-scraping-boardgamegeek-com-using-selenium-beautifulsoup-requests-lxml-and-scrapy-1902d478ecde?source=collection_archive---------48-----------------------

用 3 种不同的方法刮 boardgamegeek.com

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左图:马库斯·斯皮斯克Unsplash 拍摄的照片。右图:罗伯特·科埃略Unsplash 拍摄的照片

这是一个使用 5 种不同工具以 3 种方式进行网络抓取的教程:Selenium、BeautifulSoup、Requests、LXML 和 Scrapy。我们将从同一个网站boardgamegeek.com收集数据。

目标

  1. 抓取大约 20,000 个棋盘游戏,解析数据,然后将数据转换为 CSV 文件。
  2. 学习 3 种不同的 web 抓取方法:Selenium + BeautifulSoup、Python 请求库+ lxml 库和 Scrapy 框架。

关于 Boardgamegeek.com

该网站存储了近 120,000 款桌游的数据,包括游戏元数据、论坛数据、在线市场数据、玩家社区数据等。你可以说 Boardgamegeek.com 是桌游的 IMDB。

该网站提供了一个排名列表。下图是排名前 10 的游戏。你可以在右上方看到,排名列表有 1180 页。每页有 100 个游戏。**截至 2020 年 6 月 16 日,该数据库存储了 118,066 款桌游。**然而,并不是所有的博弈都有完整的信息。**只有 19023 场比赛有排名数据。**排名值是根据玩家的投票计算的。没有排名意味着没有人为这个游戏投票。在这个项目中,我们将只收集 19,023 个有可用排名数据的游戏。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

boardgamegeek.com 十大游戏

BGG 也有 API。每个游戏都有自己的 XML 页面。下面是游戏‘gloom haven’的 XML 文件的部分截图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 BGG API 的游戏“Gloomhaven”的 XML 文件

方法和工具介绍

每个工具或语言库都是为了满足特定的用例而发明的。基于网站设计和数据量/复杂性,利用不同的工具将使工作更容易或更快。

简而言之,web 抓取是请求网页,然后解析 HTML 中包含的数据的过程。

请求阶段:

Python 请求库:

**优点:**是最常用的 Python 库。它简单易学。用 API 连接网站的绝佳选择。

**缺点:**不能用来模拟人类交互,比如点击按钮。

硒:

**优点:**它可以通过模仿人类的动作,如点击和拖动,与网站进行交互。对于用动态 Javascript 编写的网站来说,这是一个很好的选择。

缺点:它需要一个 chrome 驱动程序才能工作,并且必须与你的 Chrome 版本完全匹配。这降低了代码的可移植性。它的速度也很慢。

刺儿头:

**优点:**它速度快,结构化,功能丰富。它使用并行处理来快速收集数据。它拥有能够在同一个工具中抓取和处理数据的工具。

缺点:学习曲线很陡。

解析阶段:

美丽组图:

**优点:**对破损的 HTML/XML 文件非常宽容。简单易学,有据可查。直接从网站而不是 API 文件获取 html 的最佳选择。

**缺点:**比 lxml 慢一点。

Python lxml 库:

**优点:**专门解析 XML。Python 内置 ElementTree 的强大扩展,具有完整的 xpath 特性。好用。

**缺点:**没有刺儿头快。仅适用于 XML 文件。

**刺儿头:**利弊同上请求阶段

项目步骤:

要获得最高排名的 19,023 场比赛,我们需要做如下工作:

第一步:获取前 19,023 个游戏的游戏 id 列表

BGG API 不提供排名信息,所以我们需要先抓取排名页面。然后我们从每个游戏的 URL 中提取 gameID,这样我们就可以使用包含 gameID 的 URL 调用 API 来请求每个游戏的页面。我们需要先抓取排名网页的 HTML。

步骤 2:下载每个游戏的 XML 文件并解析数据

有了 gameID 列表,我们将能够请求每个游戏的 XML 文件,将它们下载到本地计算机,然后将数据解析到数据帧中,并保存到 CSV 文件中。

第三步:试着只用一个工具 Scrapy 来做上面的所有事情

有一种方法可以使用 Scrapy 做上面的所有事情。我们将试一试。

第一步:用硒+美容素刮痧

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左:来自硒。右:来自 https://funthon.wordpress.com/2017/05/21/beautiful-soup-4/

为什么选择这些工具?

我们正在抓取网站的 HTML。网站包含 Javascript,所以需要 Selenium。此外,我们不确定 HTML 是否有任何错误,因为直接来自网页的数据不像来自 API 的数据那样结构化。因此,选择 BeautifulSoup 来解析数据。

设置硒

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置硒

写解析函数

用 Selenium 和 BeautifulSoup 解析函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

游戏排名列表的前 5 行

游戏 id 在 URL 里面。为了下一步,我们需要将它们提取到一个列表中。

步骤 2:使用 Python 的请求库+ lxml 库进行抓取

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左:来自 pipy.org 右:来自 lxml.de

为什么选择这些工具?

我们将通过 BGG API 请求 XML 页面。这是一个简单的任务,不需要类似人类的互动。所以 Python 的请求库可以很好地完成这项工作。在我们获得 xml 文件之后,使用 lxml 解析它们是一个好方法,因为 lxml 专门用于 XML 解析,具有完整的 Xpath 特性和相对较快的速度。

请求 XML API 并将文件保存在本地

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 Python 的请求库下载 XML 文件

编写解析函数

有 47 个标记后来被转换为数据框列。实际的解析代码非常长。下面是一些示例代码,涵盖了 BGG XML 文件中不同的标签情况。

这很好地展示了如何使用 lxml。

使用 lxml 解析函数的示例代码

通过连接步骤 1 和步骤 2 中的两个表获得最终的 CSV

由于 XML 文件没有排名信息或游戏 URL,我们需要连接两个表来获得最终的数据框。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

连接两个数据框

我们需要删除包含重复数据的列,然后将数据框保存到 CSV 文件中。我们的最终数据有 50 列和 19023 行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

删除重复的列并保存到 csv 中

第三步:零碎的框架

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Scrapy.org

为什么用 Scrapy?

Scrapy 是一个强大的抓取框架。我们在步骤 1 和 2 中所做的所有工作都可以通过使用 Scrapy 来完成。此外,它还有许多优点:

  1. 它超级快!Scrapy 使用多线程,这使得它比使用其他一些 Python 库要快得多。例如,第一步中使用硒和 BeautifulSoup 的刮擦需要大约 20 分钟,但 Scrapy 只需要大约 90 秒!
  2. 一切都在一个地方,井井有条,非常适合复杂项目
  3. 与 BeautifulSoup、lxml 解析器和 Xpath 兼容

Scrapy 怎么编码?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

VS 代码中的碎片

1。安装 Scrapy 并创建一个新项目

首先打开命令行终端,键入**“pip install scrapy”**。然后导航到保存项目文件的文件夹,在终端中键入:

BGG scrapy start project(或你的项目名)

2。红区:好有条理!

在终端中创建新项目后,Scrapy 会在项目文件夹中自动生成一组文件。当您在代码编辑器中加载文件夹时,您可以在红色正方形区域中看到文件结构。

Scrapy 用“蜘蛛”来刮。在 spiders 文件夹中,您可以创建一个新的蜘蛛文件,这将是一个 Python 脚本。另一个包括。py 文件为您提供了各种用途的代码结构,有助于您以后的编码,例如将所有自定义设置分组到“settings.py”中,或者用于构建数据管道。为了方便起见,输出文件也组织在这个区域中。

3。黄色区域:一切都以蜘蛛类开始

现在我们将编写蜘蛛 Python 脚本。为了刮擦,所有 Scrapy 需要的是一个蜘蛛类。首先,需要定义两个变量:“name”和“start_urls”。注意他们的名字是预先确定的,你不能用其他名字。“名称”用于稍后运行蜘蛛,start_urls 显示要抓取的第一个页面。

4。绿色区域:实际执行工作的解析函数

在 BS4 和 lxml 中,我们操作的对象是“汤”和“树”。在 Scrapy 中,它是“响应”。Scrapy 的与众不同之处在于它的语法。它只使用。css 和。xpath 作为它的选择器。考虑到新的语法,编写解析函数实际上类似于使用 BS 或 lxml。以下是 Scrapy 文件中的引文:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

XPath 和 CSS 选择器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

css 和 XPath 之间的语法差异

另一个区别是我们如何存储输出。我们需要创建一个字典来存储数据。我们需要用“收益”而不是“回报”。“yield”会将每次迭代的解析数据结果发送到 Scrapy,然后返回到循环中继续解析下一行数据。Scrapy 将保存所有迭代的结果,然后将数据保存到 setting.py 文件中定义的四种文件类型之一:CSV、JSON、JSON Lines 或 XML。

5。蓝色区域:请下一页!

当我们使用其他库时,我们通常定义一个输入页数的函数。而使用 Scrapy,你只需要告诉它的网址开始,然后它会使用一个下一页选择器继续点击下一页,直到结束或到达页面限制你在代码中设置。这是一个自我回调函数,也就是几行代码。

6.是时候坐下来享受了!

最后一步是运行蜘蛛脚本。在终端中,键入

scrapy crawl BG ranks(或你的‘name’变量的字符串)

轻轻一点,就能见证 Scrapy 的超级爬行速度。下图显示了生成的 CSV 文件。短短 90 秒就刮出了 19000 个游戏排名记录!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

生成的 CSV 文件的预览

摘要

在本文中,我们了解了多种 web 请求工具和 XML/HTML 解析工具之间的区别。在现实中,人们通常出于习惯而坚持使用某些工具。然而,了解多种工具可以使你的网络抓取更快,更容易处理复杂的项目。感谢您的阅读!

使用 Selenium 的网页抓取

原文:https://towardsdatascience.com/web-scraping-e-commerce-website-using-selenium-1088131c8541?source=collection_archive---------12-----------------------

抓取网上书店的一个简单例子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Christopher Gower 在 Unsplash 上的照片

在这篇文章中,我们将通过一个电子商务网站的网页抓取过程。我设计了这篇特别的帖子,是为了方便初学者。因此,如果您没有 web 抓取或 Selenium 方面的知识,您仍然可以继续学习。

为了理解网络抓取,我们需要理解 HTML 代码的基础知识。我们也会谈到这一点。

HTML 基础

关于 HTML 基础知识有很多东西要谈,但是我们将把重点放在对网络抓取有帮助的东西上(至少大多数时候)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1,:一个简单的 HTML 代码, : HTML 元素,来源:作者

  • HTML 元素(图 1 右侧)—HTML 元素是开始标签、其属性、结束标签以及它们之间的所有内容的集合。
  • 属性 —是在开始标签中使用的特殊单词,用于控制元素的行为。属性及其值一起用于引用标记及其内容进行样式化。我们将在网络抓取中使用的最重要的属性包括classidname
  • **class** **id** 属性 — HTML 元素可以有一个或多个类,用空格分隔(见上图 1 左)。另一方面,HTML 元素必须有唯一的id属性,也就是说,一个id不能用于引用多个 HTML 元素。

简单的网页抓取

在我们进入电子商务网站的实际抓取之前,让我们抓取下图所示的网站(来自图 1 左边的 HTML 代码)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:现场

从上图(图 2)中,请注意以下几点:

  1. 这是统一资源定位符( URL )。对于这种特殊的情况,定位器指向本地存储的 HTML 代码。
  2. 当您在页面中悬停以识别您感兴趣的元素时,标记为 2 的按钮非常重要。一旦您感兴趣的对象被突出显示,标签元素也将被突出显示。
  3. 这是页面源代码。它只是像图 1 左边的 HTML 代码。您可以通过单击 Ctrl+Shift+I 来检查页面,或者在站点上右键单击并选择选项上可用的检查元素检查来查看该页面源代码。

先决条件

为了进行网页抓取,我们需要selenium Python 包(如果你没有这个包,用pip安装)和浏览器webdriver。为了让selenium工作,它必须能够访问驱动程序。从这里下载与你的浏览器匹配的 web 驱动: ChromeFirefoxEdgeSafari 。下载 web 驱动程序后,保存它并记下路径。默认情况下, selenium会在当前工作目录下寻找驱动程序,因此你可能想把驱动程序保存在 Python 脚本所在的目录下。然而,您没有义务这样做。您仍然可以保存它,并在下面的第 5 行提供可执行文件的完整路径

代码片段 web 抓取的基本示例

  • 1 号线和 2 号线导入必要的库。
  • Line 4 an 5 —定义你下载的 web 驱动的路径,实例化一个 Chrome 驱动。我用的是 Chrome 网络驱动,但你也可以用 Firefox、Microsoft Edge 或 Safari。
  • 第 6 行 —驱动程序在 5 中启动一个 Chrome 会话,并在 6 中获取 url 源。
  • 第 7 行和第 8 行 —这一行暂停 Python 执行 5 秒钟,然后在第 8 行关闭浏览器。暂停是很重要的,这样你就可以对浏览器上发生的事情有一个粗略的了解,而关闭可以确保浏览会话结束,否则我们将会有很多 Chrome 会话窗口。等待页面加载时,睡眠时间也可能非常重要。然而,还有另一种开始等待的适当方法。

定位元素

这是网络抓取最重要的部分。在这一节中,我们需要学习如何通过使用不同的属性来获取 HTML 元素。

回忆 : 网页的元素可以用 **class** **id** **tag** **name** 或/和 **xpath** 来标识。id 是唯一的,但类不是。这意味着给定的 **class** 可以标识多个 web 元素,而一个 **id** 只能标识一个元素。

可以使用以下任何一种方法来标识一个 HTML 元素

  • driver.find_element_by_id
  • 驱动程序.按名称查找元素
  • driver.find_element_by_xpath
  • driver.find _ element _ by _ 标签 _ 名称
  • driver . find _ element _ byclass _ name

可以使用以下任何一种方法来标识多个 HTML 元素(结果是找到的元素列表)

  • 驱动程序.按名称查找元素
  • driver.find_elements_by_xpath
  • driver . find _ elements _ by _ tag _ name
  • driver . find _ elements _ by _ class _ name

注意: **id** 不能用于识别多个元素,因为 **id** 只能识别一个元素。

Snipet 2:定位元素

输出:

Element identified by id: **Content 2 here**
Element identified by class: **Content here**
Element identified by class: **Content 3 here**
Element identified by tag name: **My First Heading**
Element identified by xpath: **My first paragraph.**
  • 第 8 行 —注意container1是标识两个元素的类属性值,drive.find_element_by_class_name返回找到的第一个元素。
  • 为了从 HTML 元素中提取文本,我们使用了.text函数,如上面的代码片段所示。
  • 第 11 行 —通过xpath检查站点元素来定位元素,右键单击与感兴趣的元素匹配的源代码,并复制 XPath,如下图所示(图 3)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3:获取特定元素的 XPath

我们可以识别并循环通过由container1类识别的两个元素,如下所示

代码片段 3:定位多个元素

输出:

Content here
Content 3 here

抓取实际站点

现在,您已经了解了 selenium 的工作方式,让我们继续前进,清理我们应该清理的实际站点。我们将刮网上书店[ 链接 ]。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4:我们想要抓取的网站(来源:作者)

我们将如下进行。

  • 在页面上刮掉每本书的细节。每页 20 本书。利用每张卡片上的网址可以找到每本书的详细内容。因此,要获得这本书的详细信息,我们需要这个链接。
  • 把书的每一页都刮下来。这意味着我们将有一个循环来抓取页面中的每本书,还有一个循环来遍历页面。
  • 从一个页面移动到另一个页面需要修改 URL,这使得预测到任何页面的链接变得很容易。

以下是页面:

显然,我们可以注意到一个模式,它暗示着在页面中循环将会很简单,因为我们可以在循环过程中生成这些 URL。

刮一本书

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5:一本书的元素检查。

在检查网站时,这里是突出显示区域的 HTML 代码(代表一本书)

<article class="product_pod">
 <div class="image_container">
  <a href="the-nameless-city-the-nameless-city-1_940/index.html">
   <img src="../media/cache/f4/79/f479de5f305c2ac0512702cf7155bb74.jpg" alt="The Nameless City (The Nameless City #1)" class="thumbnail">
   </a>
  </div>
  <p class="star-rating Four">
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
  </p>
  <h3>
   <a href="the-nameless-city-the-nameless-city-1_940/index.html" title="The Nameless City (The Nameless City #1)">The Nameless City (The ...</a>
  </h3>
  <div class="product_price">
   <p class="price_color">£38.16</p>
   <p class="instock availability">
    <i class="icon-ok"></i>

        In stock</p>
   <form>
    <button type="submit" class="btn btn-primary btn-block" data-loading-text="Adding...">Add to basket</button>
   </form>
  </div>
 </article>

在我们开始编码之前,让我们做一些观察

  • 有问题的书在article标签里面。值为product_prod的类属性标签
  • 我们在这张卡中需要的是获取 URL,也就是 a标签中的href。要进入href,我们需要向下移动层次如下:class= “product_prod” > h3标签> a标签和href属性的 get 值。
  • 事实上,所有页面中的所有书籍都属于同一个类别product_prod并带有article标签。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6:一本书的详细信息页面(添加了注释以显示我们感兴趣的细节)

片段 4:搜集一本书的细节

让我们浏览几行代码,这样你就能理解代码实际上在做什么

  • 第 16 行到第 18 行— 我们沿着 HTML 代码向下移动,以获得这本书的 URL。一旦我们得到链接,我们在 19 打开。注意 16 定位页面中所有的书,因为所有的书都属于同一个类product_prod,这就是为什么我们对它进行索引(索引 0)以只获得一本书
  • 同样值得注意的是,一本书的星级数是作为p标签的属性而来的。这是这颗星的位置:
<p class="star-rating Four">
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
   <i class="icon-star"></i>
  </p>

这本书被评为 4 星级,但这一事实被隐藏为 class 属性的值。你用get_attribute(class)来获取这样一个信息。在使用文本函数**、提取第行第 24** 行的内容时,您将得到这样一个字符串

star-rating Four

因此,我们必须在使用第 28–38 行中的函数之前拆分字符串,以获得实际的星号。

  • 如果你在 23 中提取文本内容,你会得到这样的字符串
In stock (22 available)

我们需要的只是数字 22,这意味着我们有 22 份拷贝。我们通过第 25 行实现了这一点,在这里我们使用正则表达式来提取数字。

re.findall("\d+","In stock (22 available)")Output:
['22']
  • 在正则表达式中,\d 表示值[0–9 ],而+表示一个字符在该类中出现一次或多次,也就是说,在我们的例子中,我们希望捕获字符串中的任何数字(不考虑数字的数量)。

把所有的书都刮到一页

回想一下上面的第 16 行定位页面中的所有书籍。因此,为了在一页中抓取所有的书,我们需要循环遍历该行中生成的列表,如下所示

片段 5:把所有的书都刮到一页。一页里有 20 本书。

一旦你理解了前面抓取一本书的例子,那么这本书应该很容易理解,因为唯一的区别是我们想要遍历所有的书来提取链接(第 33 行到第 38 行),然后遍历这些链接来提取我们需要的信息(第 42–84 行)。

在这个代码片段中,我们还引入了 try-except 块来捕捉我们想要的信息不可用的情况。具体来说,有些书漏掉了description一节。

我相信您也会喜欢看到 selenium 在您观看时打开页面。尽情享受吧!

抓取所有页面的所有书籍

这里要理解的关键概念是,我们需要循环遍历每一页中的每一本书,也就是说,这里涉及到两个循环。如前所述,我们知道页面 URL 遵循某种模式,例如,在我们的例子中,我们有

我们可以很容易地创建一个 Python for-loop 来生成这样的 URL。让我们看看如何生成前 10 个

代码片段 6:通过修改页面 URL 生成 URL

输出:

[http://books.toscrape.com/catalogue/category/books_1/page-1.html](http://books.toscrape.com/catalogue/category/books_1/page-1.html)
[http://books.toscrape.com/catalogue/category/books_1/page-2.html](http://books.toscrape.com/catalogue/category/books_1/page-2.html)
[http://books.toscrape.com/catalogue/category/books_1/page-3.html](http://books.toscrape.com/catalogue/category/books_1/page-3.html)
[http://books.toscrape.com/catalogue/category/books_1/page-4.html](http://books.toscrape.com/catalogue/category/books_1/page-4.html)
[http://books.toscrape.com/catalogue/category/books_1/page-5.html](http://books.toscrape.com/catalogue/category/books_1/page-5.html)
[http://books.toscrape.com/catalogue/category/books_1/page-6.html](http://books.toscrape.com/catalogue/category/books_1/page-6.html)
[http://books.toscrape.com/catalogue/category/books_1/page-7.html](http://books.toscrape.com/catalogue/category/books_1/page-7.html)
[http://books.toscrape.com/catalogue/category/books_1/page-8.html](http://books.toscrape.com/catalogue/category/books_1/page-8.html)
[http://books.toscrape.com/catalogue/category/books_1/page-9.html](http://books.toscrape.com/catalogue/category/books_1/page-9.html)
[http://books.toscrape.com/catalogue/category/books_1/page-10.html](http://books.toscrape.com/catalogue/category/books_1/page-10.html)

因此,我们可以像下面这样简单地将所有页面中的所有书都刮掉

代码片段 7:抓取所有页面中的所有书籍(50 页,每页 20 本= 1000 本要抓取的书籍)

这个代码片段与上一个代码片段之间的唯一区别是,我们从第 34 行开始循环遍历页面,并且我们还将所有搜集到的信息写入一个名为all_pages.csv的 CSV 文件中。

我们还使用 try-expect 来处理在抓取过程中可能出现的异常。如果出现异常,我们只需退出并关闭浏览器(第 94 行)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 7:生成的 CSV 文件(all_pages.csv)的主视图

结论

Web 抓取是从互联网上收集数据的一个重要过程。不同的网站有不同的设计,因此没有一个特定的刮刀可以用于任何特定的网站。最基本的技能是在高层次上理解 web 抓取:知道如何定位 web 元素,并能够在出现错误时识别和处理错误。当我们在不同的网站上练习网络抓取时,这种理解就产生了。

以下是更多网页抓取示例:

[## 网页抓取:抓取表格数据

在这篇文章中,我们将学习如何使用 Python 抓取 web 数据。简化。

towardsdatascience.com](/web-scraping-scraping-table-data-1665b6b2271c) [## 使用 Python 中的 BeautifulSoup 对新冠肺炎数据进行网络抓取

网络搜集是数据收集最重要的概念。在 Python 中,BeautfiulSoup、Selenium 和 XPath 是…

medium.com](https://medium.com/analytics-vidhya/web-scraping-covid-19-data-using-beautifulsoup-in-python-1bc087918980)

最后,一些网站不允许他们的数据被抓取,尤其是抓取和发布结果。因此,在抓取之前检查站点策略是很重要的。

在 https://medium.com/@kiprono_65591/membership加入媒体以获取媒体上的所有报道。

你也可以在我发文章的时候通过这个链接把文章发到你的邮箱里:https://medium.com/subscribe/@kiprono_65591

一如既往地感谢您的阅读:-)

用于机器学习的网页抓取

原文:https://towardsdatascience.com/web-scraping-for-machine-learning-5fffb7047f70?source=collection_archive---------14-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片作者贝蒂·隆巴顿/ 阿奇博尔德汽车商店——教堂街 / CC BY-SA 2.0

买东西有个普遍规律,“少花钱不如多花钱”。出于个人原因,我需要买一辆二手车,但我并不着急,我有时间考虑并找到最好的交易。

在检查当地的二手车商店时,他们向我展示了价格在 7,000 至 10,000 欧元之间的汽车。这是一大笔钱,所以我想我应该利用我的数据科学技能来找到最好的交易。

数据采集

机器学习项目首先需要的是数据。你可以猜到,西班牙市场上没有二手车数据的数据集,即使有,也会因为价格不断变化而每个月都过时。

我从西班牙最受欢迎的二手车分类广告页面获得数据。出于隐私原因,我将对我使用的页面名称保密。用于搜索的限制如下:

  • **距离我:**不到 100 公里
  • **车龄:**10 年以下
  • **价格:**低于 10.000 欧元

让我们检查一下用于从这些网站收集数据的工具:

  • urllib.request: 使用 Python 标准库中的这个模块来下载网站的 html 代码。
  • BeautifulSoup4: 用这个模块解析 html 代码,找到相关信息。

我们需要下载两件东西,一个页面包含我们限制的可用汽车列表,另一个页面包含汽车的所有信息。

对于汽车列表,一些示例 URL 可能是:

https://www.adspage/cars-search/?location=Barcelona&最高价格=10000 &年起=2010

对于某辆汽车,URL 可能是这样的:

【https://www.adspage/cars/?carid】= 141238

我们使用 urllib 下载并保存这些页面:

from urllib.request import urlopendef download_and_save_page(url, file):
    html_code = urlopen(url).read()#.decode('utf-8')
    f = open(file, 'wb')
    f.write(html_code)
    f.close()
    return html_code

首先,我们删除包含汽车列表的页面,找到所有可用汽车的链接并下载它们。这很容易用 BeautifulSoup 的 find_all 方法完成

links = soup.find_all('a', href=True, class_='car-link')
for link in links:
    print(link['href'])

请记住,分类广告页面通常遵循分页系统,因此在每个页面中,我们都会列出一定数量的汽车(例如 20 辆),为了让所有汽车可用,我们需要了解分页系统是如何工作的。通常我们只需在 URL 上添加一个页码,例如:

https://www.adspage/cars-search/?location=Barcelona&up price = 10000&year from = 2010&page= 7

使用此代码,我们可以创建一个汽车链接数据库,并将它们提供给下载功能,以使我们的 scraper 运行并下载包含所有可用汽车信息的页面。

下一步是处理所有下载的页面并提取汽车的相关信息。所有信息都保存在一个 CSS 文件中。我决定保存的数据是:

  • 广告网址(以便以后我发现有趣的东西时手动检查)
  • 汽车品牌
  • 汽车模型
  • 卖家类型(私人/专业)
  • 价格
  • 描述
  • Kms
  • 出版日期
  • 带图片的 URL 列表

我最终没有使用一些字段(描述和图片),因为它们增加了很多复杂性,但是它们可以包含相关信息,你可以通过查看图片来了解汽车的状况,描述多次谈到汽车的额外功能,可以提供相关信息(发动机损坏的部分)

提取数据主要是通过 BeautifulSoup 的 findfind_all 方法完成的,搜索页面上的相关字段。

soup.find('div', class_='car-price').get_text()

找到正确的类名很重要,我用 Firefox 的开发工具做到了这一点(用 Ctrl+Shift+C 打开检查器)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用检查器选择网站栏

使用检查器,我们选择页面上的所有相关字段,并记录它们的信息。

  • 是元素、

    元素还是什么样的元素?

  • 如何从所有同类元素中识别它们(惟一 id 或惟一类名)

连接所有这些元素,我们可以创建一个包含所有汽车数据的 CSV 文件。在我的例子中,CSV 文件是 5 MB,包含 3487 辆汽车的数据。该数据仅适用于 2019 年 12 月销售的汽车,并且符合我之前描述的搜索标准。获得更老的数据会很有趣,但在网上无法获得。

数据分析

现在到了有趣的部分,我们打开我们的 Jupyter 笔记本,开始分析数据。

#Load data
df = pd.read_csv('data/car_data.csv')

让我给你介绍一下 Pandas Profiling ,这是一个 python 模块,可以从 Pandas 数据帧生成报告。该报告为我们提供了数据集中所有变量的统计数据的快速可视化。

from pandas_profiling import ProfileReport
prof = ProfileReport(df)
prof.to_file('output.html')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

kms 变量的统计信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

公里直方图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在极端值上,我们可以看到输入错误的值(超过一百万公里的汽车)

一些有趣的统计数据是在西班牙销售的最常见的品牌和型号:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

快速可视化之后,我检查了数据集上不太常见的品牌,发现一些汽车品牌只有几个条目。我把它们删除了,因为这么少的数据会让它过度适合这些特定的品牌。

然后对品牌和型号应用一个热编码,最终得到 371 个变量。

使用训练/测试分割来检查 ML 模型的准确性,并使用 RMSE 来评估它们的性能。目标变量是汽车的价格。

我想谈论的车型是 XGBoost,它为 RMSE 和 KNN 提供了最佳价值,我发现这个应用程序很有趣,因为我们在搜索汽车价格时直观地将它与其他在售的类似汽车进行比较。

XGBoost:

import xgboost as xgb
model=xgb.XGBRegressor(random_state=1, n_estimators=5000, learning_rate=0.01)
model.fit(X_train, y_train)sqrt(mean_squared_error(y_val, model.predict(X_val)))

得到了 1.288,39 的 RMSE。请注意,这一幅度相当于欧元误差。这是一个很高的值,请记住,我们只查看价格超过 10.000 欧元的汽车,平均值为 7.226 欧元。

KNN:

from sklearn.neighbors import KNeighborsRegressor
knn = KNeighborsRegressor(n_neighbors=5)
knn.fit(X_train, y_train)sqrt(mean_squared_error(y_val, model.predict(X_val)))

即使我期望从这个模型的直观方法中得到好的结果,它也悲惨地失败了,给出了 7.242 的 RMSE。

结论

我从这个项目中得到的主要收获是,我可以找到与我在附近商店看到的一样好的汽车,并获得更好的价格,能够找到 4,000 至 5,000 英镑范围内的汽车,这是目前最划算的价格。

最后,我买了一辆我非常满意的雪铁龙 C4。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我买的车

我想提到的一些事情是,从分类广告页面提取的数据并不意味着以某一价格发布的汽车最终以该价格售出。大多数情况下,卖家在与买家谈过之后会降低价格,而这并没有反映在网站上。其他卖家可能会开出一个高得离谱的价格,但却无人问津,因为没有人愿意以这个价格购买他们的汽车。所有这些都使算法偏向于给出比真实价格更高的价格。

有很多广告缺少一些信息,有时他们缺少车龄,有时缺少公里数等。其他时候数据格式不佳,卖家没有在适当的字段中引入数据,最终导致数据点缺少大部分功能,但是他们在描述中以自己的格式引入所有这些数据,这是算法无法解释的。所有这些都会影响数据的质量,从而影响我们的结果。

改善这种分析的其他方法包括使用 NLP 从描述中添加信息,卖家有时会谈到汽车中包含的额外功能,有时会谈到汽车的发动机或状况,有时会说有机械问题。我相信从这些描述中可以提取出许多有趣的信息。另一种方法是使用计算机视觉从贴有广告的汽车图片中获得额外的信息,有时你可以看到汽车受到了一些影响,有时你可以看到汽车的内部,有时没有图片,这是一个不好的迹象。

这些仅仅是可以持续改善这个项目结果的许多途径中的一部分,然而在买了车之后,我感觉不到继续在这个项目上工作的动力。

Web 抓取:如何用 Selenium 处理日历

原文:https://towardsdatascience.com/web-scraping-how-to-handle-a-calendar-with-selenium-862ce689a7d7?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由贾兹敏·奎诺尔Unsplash 拍摄

学习使用 Python 工具来抓取 web

❝ … *时间过得很慢,但却过得很快…*❞—·爱丽丝·沃克

我坐在我最喜欢的沙发上看电视。嗯,说实话,我在频道冲浪。

也许没有什么有趣的东西可看,或者我太分心去想我在工作中不能解决的问题。

我把视线从电视上移开一分钟来回答一条信息。当我回头看屏幕时,它就在那里。我反复看的电影之一。

等一下。等等,博士,你是说你用一辆德罗宁造了一台时光机?马蒂·小飞侠说

"依我看,如果你要把时间机器做成一辆汽车,为什么不做得有点风格呢?”—医生回答

时间旅行。很多电影都在讲这个话题。我相信这是朋友们深夜闲聊的话题。

起初,我很高兴找到这部电影,因为我非常喜欢它。但后来,它提醒了我一个我无法解决的问题。

我并没有试图建造一台时间机器或者进行时间旅行。

我只是想在一个特定的网站上搜集历史数据。这个页面总是有相同的网址。但是当你从日历中选择不同的日子时,内容就变了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果选择新的日期,内容将会改变。但是,URL 地址将保持不变。

我当时真的很挣扎。我以前用 Scrapy 制作过刮刀(如果你想了解更多,请阅读我的 以前的帖子 )。

但是我知道这个 Python 框架有一些限制。其中之一是处理 Javascript。

我决定停止浏览频道。我开始阅读,突然,我找到了解决办法:硒。

S elenium 是一款方便的网络浏览器自动化工具。它能够打开选择的浏览器并模仿人类行为。

这意味着它可以执行点击按钮、填写表格或在网站上搜索信息等任务。很酷,对不对

安装包也非常容易。我们需要使用正常的 pip 语法:pip install selenium

但是还有一个额外的步骤需要完成。我们需要下载 Chrome 驱动 **。**这个 WebDriver 是一个用于自动化测试的开源工具,它提供了导航到网页、用户输入、JavaScript 执行等功能。

注意下载与你的浏览器版本兼容的 ChromeDriver 版本

开始编码吧!

首先,我们将导入我们需要的模块。

  • 使用正则表达式的模块re
  • BeautifulSoup从网站上提取数据
  • selenium.webdriver启动浏览器
  • selenium.webdriver.[ActionChains](https://www.selenium.dev/selenium/docs/api/py/webdriver/selenium.webdriver.common.action_chains.html)实现鼠标移动等低级交互的自动化。

之后,我们需要创建一个新的 google chrome 实例。

我们将使用webdrive.Chrome()传递指向我们下载 ChromeDrive 的位置的 确切路径 作为参数。

然后,我们使用.get()方法将所需的 URL 作为参数传递。

如果我们运行这个,我们会看到一个新窗口打开,显示图例Chrome is being controlled by automated test software

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

刮网站首先要做的是了解网站的结构。特别是,我们如何指示硒,如何选择不同的日期。

让我们检查网页 HTML 代码,重点是日历元素。

我们想取消过去两年网站的内容。这里有许多可以遵循的策略。

我们将指示 WebDriver 点击 n 次前一个<按钮。所以如果我们在March 2020想去March 2018,就要按 24 次按钮。

让我们重温一下关于 XPath 的知识。

XPath代表 XML 路径语言。跟网页抓取有什么关系?我们将学习如何识别 HTML 元素。但是现在出现的问题是我如何向刮刀指出元素?答案是 XPath。

XPath 是一种特殊的语法,可用于浏览 XML 文档中的元素和属性。此外,它将帮助我们获得某个 HTML 元素的路径并提取其内容。

让我们看看这个语法是如何工作的

/用于向前移动一个代,tag-names给出哪个元素的方向,[]告诉我们选择哪个兄弟姐妹,//查找所有后代,@选择属性,*是通配符,表示我们想要忽略标签类型?

如果我们看到下面的 XPath:

Xpath = '//div[@class="first"]/p[2]'

我们会理解,从所有(//)带有class"""(div[@class="first"])的div元素中,我们想要第二个([2])段落(p)元素。

幸运的是,web 浏览器有一种简单的方法来获取元素的 XPath。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们复制元素的 XPath 并将其传递给函数[.find_element_by_xpath()](https://selenium-python.readthedocs.io/locating-elements.html)

现在,是时候告诉 WebDriver 去点击这个元素了。我们通过从ActionChains()链接以下函数来实现:

  • .click()即会点击元素
  • .perform()即会执行动作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

web 驱动程序应该如何按时返回

一旦日历回到 24 个月前,我们应该告诉 selenium 每天点击并抓取内容。

为了理解如何指向日元素,让我们再次检查网站。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看 HTML 代码。我们可以观察到不同的日期属性被赋予了不同的类值。

以灰色出现的日子,有day disable类。黑色的那一天,有类别day,选择的那一天(当前日期)有类别active day

最后一个类对于当前日期属性是唯一的,所以我们可以用它从日历中选择当前日期。

首先,我们将列出所有具有包含单词day的 class 属性的元素。

这一次,我们将使用函数[.find_element_by_class_name()](https://selenium-python.readthedocs.io/locating-elements.html)指向这些元素。当我们想通过类属性名定位一个元素时,这很方便。

一旦我们有了那个列表,我们将循环这个列表。对于我们找到的每个元素,我们获取它的属性并询问它是否严格等于day。如果是,我们会告诉 webdriver 点击它。

我们将等待 5 秒钟,以便可以加载网站。

之后,我们将使用BeautifulSoup浏览网站。在这里,我们可以插入任何代码来删除网站的内容。我们可以使用find()findall()方法。

一旦我们删除了内容,循环将移动到找到的下一个day元素。

请注意,我们每个月都需要这样做。所以一旦这个月的所有元素都循环了,我们就需要进入下个月。该过程与我们对上一个按钮所做的完全相同。

现在,我们将这个脚本保存在一个文件中(例如selenium_script.py))。为了运行脚本并开始废弃,我们打开一个新的终端窗口。

我们需要转到文件所在的文件夹,然后键入:

python3 selenium_script.py

之后会弹出一个 Chrome 窗口。开始自动点击不同的日期。我们会看到这样的情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

网络驱动程序将模拟选择不同的日期

一旦所有的网站和日期都被废弃,我们将在终端中看到以下消息:

Process finished with exit code 0

这意味着一切顺利,没有遇到错误。

如果我们指定了一个文件来保存网站的内容,我们现在可以转到该文件并检查废弃的内容。

现在,轮到你用 Selenium 刮网站了!

如果你想了解更多关于这个话题的内容,请查看以下帖子:

使用 Selenium 的网页抓取简介

使用 Selenium-Python 进行网页抓取

3 分钟内完成网页抓取

原文:https://towardsdatascience.com/web-scraping-in-3-minutes-1c37830a29c1?source=collection_archive---------24-----------------------

简介:

数据,或任何种类的信息,是 21 世纪最宝贵的东西之一。数据是如此强大,以至于可以在许多方面利用它,例如预测未来的销售趋势以获取利润,在医疗保健行业中用于早期诊断结核病,从而挽救患者的生命,等等。因此,从不同来源提取有价值的数据是数据科学家应该掌握的关键技能之一。

在本文中,我们将学习如何使用 python 中的不同库从网站中提取数据。我们将使用 shorts 网站中的 来提取与板球、羽毛球和网球等不同运动相关的新闻文章。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Florian OlivoUnsplash 上拍摄

步骤 1:导入相关库

步骤 2:用漂亮的汤发出 Web 请求并解析

我们来看看某一类新闻的源代码这里

进入这个网页后,我们将看到不同的新闻,让我们集中在一个特定的新闻和它的源代码提取使用美丽的汤。

我们可以在右边看到新闻文章及其各自的源代码。我们将使用请求库和使用。在 url 上获取()以从网页访问 HTML 脚本。然后,我们将使用漂亮的 soup 库来解析 python 中的 HTML 语言。然后,进一步根据我们想要提取的信息类型,我们可以使用不同的 html 标签过滤信息,如使用

、。find()函数。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在完成上述步骤并解析 HTML 语言后,这个特定新闻的部分如下所示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这种情况下,我们可以看到文章的标题位于这个类下-<**div class = " news-card-title news-right-box ">。**我们可以进一步看到标题存在于带有 attributes= "itemprop “和” headline "的< span >标签中。这可以通过使用。find()函数。

news1=soup.find_all('div', class_=["news-card-title news-right-box"])[0]title=news1.find('span',attrs={'itemprop':"headline"}).stringprint(title)We get the following output given below-Shuttler Jayaram wins Dutch Open Grand Prix

同样,如果我们要访问新闻内容,它位于这个类 **<下 div class = " news-card-content news-right-box ">。**我们可以进一步看到新闻的主体在于带有 attributes= "itemprop “和” articleBody "的< div >标签。这可以通过使用。find()函数。

news1=soup.find_all('div', class_=["news-card-content news-right-box"])[0]content=news1.find('div',attrs={'itemprop':"articleBody"}).stringprint(content)Indian Shuttler Ajay Jayaram clinched $50k Dutch Open Grand Prix at Almere in Netherlands on Sunday, becoming the first Indian to win badminton Grand Prix tournament under a new scoring system. Jayaram defeated Indonesia's Ihsan Maulana Mustofa 10-11, 11-6, 11-7, 1-11, 11-9 in an exciting final clash. The 27-year-old returned to the circuit in August after a seven-month injury layoff.

以类似的方式,我们可以提取任何信息,无论是图像、作者姓名、时间等。

步骤 3:构建数据集

让我们为 3 个不同的类别实现这一点,并将所有的文章、各自的内容和类别存储在一个数据框中。在本节中,我们将使用三个不同的 Url,然后我们将对每个 Url 执行相同的过程,并将所有文章、其内容、类别存储到一个列表中。

输出-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论:

我们可以看到使用漂亮的 soup 库在 python 中实现 web-screwing 是多么容易。使用这种技术,我们可以轻松地收集优秀的数据,以便开始任何数据科学项目。

感谢阅读!

如果你喜欢我的工作,想支持我。支持我的最好方式就是在媒体上关注我。

使用 CSS 选择器在 R 中抓取网页

原文:https://towardsdatascience.com/web-scraping-in-r-using-rvest-and-selectorgadget-5fc5124547e?source=collection_archive---------17-----------------------

又名当客户做空你时如何获得更多数据

R 中的 Web 抓取比你想象的要容易——像 CSS 选择器和抓取库这样的工具可以快速完成工作。事实上,“最困难”的部分是识别元素的 CSS 路径,但是我将向您展示如何轻松地到达那里!

我曾经有一个客户(美国的一家商业保险经纪公司),他想要一个数据科学解决方案来提高他们的销售和转化率。看似直白?客户给我们的数据非常少——只有客户的唯一许可证号、销售结果(保单状态)和保费价格。

我开始在网上寻找相关数据的其他来源。客户的唯一许可证号是由美国政府交通部(DOT)颁发的 DOT 号。联邦汽车运输安全管理局(FMCSA)对与 DOT 编号相关的车辆和司机进行例行检查,并在其网站上发布报告。这是公共信息,不需要登录/密码即可访问。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个点号的 FMCSA 安全报告部分截图。

像报告的撞车次数、车辆/驾驶员危险率这样的数据可以帮助优化保单保费,以增加客户购买保单的几率。

获得这一点需要 3 个步骤:

  1. 识别感兴趣的元素,并获取它们的 CSS 路径。
  2. 将抓取的元素压缩成一个数据帧。
  3. 清理输出,然后将其连接到现有数据(由客户端提供)。

包和工具

我使用了 rvest 库和 CSS 选择器 SelectorGadget 来抓取网页。该工具可以作为浏览器的扩展下载,这样可以更容易地确定网页上每个元素的 CSS 路径。

定义 URL 和网页

我开始使用单点编号报告。报告的 URL 包含点号本身,这对于以后遍历点号列表非常有用。

检查感兴趣的元素

首先,我想收集每个点号的注册地址,以及它们拥有的驱动程序的数量。我需要这些元素的 CSS 路径——这告诉 scraper 要抓取的元素的精确位置。一个地址,如果你愿意的话。

打开 SelectorGadget 扩展——浏览器底部会出现一个框。选择屏幕上列出地址的区域。该工具将在屏幕上突出显示许多其他元素——此时它已经选择了 67 个其他元素。只需点击黄色元素,直到只剩下绿色的地址部分。(这只需要 3 到 4 次点击)。额外元素的每次“取消选择”都会将 CSS 路径更新到地址的精确位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在 address 元素的 CSS 路径可用了。截图自此处

现在“地址”是唯一突出显示的元素。红框里看似乱码的文字就是这个元素的 CSS 路径,这就是我们要传递给 rvest 去刮取的东西。

类似地,要获得驱动程序数量的 CSS 路径:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

截图自此处

将 CSS 路径传递给 rvest:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们有产出了!它必须被清洗,很多,但它的工作!

现在我将为所有的点号刮取更多的元素。

遍历所有的点号

我利用了 URL 反映点号的事实-https://ai . fmcsa . DOT . gov/SMS/Carrier/2844805/complete profile . aspx

我创建了一个包含每个点号的 URL 的向量。

现在,刮!

最后一步将所有不同的元素组合成一个数据帧,称为 fmcsa_data。这将需要一些时间,取决于你有多少迭代。我建议把电脑插上电源,给自己泡杯茶。

清洁数据框

产生的数据帧并不美观——大量无关的文本隐藏了相关的信息。还有一些缺失的数据——FMCSA 网站还没有一些点号的报告,所以什么也没有收集到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对数据的进一步观察也揭示了许多不可见的特征。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

清理这些数据是一个简单的过程:

  1. 删除空行。将每一列从因子转换为字符类型。
  2. 删除地址的不可见字符。
  3. 仅提取除地址、姓名和安全等级之外的所有列的数字。

清理后的 dataframe 就懂事多了!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是我们从成千上万份报告中整理出来的简洁明了的数据框架。

我是帕洛阿尔托 ScoreData 公司的数据科学家。我非常热衷于有效的沟通——我热衷于将统计数据转化为对业务友好的、可操作的见解。我想让这个博客成为一个分享我一路走来所学到的一些东西的空间,所以一起来吧!

https://www.linkedin.com/in/namrata-date/

使用 Selenium 从 Indeed.com 收集招聘信息

原文:https://towardsdatascience.com/web-scraping-job-postings-from-indeed-com-using-selenium-5ae58d155daf?source=collection_archive---------21-----------------------

使用 NLP 和神经网络的工作工资预测项目的第一部分

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

戴安娜·奥雷在 Unsplash 上的照片

我希望在我的数据科学之旅的早期就知道如何进行网络搜集!这是一个非常方便的工具,打开了很多酷项目的大门。对于刚接触编码的人来说,这听起来可能有点难以接受。但是相信我,这比你想象的更容易,更直观!

这篇文章是我最近完成的一个更大项目的第一部分**,该项目旨在预测数据相关领域(数据科学、商业智能、分析等)的工作薪水。)通过文本分类和深度学习。为了构建模型,我需要收集大量的职位发布以及与职位发布相关的工资。**

因此,我决定从 Indeed.com 那里刮乔布斯。我正在使用的 API 叫做 Selenium 。Selenium 广泛用于 web 自动化,它实际上非常容易安装和使用。您可以像这样安装 selenium:

pip install selenium

Selenium 需要一个驱动程序来连接 web 浏览器。你可以在这里找到 Chrome,Edge,Firefox 或者 Safari 的驱动。下载后,确保驱动程序与您的浏览器应用程序在同一路径。

进口硒

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC#specify driver path
DRIVER_PATH = '/Users/bonniema/Desktop/chromedriver'
driver = webdriver.Chrome(executable_path = DRIVER_PATH)

浏览页面

driver.get 方法将导航到 URL 给出的页面。执行此操作后,您将看到一个网页打开,表明 web 浏览器正在被控制。

driver.get('[https://indeed.com'](https://indeed.com'))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一步是找工作。使用 Selenium 的一个好处是可以通过 id、名称或者 xpath 来识别一个项目或者按钮。在这种情况下,我想单击“查找工作”按钮。如果你检查页面,你可以看到 HTML 的“寻找工作”按钮。正如下图中突出显示的,我们可以看出按钮元素在一个<按钮>标签中,该标签在一个分隔线< div >下,该分隔线在 id="whatWhereFormId "的表单下。虽然您可以有不同的方法来标识按钮,但我将使用该表单 ID 来标识按钮。最好使用一个足够唯一的项目或属性(比如类),但是不要随时间而改变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

initial_search_button = driver.find_element_by_xpath
(‘//*[[@id](http://twitter.com/id)=”whatWhereFormId”]/div[3]/button’)initial_search_button.click()

关闭弹出窗口

单击“搜索”按钮后,会显示一个弹出窗口。我们可以用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

close_popup = driver.find_element_by_id("popover-close-link")
close_popup.click()

执行高级搜索

在稍微摆弄了一下页面之后,我知道我想要执行高级工作搜索,在这里我可以指定搜索术语并设置每页显示的工作数量。查看 HTML 结构,看起来“高级工作搜索”被包装在一个标签中。一种方法是使用“contains”通过文本定位 xpath。

advanced_search = driver.find_element_by_xpath("//a[contains(text(),'Advanced Job Search')]")advanced_search.click()

另一种方法是右键单击该路径,检查是否可以直接复制 XPath。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

似乎这个 XPath 不够通用,不能在这里使用。

//*[[@id](http://twitter.com/id)="jobsearch"]/table/tbody/tr/td[4]/div/a

输入搜索值

接下来,我们需要向搜索表单发送值。下面这段代码发送位置关键字,设置显示限制,并按日期对结果进行排序

#search data science 
search_job = driver.find_element_by_xpath('//input[[@id](http://twitter.com/id)="as_and"]')
search_job.send_keys(['data science'])#set display limit of 30 results per page
display_limit = driver.find_element_by_xpath('//select[[@id](http://twitter.com/id)="limit"]//option[[@value](http://twitter.com/value)="30"]')
display_limit.click()#sort by date
sort_option = driver.find_element_by_xpath('//select[[@id](http://twitter.com/id)="sort"]//option[[@value](http://twitter.com/value)="date"]')
sort_option.click()search_button = driver.find_element_by_xpath('//*[[@id](http://twitter.com/id)="fj"]')
search_button.click()

找到工作卡,立刻获得所有信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的目标是从一个工作卡中获取职位、公司名称、城市和公司评级、工资(如果有的话)以及工作 url,然后迭代该页面上的所有工作卡。然后到下一页去刮更多的数据。

下面这段代码使用 for 循环遍历每页中的工作卡,并将相关信息保存在一个列表中。

现在繁重的提升部分已经完成了!

从个人网址获取职位描述

descriptions=[]
for link in links:

    driver.get(link)
    jd = driver.find_element_by_xpath('//div[[@id](http://twitter.com/id)="jobDescriptionText"]').text
    descriptions.append(jd)

把它们放在一个数据框里!

df_da=pd.DataFrame()
df_da['Title']=titles
df_da['Company']=companies
df_da['Location']="Palo Alto, CA"
df_da['Link']=links
df_da['Review']=reviews
df_da['Salary']=salaries
df_da['Description']=descriptions

网页抓取—朝鲜棒球组织(KBO)

原文:https://towardsdatascience.com/web-scraping-korea-baseball-organization-kbo-40bf6210a267?source=collection_archive---------65-----------------------

抓取网页,创建一个体育场的地图,球队发挥和可视化击球统计

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

南韩蚕室棒球场(照片由晓星崔Unsplash 上拍摄)

大约一周前,ESPN 开始转播朝鲜棒球组织(KBO)的比赛,自 3 月以来首次提供现场体育比赛。渴望现场表演的粉丝们,它提供了一些东西。除非你是丹()那样的铁杆球迷,否则你不会对 KBO 队或球员很熟悉。因此,我尝试用数据科学和 Python 编程来介绍 KBO。

KBO 队在哪里比赛?

KBO 是南韩最高的职业棒球联盟。它从 1982 年开始有六个队参加比赛,后来扩大到 10 个队。这是十支 KBO 球队和他们主场比赛的城市。

  • 斗山熊队(首尔)
  • 韩华鹰队(大田)
  • 起亚老虎队(光州)
  • 基武姆英雄(首尔)
  • KT Wiz(水原)
  • LG 双胞胎(首尔)
  • 乐天巨人(釜山)
  • 数控恐龙(昌原)
  • 三星雄狮(大邱)
  • SK 双足飞龙(仁川)

废弃 Wiki 页面以检索体育场名称

KBO 维基页面提供了几个表格,其中一个包含球队名称和他们比赛的体育场。我们可以使用 Pandas 的 read_html 废弃这些表。Pandas 的 read_html 提供了一种将表读入 DataFrame 对象列表的简洁方法。

[## KBO 联赛

KBO 联赛(韩语:KBO 리그),原名韩国棒球锦标赛(韩语:한국야구선수권대회;罗马化…

en.wikipedia.org](https://en.wikipedia.org/wiki/KBO_League)

wikipage = "[https://en.wikipedia.org/wiki/KBO_League](https://en.wikipedia.org/wiki/KBO_League)"
result = pd.read_html(wikipage)
result

检查结果后,我们可以看到第三个表包含球队、城市、体育场、容量和加入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在选择了第三个表并用第一行替换了标题之后,我们有了一个显示体育场信息的熊猫数据帧。

#df = third table
df = result[2]#change top row to header
df.columns = df.iloc[0]
df = df[1:]
df

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从体育场名称获取地理编码

使用 geopy 的地理编码器,我们可以只传递体育场的名称来检索纬度和经度。我不得不把“大田汉巴特棒球场”替换为“韩华生命鹰公园”,因为地理定位器无法识别前者。

def geolocate(loc):
    try:
        loc = geolocator.geocode(loc)
        # Return latitude and longitude
        return (loc.latitude, loc.longitude)
    except:
        # Return missing value
        return np.nandf['Geolocate'] = df['Stadium'].apply(geolocate)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建地图

在我们检索了每个体育场的纬度和经度之后,我们可以使用 yellow 来创建球队比赛的地图。

import folium
from folium.plugins import MarkerCluster

#empty map
m= folium.Map(tiles="cartodbpositron")marker_cluster = MarkerCluster().add_to(m)for i in range(len(df)):
        lat = df.iloc[i]['Latitude']
        long = df.iloc[i]['Longitude']
        radius=10
        popup_text = """Team : {}<br>
                     City : {}<br>"""
        popup_text = popup_text.format(df.iloc[i]['Team'],
                                   df.iloc[i]['City']
                                   )
        folium.CircleMarker(location = [lat, long], radius=radius, popup= popup_text, fill =True).add_to(marker_cluster)#show the map
m

五个队在汉城或附近比赛,另外五个队在韩国南部比赛。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

周围的首尔区域被缩放,并且显示了带有球队名称和城市的 folium 标记。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

刮 KBO 统计

这篇文章(网络搜集 NBA 数据)提供了一个从篮球参考网站搜集 NBA 数据的极好的教程。类似地,我们可以删除 Baseball-Reference.com 的棒球统计数据,因为该网站提供了包括 KBO 在内的全面的球队和球员统计数据。

下面的代码块将 2020 年 KBO 的击球统计数据抓取到一个熊猫数据帧中。

然而,抓取的熊猫数据帧的数据类型是对象。我们可以将非对象类型转换成数字,以便以后可视化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们现在可以可视化团队本垒打或任何其他你想要的统计数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

摘要

总而言之,从维基百科中抓取一个表格,然后用于创建一个地图,从棒球参考中抓取当前击球数据。希望这能提供一些有价值的信息。下面你可以找到更多的资源,如如何观看。希望你也喜欢这些现场棒球比赛!

[## ESPN 时间表上的 KBO,如何观看,朝鲜棒球联盟的球队等等

韩国棒球组织的常规赛季正在进行中,这意味着是时候进行一些现场棒球比赛了——

www.espn.com](https://www.espn.com/mlb/story/_/id/29136672/kbo-espn-schedule-how-watch-teams-korea-baseball-league-more) [## MyKBO.net

致力于韩国棒球组织(KBO)和韩国棒球的一个地点。韩国棒球时间表,统计数据…

www.mykbo.net](http://www.mykbo.net/) [## 在电视上看韩国棒球?让我们来帮忙

有很多蝙蝠翻转,但吐痰是不允许的。这里有一批球员要留意谁可能会登陆…

www.nytimes.com](https://www.nytimes.com/2020/05/05/sports/baseball/coronavirus-baseball-korea-opening.html)

网页抓取—制作您自己的数据集

原文:https://towardsdatascience.com/web-scraping-make-your-own-dataset-cc973a9f0ee5?source=collection_archive---------21-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片鸣谢:巨蟒请求巨蟒美瞳

尽管有许多资源可以获得所需的数据集,但最好还是有一个自己创建的数据集。在当前新冠肺炎的场景中,我发现了关于worldometers.com的有趣数据。它显示了一个包含案例总数、已执行测试总数、已关闭案例总数等的表格。该表每天更新。

出于好奇,我想在自己的数据集中包含这些新冠肺炎数据。在基本 python 库、pandas、numpy 和 BeautifulSoup 的帮助下,我决定将这些数据收集到我自己的数据集中。由于我成功地创建了数据集,我想与大家分享我的故事。因此,我将带你浏览我的笔记本。

网页抓取是从网页中收集信息的过程

当手动收集大量数据时,需要大量的时间和精力。如果要收集的数据来自定期更新的网页,这将是非常激烈的。因此,最好有一个脚本,它可以自动从网页中提取数据,并以所需的格式存储。

你所需要的是一个 python 包来解析来自网站的 HTML 数据,以表格形式排列它,并做一些数据清理。有几十个软件包可以完成这项工作,但我的故事继续与 BeautifulSoup。

美丽组图

它是一个 python 库,使我们能够从网页中抓取所有内容。假设有一个网页包含一些有趣的信息,但没有提供直接下载数据的方法。BeautifulSoup 提供了一套工具来从网页中提取数据,并定位隐藏在 HTML 结构中的内容。

让我们开始创建自己的数据集……

第一步:安装所需的软件包

您需要 requests 包,它允许您使用 Python 发送 HTTP 请求。如果你已经预装了,你只需要导入它。否则,您需要使用 pip 安装程序来安装它。

pip install requests
pip install beautifulsoup4

我使用 Python 内置的 HTML 解析器将网站输入的文本数据转换成复杂的解析树,可以进一步处理得到所需的数据。如果你想使用不同的解析器,在这里你可以找到一个助手。

一旦你安装了所有的包,把它们导入到你的脚本中。

import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup

第二步:BeautifulSoup 构造器

BeautifulSoup 构造函数接受 2 个输入参数

  • 字符串—它是您要解析的标记。这个标记是使用 python requests包的 get()方法获得的。这个 get()方法返回包含服务器对 HTTP 请求的响应的requests.Response()对象。此外,此响应对象的 text 方法获取响应的内容。整个字符串作为 BeautifulSoup 构造函数的第一个参数传递。
  • 解析器—它是您想要用来解析标记的方法。您需要提供解析器的名称。我使用了 python 内置的 HTML 解析器。
website='[https://www.worldometers.info/coronavirus/#countries'](https://www.worldometers.info/coronavirus/#countries')
website_url=requests.get(website).text
soup = BeautifulSoup(website_url,'html.parser')

好了…在 3 行代码中,您将所需网页的所有内容都输入到了笔记本中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:开发者工具中的信息

开发者工具中来自元素标签(红色标记)的所有 HTML 文本都将存储在 BeautifulSoup 对象soup中。如上图 1 所示,当你在元素标签中滚动特定行时,它会在网站的实际表格中高亮显示相应的单元格。

第三步:熊猫数据框

为了制作 Pandas DataFrame,我们需要将对象soup中的所有文本数据转换成表格格式。在上面的图片 1 中,我还标记了 3 个绿色矩形。这些是你需要在汤里找到的术语。

让我们简单理解一下,这些术语是什么意思—

  • <tbody>:指定网页上的表格。
  • <tr>:指向该表中的特定行。
  • <td>:指向该行的特定单元格。

在 python 脚本中,您将使用 object soup的方法在解析的文本中查找这些术语。

my_table = soup.find('tbody')

变量my_table将包含网页上的表格,但仍然是 HTML 格式。它包含另外两个术语<tr><td>,分别指向单独的行和单元格。在下面的代码中,您将把这个my_table转换成包含列和值的实际表格。

请注意,下面这段代码是 2020 年 4 月写的。稍后,请检查网站上的列的顺序,并相应地修改代码。

table_data = []for row in my_table.findAll('tr'):
    row_data = [] for cell in row.findAll('td'):
        row_data.append(cell.text) if(len(row_data) > 0):
        data_item = {"Country": row_data[0],
                     "TotalCases": row_data[1],
                     "NewCases": row_data[2],
                     "TotalDeaths": row_data[3],
                     "NewDeaths": row_data[4],
                     "TotalRecovered": row_data[5],
                     "ActiveCases": row_data[6],
                     "CriticalCases": row_data[7],
                     "Totcase1M": row_data[8],
                     "Totdeath1M": row_data[9],
                     "TotalTests": row_data[10],
                     "Tottest1M": row_data[11],
        }
        table_data.append(data_item)

现在您得到了table_data,它实际上是一个包含列和值的表。这个表现在将被转换成一个熊猫数据帧df

df = pd.DataFrame(table_data)

注意,在这个数据帧中,所有的列都是 object 类型。此外,这些物品中还有一些不需要的字符,如 /\n|+。所有常用的数据清理过程现在都可以在上面使用。

根据个人需求,您可以从原始数据帧中提取不同的列和行,根据需求对其进行清理和转换。

这种数据的收集、评估、清理和转换被称为数据争论过程。这里有一个关于数据争论过程的有趣的可视化快速阅读。

[## 数据争论—从原始到干净的转变

简单的三个字的解释

towardsdatascience.com](/data-wrangling-raw-to-clean-transformation-b30a27bf4b3b)

第四步:导出到 Excel

然后,可以使用 pandas 将经过清理和转换的最终数据帧导出到 excel。

df.to_excel('Covid19_data.xlsx', index=True)

总之,您为新冠肺炎创建了自己的数据集。

您还可以通过抓取不同的网页来创建多个数据集,并最终将所有数据集组合在一起。想了解更多关于组合不同数据集的信息吗??

在这里,我有一个关于 Python Pandas 中合并选项的简单的 4 分钟阅读。你需要记住的只是下面文章的最后一张图,解释了所有类型的数据集 join 操作。

[## 加入表格

了解 Python pandas 中的 merge()和 concat()

towardsdatascience.com](/join-the-tables-ab7fd4fac26b)

使用 Matplotlib Python 库可以很容易地可视化这种自行创建的数据集,并且可以很容易地定制可视化,如下文所述。

[## matplotlib——一个分层的数据可视化库

使用 Matplotlib 了解地块定制的简单方法

medium.com](https://medium.com/analytics-vidhya/matplotlib-a-layered-data-visualization-library-870d992ff4b5)

通过我的故事……

我带你通过 4 个简单的步骤将一个网页抓取到一个 excel 表格中。我演示了如何使用简单易用的 BeautifulSoup 包抓取网页,并将这些数据转换成熊猫数据帧。完整的笔记本可以在我的 Github 个人资料中找到。

这里有一些资源,可以帮助你解决这个问题

欢迎您随时提出反馈意见,并通过 LinkedIn 与我联系!!!

网络抓取 NBA 2k 数据

原文:https://towardsdatascience.com/web-scraping-nba-2k-data-d7fdd4c8898c?source=collection_archive---------40-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片来自 Pixabay,作者为 Rochigb

这是一个学习宝贵的数据科学技能的实践示例

并不是所有值得分析的数据都打包好了(我正看着你呢,Kaggle)。最终,在您的数据科学之旅中,您会发现自己在寻找一个并不存在的数据集。是吗?

进入:网页抓取。

网络抓取是从网页中获取数据的一个非常有价值的工具。抓取不是手动收集信息,而是自动获取和存储数据。它涉及一个网页:

  • 从语法上分析
  • 重新格式化
  • 复制到电子表格中

入门

此时,您可能想知道可以使用哪些库来开始 web 抓取。有多种选择,但最常见的库和框架是:

  • 要求
  • 美味的汤
  • Scrapy
  • LXML

在本教程中,我们将使用以下库:

  • 熊猫
  • 要求
  • 美丽的声音
  • 有平面的

第一步是导入上面的内容:

查看网页

网站包含许多不同的元素,因此检查网页以了解 python 代码应该以哪些元素为目标非常重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

像 HoopsHype 这样的网站定期收集体育数据并发布。

我们将关注 2016 年 NBA 2K 收视率。这将是基于篮球评级的数据可视化或机器学习项目的伟大先驱。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

检查一个网站将揭示其源代码

要轻松检查网站,请将光标放在包含数据的元素中或突出显示该元素。然后,右键单击并选择“Inspect”来访问站点的源代码。如果数据存储在一个表中,您将会知道,因为像表行()和数据单元格()这样的标记不是实际的元素。

下面是一个数据单元格标签示例:

<td style=”text-align:center;”>71</td>

下面是一个表格行标签的例子:

<tr style=”font-size:11px;”></tr>

解析网页

解析的第一步是获取你想要抓取的网页的 url。接下来,使用 requests get()方法查询页面。这将返回一个请求。响应对象。

让我们创建一个漂亮的对象。这将表示已解析的页面。使用“美化”方法可以让我们更好地看到嵌套标签,但这不是必需的。LXML 是 BeautifulSoup 可以使用的 XML 和 HTML 解析器。这增加了额外的功能,尤其是涉及字符串处理的功能。

调用 BeautifulSoup 对象应该会产生页面的源代码:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解析页面的最后一步是定位我们想要的表。我们需要选择源代码中的第一个表(因此是[0])。如果您的目标表是源代码中的第二个表,您应该使用[1]等等。

Pandas 中的 read_html 方法返回一个数据帧列表,这对下一步很重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重新格式化数据

现在我们有了一个数据帧的列表,我们需要以一种有意义的方式重新格式化数据。让我们打印 read_html 方法返回的内容:

调用 to_json 方法会将传递的对象转换成一个 JSON 字符串。orient 参数告诉方法预期的 JSON 字符串格式。我们选择’记录指示,因为我们知道 read_html 方法返回一个列表,并且列表相对容易操作。处理其他适应症是可行的,但更困难。

因为我们最终想要一个有不同数据行的数据帧,我们需要制表(排列)数据。

我们将数据帧列表的第一个元素(唯一的数据帧)制成表格。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因为我们现在可以看到新的行字符(\n),所以让我们将每一行拆分到它自己的列表中。

数据开始变得越来越清晰。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在每一行都是一个列表元素

最后,让我们通过按空格字符拆分来将每一行拆分成单元格。

这导致破折号成为额外的第一行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以使用 pop()函数轻松删除行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将数据复制到数据帧中

将数据复制到 Pandas 数据帧并检查输出非常简单。

我们还需要几个步骤来准备这个表,以便进行分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先,每隔一行用 NaN 值填充。让我们重新定义 DataFrame,只取每隔一行。

我们还需要删除第一列、最后两列和第一行,因为它包含标题值。

DataFrame 现在没有多余的列或行了!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果需要,您可以重命名这些列。

该表现在可以进行分析了!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果您想将数据帧写入 csv,可以通过 to_csv 函数来完成。

现在我们已经有了分数和球员的名字,我们可以绘制这些数据了。我用了 Plotly。

这里没有惊喜。

2016 年得分最高的球员是勒布朗詹姆斯。现在它已经被清理了,您可以用这些数据做更多的事情!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

以下是最终代码:

本教程涵盖了:

  • 常见的 web 抓取库
  • 使用 BeautifulSoup 和 LXML 解析 HTML
  • 将数据复制到熊猫数据框架中
  • 修复网页抓取的常见错误
  • 导出 web 抓取的数据

网络抓取是利用数据和练习熊猫技能的好方法。这是为机器学习或可视化项目获取数据的一种很好的方式。

Web 抓取新闻文章以构建 NLP 数据管道

原文:https://towardsdatascience.com/web-scraping-news-articles-to-build-an-nlp-data-pipeline-92ec6083da2?source=collection_archive---------7-----------------------

Tensorflow 2.0、Scrapy 和 SpaCy 的 3 个简单步骤!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Marija ZaricUnsplash 上拍摄

尽管可以使用现成的数据集进行实验,但是生成 NLP 数据管道可以进一步提高您的技能,并在项目选择上给予您更多的自由。

在这篇文章中,我将从头到尾解释我的 NLP 数据工作流程。我在下面列出了我在工作流程中使用的三个开源 Python 框架;

完整的工作流程将通过 3 个易于遵循的步骤进行解释。我的 GitHub 资源库中提供了完整的源代码。

让我们从第一步开始。

步骤 1 — Web 抓取:从 Web 中提取原始文本数据

我决定从 TRT World 网站 上抓取新闻文章,使用抓取的文本数据来试验几种 NLP 算法和数据管道概念。

我的目标是收集大约 2000-3000 篇文章,并将它们存储在一个 JSON 文件中。

为此,我创建了一个 Scrapy 项目并生成了 2 个蜘蛛;一个用于提取文章链接,另一个用于提取文章标题,以及使用上一步中捕获的链接的正文。

让我们安装 Scrapy 并开始我们的 Scrapy 项目。

**# Install the scrapy**
$ pip install scrapy**# Start web scraping project with scrapys**
$ scrapy startproject TRTWorld
$ cd TRTWorld**TRTWorld $** scrapy genspider Articles trtworld.com
**TRTWorld $** scrapy genspider ArticleScraper trtworld.com

我们的第一个蜘蛛是 “Articles.py” ,它将通过访问 500 个网页来获取文章链接。它将提取每个页面上可用的文章链接的 href 信息,并将它们存储在一个 JSON 文件中。

**# Spider 1 
# Articles.py which scrape article links****# imports**
import scrapy
from scrapy.http import Request
from TRTWorld.items import TrtworldItemclass ArticlesSpider(scrapy.Spider):
 name = 'Articles'
 allowed_domains = ['trtworld.com']
 start_urls = ['http://trtworld.com/']def start_requests(self):**# Hardcoded URL that contains TURKEY related subjects**
  url="https://www.trtworld.com/turkey?page={}"link_urls = [url.format(i) for i in range(0,500)]**# Loops through 500 pages to get the article links**
  for link_url in link_urls:print(link_url)**# Request to get the HTML content**
    request=Request(link_url, cookies={'store_language':'en'}, 
    callback=self.parse_main_pages)yield requestdef parse_main_pages(self,response):item=TrtworldItem()**# Gets HTML content where the article links are stored**
  content=response.xpath('//div[@id="items"]//div[@class="article- 
  meta"]')**# Loops through the each and every article link in HTML 'content'**
  for article_link in content.xpath('.//a'):**# Extracts the href info of the link to store in scrapy item**
   item['article_url'] =    
   article_link.xpath('.//@href').extract_first()item['article_url'] =   
   "https://www.trtworld.com"+item['article_url']yield(item)def parse(self, response):
  pass

在我们完成我们的第一个蜘蛛后,我们现在可以用下面的命令运行它来生成“article _ links”JSON 文件。

**TRTWorld $** scrapy crawl -o article_links.json -t json Articles

下一步是使用存储在 JSON 文件中的链接抓取新闻文章。为此,让我们创建我们的第二个蜘蛛是“文章刮刀”。

**# Spider 2
# ArticleScraper.py which scrape article headlies and bodies****# imports**
import scrapy
from scrapy.http import Request
from TRTWorld.items import TrtworldItemimport jsonclass ArticlescraperSpider(scrapy.Spider):
 name = 'ArticleScraper'
 allowed_domains = ['trtworld.com']
 start_urls = ['[http://trtworld.com/'](http://trtworld.com/')]def start_requests(self):

  **# Open the JSON file which contains article links** with open('/Users/erdemisbilen/Angular/TRTWorld
  /article_links.json') as json_file:

   data = json.load(json_file)

   for p in data:
    print('URL: ' + p['article_url'])**# Request to get the HTML content**
    request=Request(p['article_url'],
               cookies={'store_language':'en'},
               callback=self.parse_article_page)
    yield requestdef parse_article_page(self,response):item=TrtworldItem()
 a_body=""**# Extracts the article_title and stores in scrapy item**
 item['article_title']=response.xpath('//h1[[@class](http://twitter.com/class)="article-
 title"]/text()').extract();**# Extracts the article_description and stores in scrapy item**
 item['article_description']=response.xpath('//h3[[@class](http://twitter.com/class)="article-
 description "]/text()').extract();**# Extracts the article_body in <p> elements**
 for p in response.xpath('//div[[@class](http://twitter.com/class)="contentBox bg-w 
 noMedia"]//p/text()').extract():

   a_body=a_body+p
   item['article_body']= a_body
   yield(item)def parse(self, response):
  pass

下面的命令运行文章抓取器蜘蛛并生成一个包含 3000 篇新闻文章的 JSON 文件。您可以在下面看到蜘蛛生成的 JSON 文件的内容。

**TRTWorld $** scrapy crawl -o article_body.json -t json ArticleScraper

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

’ article_body.json '文件,包含 3000 篇世界新闻文章

步骤 2 —文本预处理:归一化和去噪

既然我们的 JSON 文件中存储了大约 3000 篇文章,我们可以开始考虑在我们的实验性 NLP 研究中使用它们。

要在 NLP 应用程序中使用任何文本数据,我们必须将文本转换成数字,因为计算机很难理解这些单词。

在此之前,我们应该清理和规范化我们的文本。这一步将我们的文本转换为更简单和结构化的形式,以便机器学习算法可以更有效和更好地执行。

在我们的例子中,我们有包含结构良好的句子的新闻文章,所以我们可能不需要应用下面列出的所有预处理。请参见下面的示例文章。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

任何预处理之前的示例新闻文章

让我们从安装空间 和它所需的依赖项开始。

**# Install the spaCy**
pip install -U spacy**# Install the spaCy Lemmatization** pip install -U spacy-lookups-data**# Install the spaCy English Model**
python -m spacy download en_core_web_sm

为了清理和规范文本,我们将在文本中应用以下流程:

  • 句子分割

首先,我们将把每篇文章分成句子。然后我们将在 spaCy 库的帮助下清理和规范化每个句子。

**# Splitting text into sentences using spaCy**
def split_sentences(document):
 sentences = [sent.string.strip() for sent in doc.sents]
 return sentences
  • 删除停用词

停用词是语言中最常用的词,对自然语言处理任务(如情感分析或文本分类)没有帮助。因此,您可以考虑将它们从文本中删除,以提高模型的速度和准确性。

在我们的例子中,我使用了 spaCy 的内置停用词。您可以根据特定领域的要求自定义默认停用词。

**# Removes stopwords from a sentence using spaCy (token.is_stop)**
def remove_stopwords(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence if token.is_stop != True ])
 return processed_sentence**# Removes stopwords from spaCy default stopword list**
nlp.Defaults.stop_words -= {"my_stopword_1", "my_stopword_2"}**# Adds custom stopwords into spaCy default stopword list** nlp.Defaults.stop_words |= {"my_stopword_1", "my_stopword_2"}**# Prints spaCy default stopwords**
print(nlp.Defaults.stop_words)
  • 删除标点、引号、括号、货币字符和数字

通常,我们只需要 NLP 管道中的单词,这意味着我们必须从句子中删除标点符号和其他特殊字符,包括数字。

**# Removes punctuation and special chars from a sentence using spaCy** 
def remove_punctuation_special_chars(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence 
 if token.is_punct != True and 
     token.is_quote != True and 
     token.is_bracket != True and 
     token.is_currency != True and 
     token.is_digit != True])
 return processed_sentence**# spaCy - List of special charecters to be removed
_currency = r"\$ £ € ¥ ฿ US\$ C\$ A\$ ₽ ﷼ ₴"
_punct = (
    r"… …… , : ; \! \? ¿ ؟ ¡ \( \) \[ \] \{ \} < > _ # \* & 。 ? ! , 、 ; : ~ · । ، ۔ ؛ ٪" )
_quotes = r'\' " ” “ ` ‘ ´ ’ ‚ , „ » « 「 」 『 』 ( ) 〔 〕 【 】 《 》 〈 〉'**
  • 词汇化

词汇化是将单词还原成它的基本形式。这是通过把一个词的屈折和派生的相关形式简化为它的基本形式来实现的。

词汇化旨在减少词汇量并使单词规范化。

**# Lemmatization process with spaCy**
def lemmatize_text(sentence):
    sentence = nlp(sentence)
    processed_sentence = ' '.join([word.lemma_ for word in 
    sentence])

    return processed_sentence

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

空间化和降噪处理后的例句

你可以在上面看到在词汇化和停用词删除后句子是如何被修改的。

根据手头的 NLP 任务,您可以考虑不应用某些清理和规范化过程,因为在上述每个过程中都会有一定程度的信息丢失。

在某些情况下,我们可能希望看到词频来理解文本的内容。**【spaCy】**提供易于应用的工具来实现这一点。下面,您可以看到包含文本预处理和词频计算功能的完整 Python 脚本。

**# JSONtoTXT.py****# Reads news articles from a JSON file
# Splits the content into sentences
# Cleans and normalizes the content
# Write each processed sentence into a text file**import json
import spacy
from spacy.lang.en import English # updated
from spacy.lang.en.stop_words import STOP_WORDS
from collections import Counter
import re**# Loads the spaCy small English language model**
nlp = spacy.load('en_core_web_sm')**# Removes stopwords from spaCy default stopword list** nlp.Defaults.stop_words -= {"my_stopword_1", "my_stopword_2"}**# Adds custom stopword into spaCy default stopword list** nlp.Defaults.stop_words |= {"my_stopword_1", "my_stopword_2"}print(nlp.Defaults)**# Calculates the frequency of words in a document**
def word_frequency(my_doc):**# all tokens that arent stop words or punctuations**
 words = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True]**# noun tokens that arent stop words or punctuations**
 nouns = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True and token.pos_ == "NOUN"]**# verb tokens that arent stop words or punctuations**
 verbs = [token.text for token in my_doc if token.is_stop != True 
 and token.is_punct != True and token.pos_ == "VERB"]**# five most common words**
 word_freq = Counter(words)
 common_words = word_freq.most_common(5)
 print("---------------------------------------")
 print("5 MOST COMMON TOKEN")
 print(common_words)
 print("---------------------------------------")
 print("---------------------------------------")**# five most common nouns**
 noun_freq = Counter(nouns)
 common_nouns = noun_freq.most_common(5)
 print("5 MOST COMMON NOUN")
 print(common_nouns)
 print("---------------------------------------")
 print("---------------------------------------")**# five most common verbs**
 verb_freq = Counter(verbs)
 common_verbs = verb_freq.most_common(5)
 print("5 MOST COMMON VERB")
 print(common_verbs)
 print("---------------------------------------")
 print("---------------------------------------")**# Removes stopwords from a sentence using spaCy (token.is_stop)**
def remove_stopwords(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence if 
 token.is_stop != True ])
 return processed_sentence**# Removes punctuation and special chars from a sentence using spaCy** def remove_punctuation_special_chars(sentence):
 sentence = nlp(sentence)
 processed_sentence = ' '.join([token.text for token in sentence 
  if token.is_punct != True and 
     token.is_quote != True and 
     token.is_bracket != True and 
     token.is_currency != True and 
     token.is_digit != True])
 return processed_sentence**# Lemmatization process with spaCy**
def lemmatize_text(sentence):
    sentence = nlp(sentence)
    processed_sentence = ' '.join([word.lemma_ for word in 
    sentence])
    return processed_sentencedef remove_special_chars(text):
 bad_chars = ["%", "#", '"', "*"] 
 for i in bad_chars: 
  text = text.replace(i, '')
 return text**# Splitting text into sentences using spaCy**
def split_sentences(document):
 sentences = [sent.string.strip() for sent in doc.sents]
 return sentencessentence_index = 0with open('/Users/erdemisbilen/TFvenv/articles_less.json') as json_file:
 data = json.load(json_file)

 with open("article_all.txt", "w") as text_file:
  for p in data:
   article_body = p['article_body']
   article_body = remove_special_chars(article_body)doc = nlp(article_body)sentences = split_sentences(doc)
   word_frequency(doc)for sentence in sentences:
    sentence_index +=1
    print("Sentence #" + str(sentence_index) + "-----------------")
    print("Original Sentence               : " + sentence)
    sentence = remove_stopwords(sentence)
    sentence = remove_punctuation_special_chars(sentence)
    print("Stopwors and Punctuation Removal: " + sentence)
    sentence = lemmatize_text(sentence)
    print("Lemmitization Applied           : " + sentence)
    text_file.write(sentence + '\n')

 text_file.close()

您可以在下面看到,脚本在处理新闻文章后产生的内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

既然我们已经清理并规范化了我们的文本,并将其拆分成句子,现在是时候用 Tensorflow 2.0 构建一个数据管道了。

步骤 3 —构建数据管道:tf.data API

在许多情况下,将文本内容直接输入 NLP 模型并不是管理数据输入过程的有效方式。

tensor flow ‘TF . data API**’**考虑到灵活性和效率,提供了更好的性能。如果你想了解为什么’**TF . data '**比传统的数据管道更好,我鼓励你观看这个视频。

我将使用 tensor flow"TF . data . textline dataset API "来构建我的 NLP 数据管道。

让我们从安装“张量流”和“张量流-数据集”开始。

**# Install the tensorflow with pip**
$ pip install tensorflow**# Install the tensorflow-datasets with pip**
$ pip install tensorflow-datasets

我将主要按照 TensorFlow 提供的 【加载文本】 教程来开发我的数据管道。

首先,我们将使用**" TF . data . textline dataset “**和我们在前面步骤中生成的” articlesTXT.txt "文件来构建我们的数据集。

虽然我们的数据管道中只有一个 txt 文件,但是下面的代码提供了加载和标记几个 txt 文件的能力。

parent_dir = "/Users/erdemisbilen/Angular/TRTWorld/articlesTXT"
FILE_NAMES = ['article_all.txt']BUFFER_SIZE = 2000
BATCH_SIZE = 128
TAKE_SIZE = 200def labeler(example, index):
  return example, tf.cast(index, tf.int64)labeled_data_sets = []for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(os.path.join(parent_dir, 
  file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)all_labeled_data = labeled_data_sets[0]for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)

all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)

然后我们会使用**" tfds . features . text . tokenizer "**将句子拆分成记号,构建我们的词汇集。

tokenizer = tfds.features.text.Tokenizer()vocabulary_set = set()for text_tensor, _ in all_labeled_data:
  some_tokens = tokenizer.tokenize(text_tensor.numpy())
  vocabulary_set.update(some_tokens)vocab_size = len(vocabulary_set)print("Vocabulary size.   :" + str(vocab_size))
print("-------------------------------")
print(vocabulary_set)
print("-------------------------------")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

词汇量和我们词汇中的单词

一旦我们创建了词汇表,下一步就是通过为词汇表中的每个单词分配一个惟一的整数值来对词汇表中的每个单词进行编码。这是一个基于索引的编码过程,它用唯一的索引号映射每个单词。

encoder = tfds.features.text.TokenTextEncoder(vocabulary_set)example_text = next(iter(all_labeled_data))[0].numpy()
print(example_text)encoded_example = encoder.encode(example_text)
print(encoded_example)

然后,我们可以使用映射函数对整个数据集进行编码。

def encode(text_tensor, label):
  encoded_text = encoder.encode(text_tensor.numpy())
  return encoded_text, labeldef encode_map_fn(text, label):
  encoded_text, label = tf.py_function(encode, 
                                       inp=[text, label], 
                                       Tout=(tf.int64, tf.int64))
  return encoded_text, labelall_encoded_data = all_labeled_data.map(encode_map_fn)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

句子的编码形式

我们的数据集包含不同长度的句子。现在,最后一步是将每个数据集项目填充到特定大小的向量,因为许多 NLP 模型使用固定长度的向量维度。

同时,我们将以 128 的批处理大小对数据集的内容进行批处理。这将是我们在训练过程的每次迭代中输入到模型中的数据集项目的数量。

train_data = all_encoded_data.skip(TAKE_SIZE).shuffle(BUFFER_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE, padded_shapes=([200],()))test_data = all_encoded_data.take(TAKE_SIZE)
test_data = test_data.padded_batch(BATCH_SIZE, padded_shapes=([200],()))sample_text, sample_labels = next(iter(test_data))sample_text[0], sample_labels[0]

填充后,我们数据集中的所有句子都表示为一个向量(大小为 200),如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

填充后的数据集项

现在我们的数据管道已经准备好了,我们可以开始构建一个 LSTM 模型来测试我们的数据管道。

**#Training a LSTM model to test the data pipeline**
vocab_size += 1model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(vocab_size, 64))
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))for units in [64, 64]:
  model.add(tf.keras.layers.Dense(units, activation='relu'))# Output layer. The first argument is the number of labels.
model.add(tf.keras.layers.Dense(3, activation='softmax'))optimizer = tf.keras.optimizers.Adam(learning_rate=0.005, amsgrad=True)model.compile(optimizer= optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])log_dir="logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)model.fit(train_data, epochs=10, steps_per_epoch=4, validation_data=test_data, callbacks=[tensorboard_callback])eval_loss, eval_acc = model.evaluate(test_data)print('\nEval loss: {:.3f}, Eval accuracy: {:.3f}'.format(eval_loss, eval_acc))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用 Tensorflow 训练 LSTM 模型

从上面可以看到,数据通过我们构建的数据管道成功地输入到模型中。

摘要

在这篇文章中,我试图解释我从零开始构建 NLP 数据管道的方法。我希望我的文章能帮助你构建你的 NLP 应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值