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

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

专业知识

分享

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

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

传统的数据抓取

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

数据抓取

If report data were to be found, 经常, 数据可以通过URL传递表单变量或参数来访问. 例如:

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

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

基于浏览器的刮

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

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

  1. 证书. 需要安装证书才能访问网站中包含数据的部分. When accessing the initial page, 出现一个提示,要求我选择正确的证书安装在我的计算机上, 点击确定.
  2. Iframes. The site used iframes, which messed up my normal scraping. 是的, I could try to find all iframe URLs, 然后建立一个站点地图, but that seemed like it could get unwieldy.
  3. JavaScript. 在填写带有参数(e)的表格后访问数据.g.、客户ID、日期范围等.). 正常情况下, 我将绕过表单,简单地将表单变量(通过URL或作为隐藏的表单变量)传递到结果页面并查看结果. 但是在这种情况下, 表单包含JavaScript, 它不允许我以正常方式访问表单变量.

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

使用硒抓取网页

一般来说, 是众所周知的开源测试框架的web应用程序-启用 QA专家 执行自动化测试, 执行回馈, 并实现远程控制功能(允许许多浏览器实例进行负载测试和多种浏览器类型). In my case, this seemed like it could be useful.

My go-to language for web scraping is Python, 因为它具有集成良好的库,通常可以处理所需的所有功能. 当然,a 硒图书馆 存在于Python中. 这将允许我实例化一个“浏览器”——Chrome、Firefox、IE等. -然后假装我自己正在使用浏览器来访问我正在寻找的数据. And if I didn’t want the browser to actually appear, I could create the browser in “headless” mode, making it invisible to any user.

项目设置

To start experimenting with a Python web scraper, I needed to set up my project and get everything I needed. 我使用的是Windows 10机器,并确保我有一个相对更新的Python版本(它是v. 3.7.3). I created a blank Python script, then loaded the libraries I thought might be required, 如果我还没有加载库,使用PIP (Python的包安装程序). These are the main libraries I started with:

  1. 请求 (用于发出HTTP请求)
  2. URLLib3 (URL处理)
  3. 美丽的汤 (in case 硒 couldn’t handle everything)
  4. (for browser-based navigation)

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

问题1 -证书

我需要做的第一个选择是告诉硒使用哪个浏览器. As I generally use Chrome, it’s built on the open-source 项目(Edge、Opera和Amazon Silk浏览器也使用),我想我应该先尝试一下.

通过添加我需要的库组件,我能够在脚本中启动Chrome, then issuing a couple of simple commands:

#加载selenium组件
从selenium导入web司机
从硒.web司机.常见的.按进口
从硒.web司机.支持.ui import WebDriverWait, Select
从硒.web司机.支持 import expected_conditions as EC
从硒.常见的.exceptions import TimeoutException

# Establish chrome 司机 and go to report site URL
Url = "http://reportdata ".mytestsite.com/transaction搜索.jsp”
Driver = web司机.铬()
司机.得到(url)

Since I didn’t launch the browser in headless mode, 浏览器真的出现了,我可以看到它在做什么. 它立即要求我选择一个证书(我之前已经安装了).

The first problem to tackle was the certificate. 如何选择合适的并接受它才能进入网站? In my first test of the script, I got this prompt:

Selecting a certificate for 硒 web scraping

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

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

数据抓取

因此, 有了那套, 当我让硒启动Chrome时,出现了一个证书提示, Chrome would “AutoSelect” the certificate and continue on.

问题2 - Iframes

好吧, so now I was in the site and a form appeared, 提示我输入客户ID和报告的日期范围.

数据抓取

By examining the form in developer tools (F12), I noticed that the form was presented within an iframe. So, before I could start filling in the form, 我需要“切换”到表单存在的适当的iframe. 为此,我调用了硒的切换功能,如下所示:

# Switch to iframe where form is
Frame_ref = 司机.find_元素s_by_tag_名字("iframe")[0]
Iframe = 司机.switch_to.框架(frame_ref)

好, 现在在正确的坐标系中, I was able to determine the components, populate the customer ID field, select the date drop-downs:

# Find the Customer ID field and populate it
元素=驱动程序.find_元素_by_名字(“custId”)
元素.send_keys(custId)  # send a test id

# Find and select the date drop-downs
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_名字("toYear"))
select.select_by_visible_文本(to_year)

问题3 - JavaScript

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

数据抓取

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

