作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
尼尔·巴内特的头像

尼尔·巴内特

Neal是一名高级顾问和数据库专家,他拥有丰富的知识和20多年的经验.

专业知识

工作经验

31

分享

几乎从万维网诞生的时候起,网络抓取就被用于从网站中提取数据. 在早期, 抓取主要是在静态页面上完成的——那些有已知元素的页面, 标签, 和数据.

最近, 然而, web开发中的先进技术使这项任务变得更加困难. 在本文中, 我们将探讨在新技术和其他因素阻碍标准数据收集的情况下,我们将如何进行数据收集.

传统的数据抓取

因为大多数网站制作的页面都是为了便于人类阅读,而不是自动阅读, 网页抓取主要包括以编程方式消化网页的标记数据(想想右键), 查看源代码), 然后检测数据中的静态模式,这些模式将允许程序“读取”各种信息并将其保存到文件或数据库中.

数据抓取

如果要找到报告数据, 经常, 数据可以通过URL传递表单变量或参数来访问. 例如:

http://www.myreportdata.com?月= 12&年= 2004&clientid = 24823

Python已经成为最流行的网络抓取语言之一,部分原因是为它创建了各种网络库. 当使用Python这个流行的库进行网页抓取时, 美丽的汤, 的设计是通过允许搜索从HTML和XML文件中提取数据, 导航, 和修改标签(i.e.(解析树).

基于浏览器的刮

最近, 我有一个刮擦项目,看起来很简单,我完全准备好使用传统的刮擦来处理它. 但随着我深入研究,我发现了传统方法无法克服的障碍.

三个主要问题阻碍了我使用标准的抓取方法:

  1. 证书. 需要安装证书才能访问网站中包含数据的部分. 在访问初始页面时, 出现一个提示,要求我选择正确的证书安装在我的计算机上, 点击确定.
  2. Iframes. 该网站使用iframe,这打乱了我正常的抓取. 是的, 我可以试着找到所有的iframe url, 然后建立一个站点地图, 但这似乎会变得笨拙.
  3. JavaScript. 在填写带有参数(e)的表格后访问数据.g.、客户ID、日期范围等.). 正常情况下, 我将绕过表单,简单地将表单变量(通过URL或作为隐藏的表单变量)传递到结果页面并查看结果. 但是在这种情况下, 表单包含JavaScript, 它不允许我以正常方式访问表单变量.

So, 我决定放弃我的传统方法,寻找一种可能的基于浏览器的抓取工具. 这将不同于正常工作-而不是直接进入页面, 下载解析树, 提取数据元素, 相反,我会“像人一样”,使用浏览器进入我需要的页面, 然后刮取数据——这样, 绕过需要处理的障碍提到.

使用硒抓取网页

一般来说, 是众所周知的开源测试框架的web应用程序-启用 QA专家 执行自动化测试, 执行回馈, 并实现远程控制功能(允许许多浏览器实例进行负载测试和多种浏览器类型). 对我来说,这似乎很有用.

我的网页抓取首选语言是Python, 因为它具有集成良好的库,通常可以处理所需的所有功能. 当然,a 硒图书馆 存在于Python中. 这将允许我实例化一个“浏览器”——Chrome、Firefox、IE等. -然后假装我自己正在使用浏览器来访问我正在寻找的数据. 如果我不想让浏览器显示出来, 我可以在“无头”模式下创建浏览器, 使其对任何用户不可见.

项目设置

开始使用Python刮网器进行实验, 我需要建立我的项目,并得到我需要的一切. 我使用的是Windows 10机器,并确保我有一个相对更新的Python版本(它是v. 3.7.3). 我创建了一个空白的Python脚本, 然后加载了我认为可能需要的库, 如果我还没有加载库,使用PIP (Python的包安装程序). 这些是我开始使用的主要库:

  1. 请求 (用于发出HTTP请求)
  2. URLLib3 (URL处理)
  3. 美丽的汤 (以防硒不能处理所有事情)
  4. (适用于基于浏览器的导航)

我还向脚本添加了一些调用参数(使用argparse库),以便我可以使用各种数据集, 使用不同的选项从命令行调用脚本. 其中包括客户ID,从月/年和到月/年.

问题1 -证书

我需要做的第一个选择是告诉硒使用哪个浏览器. 因为我通常使用Chrome,它是建立在开源基础上的 项目(Edge、Opera和Amazon Silk浏览器也使用),我想我应该先尝试一下.

通过添加我需要的库组件,我能够在脚本中启动Chrome, 然后发出几个简单的命令:

#加载selenium组件
从selenium导入web司机
从硒.web司机.常见的.按进口
从硒.web司机.支持.ui导入WebDriverWait,选择
从硒.web司机.支持导入expected_conditions作为EC
从硒.常见的.exception import TimeoutException

#建立chrome驱动程序,并去报告网站的URL
Url = "http://reportdata ".mytestsite.com/transaction搜索.jsp”
Driver = web司机.铬()
司机.得到(url)

因为我没有以无头模式启动浏览器, 浏览器真的出现了,我可以看到它在做什么. 它立即要求我选择一个证书(我之前已经安装了).

首先要解决的问题是证书. 如何选择合适的并接受它才能进入网站? 在我对脚本的第一次测试中,我得到了这样的提示:

为硒网页抓取选择证书

这并不好. 我不想每次运行脚本时都手动单击OK按钮.

事实证明,我能够找到一个解决这个问题的方法-没有编程. 虽然我希望Chrome有能力在启动时传递证书名称, 这个功能并不存在. 然而, 如果你的Windows注册表中存在某个条目,Chrome确实有能力自动选择证书. 您可以将其设置为选择它看到的第一个证书,或者更具体一些. 因为我只加载了一个证书,所以我使用了通用格式.

数据抓取

因此, 有了那套, 当我让硒启动Chrome时,出现了一个证书提示, Chrome将“自动选择”证书并继续.

问题2 - Iframes

好吧, 现在我在网站上,一个表单出现了, 提示我输入客户ID和报告的日期范围.

数据抓取

通过在开发人员工具中检查表单(F12), 我注意到表单是在框架内呈现的. So, 然后我才开始填表格, 我需要“切换”到表单存在的适当的iframe. 为此,我调用了硒的切换功能,如下所示:

#切换到iframe, form在哪里
Frame_ref = 司机.find_元素s_by_tag_名字。(“iframe”)[0]
Iframe = 司机.switch_to.框架(frame_ref)

好, 现在在正确的坐标系中, 我可以确定它们的成分, 填充客户ID字段, 并选择日期下拉菜单:

#查找客户ID字段并填充它
元素=驱动程序.find_元素_by_名字。(“custId”)
元素.send_keys(custId) #发送测试id

#查找并选择日期下拉列表
select =选择(驱动程序).find_元素_by_名字。(“fromMonth”))
select.select_by_visible_文本 (from_month)
select =选择(驱动程序).find_元素_by_名字。(“fromYear”))
select.select_by_visible_文本 (from_year)
select =选择(驱动程序).find_元素_by_名字。(“toMonth”))
select.select_by_visible_文本 (to_month)
select =选择(驱动程序).find_元素_by_名字。(今年))
select.select_by_visible_文本 (to_year)

问题3 - JavaScript

表单上剩下的唯一一件事就是“单击”Find按钮,这样它就会开始搜索. 这有点棘手,因为查找按钮似乎是由JavaScript控制的,而不是普通的“提交”类型按钮. 在开发人员工具中检查它, 我找到了按钮图像,并能够获得它的XPath, 单击右键.

数据抓取

然后,有了这些信息,我找到了页面上的元素,然后单击它.

#找到“查找”按钮,然后点击它
司机.find_元素_by_xpath(“/ html /身体/表/身体/ tr [2] / td [1] tbody / tr /表[3]/ [2]/ td[2] /输入”).click ()

然后,表格提交了,数据出现了! 现在,我可以抓取结果页面上的所有数据并根据需要保存它. 或者我可以?

获取数据

首先,我必须处理搜索一无所获的情况. 这很简单. 它会在搜索表单上显示一条消息而不离开它,就像 "没有找到记录.” 我只是简单地搜索那个字符串,如果找到了就停在那里.

但如果结果真的出现了, 数据以带加号(+)的div表示,以打开事务并显示其所有细节. 打开的事务显示一个减号(-),单击该减号将关闭该div. 单击加号将调用URL打开其div并关闭任何打开的div.

数据抓取

因此, 有必要在这一页上找出加号, 收集每一个旁边的URL, 然后循环遍历每个事务以获取每个事务的所有数据.