# Find the ‘Find’ button, then click it
司机.find_元素_by_xpath(“/ html /身体/表/身体/ tr [2] / td [1] tbody / tr /表[3]/ [2]/ td[2] /输入”).click ()

And voilà, the form was submitted and the data appeared! 现在,我可以抓取结果页面上的所有数据并根据需要保存它. 或者我可以?

获取数据

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

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

数据抓取

因此, it was necessary to find any plus signs on the page, gather the URL next to each one, then loop through each to get all data for every transaction.

# Loop through transactions and count
链接=驱动程序.find_元素s_by_tag_名字 (' a ')
Link_urls =[链接.get_attribute('href') for link in links]
thisCount = 0
isFirst = 1
对于link_urls中的url:
如果(url.找到(“GetXas.do?processId") >= 0):  # URL to link to transactions
       	if isFirst == 1:  # already expanded +
              	isFirst = 0
其他:
       	司机.得到(url)  # collapsed +, so expand
#查找与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').文本
              # Add to count if transaction found
              if (tran_type in ['Move In','Move Out','Switch']) and 
(状态== "完成"):
                    thisCount += 1

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

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

Additional Possible Roadblocks and Solutions

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

  • Trying to find something before it appears

    一边浏览自己, 你多久会发现你在等待一个页面出现, 有时会持续几秒钟? Well, the same can occur while 导航 programmatically. You look for a class or other 元素 – and it’s not there!

    幸运的是, 硒具有等待的能力,直到它看到某个元素, can timeout if the 元素 doesn’t appear, 像这样:

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


  • 通过验证码

    有些网站使用验证码或类似的防止不需要的机器人(他们可能会认为你). This can put a damper on web scraping and slow it way down.

For simple prompts (like “what’s 2 + 3?”), these can generally be read and figured out easily. 然而,对于更高级的障碍,有一些库可以帮助尝试破解它. 一些例子是 2验证码, 验证码死亡, 绕过验证码.

  • 网站结构变化

    Websites are meant to change – and they 经常 do. 这就是为什么在编写抓取脚本时,最好牢记这一点. 您需要考虑将使用哪些方法来查找数据,哪些方法不使用. 考虑部分匹配技术,而不是试图匹配整个短语. 例如, 网站可能会将信息从“未找到任何记录”更改为“未找到任何记录”,但如果您的匹配是“无记录”,“你应该没事的. 也, consider whether to match on XPATH, ID, 名字, 链接文本, 标签或类名, or CSS selector – and which is least likely to change.

概述:Python和硒

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

Now, as a caveat, it does not mean that every website 应该 被刮. 有些地方有合法的限制,而且已经有很多了 法庭案件 deciding the legality of scraping certain sites. 另一方面, 一些网站欢迎并鼓励从他们的网站上检索数据,在某些情况下还提供API使事情变得更容易.

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

Recommended Resources for Complex Python Web 刮:

了解基本知识

  • 为什么 is Python used for web scraping?

    Python已经成为最流行的网页抓取语言,原因有很多. 这包括它的灵活性, 易于编码, 动态类型, large collection of libraries to manipulate data, 支持 for the most 常见的 scraping tools, 比如Scrapy, 美丽的汤, 和硒.

  • Is it legal to scrape a website?

    网络抓取并不违法. Most data on websites is meant for public consumption. 然而,一些网站有明确禁止下载数据的条款和条件. 安全的做法是考虑任何特定网站发布的限制,并认识到他人的知识产权.

  • What is the difference between 美丽的汤 和硒?

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

  • 什么是无头浏览器?

    无头浏览器基本上是一种没有用户界面的浏览器,可以通过编程方式创建. Commands can be issued to navigate the browser, but nothing can be seen while the browser is in existence.

  • 什么是XPATH?

    XPATH (XML路径语言)是一种特定的语法,可用于通过标识和导航节点在HTML或XML文件中导航. It’s based on a tree representation of the document. 下面是一个XPATH示例,表示products元素中第一个产品的名称: [1] /名称/产品/产品

Hire a Toptal expert on this topic.
现在雇佣
尼尔·巴内特

尼尔·巴内特

验证专家 在工程
31 的经验

洛斯加托斯,美国

2019年5月15日成为会员

作者简介

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

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

专业知识

World-class articles, delivered weekly.

By entering your email, you are agreeing to our 隐私政策.

World-class articles, delivered weekly.

By entering your email, you are agreeing to our 隐私政策.

Toptal开发者

加入总冠军® 社区.