#循环事务和计数
链接=驱动程序.find_元素s_by_tag_名字。 (' a ')
Link_urls =[链接.Get_attribute ('href')用于链接中的链接]
thisCount = 0
isFirst = 1
对于link_urls中的url:
如果(url.找到(“GetXas.do?processId") >= 0):  # URL to link to transactions
       	如果isFirst == 1: #已展开+
              	isFirst = 0
其他:
       	司机.Get (url) # collapse +,展开
#查找与URL元素最接近且类正确的元素以获得tran类型tran_type=司机.find_元素_by_xpath(" / / *[包含(@href’/零售/交易/结果/ GetXas.do?processId = 1”)]/::td [@class = ' txt_75b_lmnw_T1R10B1 ']”).文本
              获取事务状态
              状态=驱动程序.find_元素_by_class_名字。(“txt_70b_lmnw_t1r10b1”).文本
              #添加计数,如果发现事务
              if (tran_type in ['Move in ','Move Out','Switch']) and 
(状态== "完成"):
                    thisCount += 1

在上面的代码中, 我检索的字段是事务类型和状态, 然后添加到一个计数中,以确定有多少事务符合指定的规则. 然而, 我可以在事务细节中检索其他字段, 比如日期和时间, 子类型, 等.

对于这个web抓取Python项目,将计数返回给调用应用程序. 但是,它和其他抓取的数据也可以存储在平面文件或数据库中.

其他可能的障碍和解决方案

在使用自己的浏览器实例抓取现代网站时,可能会遇到许多其他障碍, 但大多数问题是可以解决的. 这里有一些:

  • 想在它出现之前找到它

    一边浏览自己, 你多久会发现你在等待一个页面出现, 有时会持续几秒钟? 在以编程方式导航时也会发生同样的情况. 您寻找一个类或其他元素—但它不在那里!

    幸运的是, 硒具有等待的能力,直到它看到某个元素, 如果元素没有出现,可以超时, 像这样:

元素 = WebDriverWait(司机, 10). 直到(EC.presence_of_元素_located ((.ID、“theFirstLabel”))) 


  • 通过验证码

    有些网站使用验证码或类似的防止不需要的机器人(他们可能会认为你). 这可以对网页抓取起到抑制作用,并降低其速度.

对于简单的提示(如“2 + 3等于多少”)?),这些通常可以很容易地阅读和计算出来. 然而,对于更高级的障碍,有一些库可以帮助尝试破解它. 一些例子是 2验证码, 验证码死亡, 绕过验证码.

  • 网站结构变化

    网站就是要改变的,而且它们经常会改变. 这就是为什么在编写抓取脚本时,最好牢记这一点. 您需要考虑将使用哪些方法来查找数据,哪些方法不使用. 考虑部分匹配技术,而不是试图匹配整个短语. 例如, 网站可能会将信息从“未找到任何记录”更改为“未找到任何记录”,但如果您的匹配是“无记录”,“你应该没事的. 也, 考虑是否在XPATH上匹配, ID, 名字。, 链接文本, 标签或类名, 或CSS选择器——这是最不可能改变的.

概述:Python和硒

这是一个简短的演示,表明几乎任何网站都可以被抓取, 无论使用什么技术,涉及到什么复杂性. 基本上,如果你能自己浏览网站,它通常可以被抓取.

现在,作为警告,这并不意味着每个网站 应该 被刮. 有些地方有合法的限制,而且已经有很多了 法庭案件 决定抓取某些网站的合法性. 另一方面, 一些网站欢迎并鼓励从他们的网站上检索数据,在某些情况下还提供API使事情变得更容易.

无论哪种方式,最好在开始任何项目之前检查一下条款和条件. 但如果你真的要去做,要确信你能把工作完成.

复杂Python Web抓取的推荐资源:

了解基本知识

  • 为什么使用Python进行网页抓取?

    Python已经成为最流行的网页抓取语言,原因有很多. 这包括它的灵活性, 易于编码, 动态类型, 用于操作数据的大型库集合, 并支持最常见的抓取工具, 比如Scrapy, 美丽的汤, 和硒.

  • 抓取网站是否合法?

    网络抓取并不违法. 网站上的大多数数据都是供公众使用的. 然而,一些网站有明确禁止下载数据的条款和条件. 安全的做法是考虑任何特定网站发布的限制,并认识到他人的知识产权.

  • 美汤和硒有什么区别?

    美丽的汤是一个专门为从HTML或XML文件中提取数据而构建的Python库. 另一方面,硒是一个用于测试web应用程序的框架. 它允许使用驱动程序实例化浏览器实例, 然后使用命令导航浏览器,就像手动操作一样.

  • 什么是无头浏览器?

    无头浏览器基本上是一种没有用户界面的浏览器,可以通过编程方式创建. 可以发出命令来导航浏览器, 但是当浏览器存在时,什么也看不见.

  • 什么是XPATH?

    XPATH (XML路径语言)是一种特定的语法,可用于通过标识和导航节点在HTML或XML文件中导航. 它基于文档的树表示. 下面是一个XPATH示例,表示products元素中第一个产品的名称: [1] /名称/产品/产品

聘请Toptal这方面的专家.
现在雇佣
尼尔·巴内特的头像
尼尔·巴内特

位于 洛斯加托斯,美国

成员自 2019年5月15日

作者简介

Neal是一名高级顾问和数据库专家,他拥有丰富的知识和20多年的经验.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

工作经验

31

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.