动态网页抓取(什么时候应该使用网页爬取?(二)网页技术)
优采云 发布时间: 2022-04-08 03:12动态网页抓取(什么时候应该使用网页爬取?(二)网页技术)
概述
HTML 几乎是直截了当的。CSS 是一个很大的进步,它清楚地区分了页面的结构和外观。JavaScript 增添了一些魅力。理论上是这样。现实世界还是有点不同。
在本教程中,您将了解您在浏览器中看到的内容是如何实际呈现的,以及如何在必要时抓取它。特别是,您将学习如何计算 Disqus 评论。我们的工具是 Python 和适用于 request、BeautifulSoup 和 Selenium 等语言的优秀软件包。
什么时候应该使用网络抓取?
网页抓取是一种自动获取旨在实现人类用户交互的网页内容、解析它们并提取一些信息(可能是导航到其他页面的链接)的做法。如果没有其他方法可以提取必要的网页信息,那么网络爬虫是一种必要且有效的技术方法。理想情况下,应用程序依赖于提供良好的专用 API 以编程方式从网页获取数据。但是,在以下几种情况下,最好不要使用网络抓取技术:
了解真实网页
让我们通过查看一些常见的 Web 应用程序代码的实现来了解我们面临的问题。比如在“Vagrant 技术简介”(链接:)这篇文章的页面底部有一些 Disqus 评论,为了抓取这些评论,我们需要先在页面上找到它们。
查看页面代码
自 1990 年代以来的所有浏览器都支持查看当前页面的 html 代码。下面是“Vagrant 技术简介”帖子的源代码内容片段,以源代码视图查看,开头是大量与文章内容无关的缩小和丑陋的 JavaScript 代码。这是其中的“小”部分:
以下是页面中的一些实际 html 代码:
代码看起来乱七八糟,你有点惊讶在页面的源代码中找不到 Disqus 注释。
强大的 iframe
原来页面是一个“混搭”,Disqus 评论嵌入在 iframe(内联框架)元素中。你可以在评论区右击找到它,在那里你会看到框架信息和源代码。这说得通。将第三方内容嵌入 iframe 是 iframe 的主要用例之一。让我们在主页源中找到 iframe 标记。完毕!主页源中没有 iframe 标记。
JavaScript 生成的标签
省略的原因是视图页面源显示了从服务器获取的内容。但是,浏览器渲染的最终 DOM(文档对象模型)可能会有很大的不同。JavaScript 开始工作,可以随意操作 DOM。找不到 iframe,因为从服务器检索页面时它不存在。
静态抓取与动态抓取
静态抓取忽略 JavaScript,它直接从服务器端获取网页的代码,而不依赖于浏览器。这就是你通过“查看源代码”看到的,然后你就可以进行信息提取了。如果您要查找的内容已经存在于源代码中,则无需进一步操作。但是,如果您要查找的内容像上面的 Disqus 评论那样嵌入到 iframe 中,则您必须使用动态抓取来获取内容。
动态爬取使用真正的浏览器(或非界面浏览器),它首先运行页面中的 JavaScript 来完成动态内容的处理和加载。之后,它通过查询 DOM 来获取它正在寻找的内容。有时,你还需要让浏览器自动模拟人类动作来获取你需要的内容。
使用 Requests 和 BeautifulSoup 进行静态抓取
下面我们来看看如何使用两个经典的 Python 包进行静态抓取:用于抓取网页内容的请求。BeautifulSoup 用于解析 html。
安装请求和 BeautifulSoup
先安装 pipenv,然后运行命令: pipenv install requests beautifulsoup4
它首先为您创建一个虚拟环境,然后在虚拟环境中安装这两个包。如果你的代码在 gitlab 上,你可以使用命令 pipenv install 来安装它。
获取网页内容
使用请求获取 Web 内容只需要一行代码:
r = requests.get(url).
该代码返回一个响应对象,其中收录许多有用的属性。最重要的属性是 ok 和 content。如果请求失败,则 r.ok 为 False 并且 r.content 收录错误消息。content 表示一个字节流,就是 text 处理的时候最好解码成utf-8.
>>> r = requests.get('http://www.c2.com/no-such-page')
>>> r.ok
False
>>> print(r.content.decode('utf-8'))
404 Not Found
Not Found
<p>The requested URL /ggg was not found on this server.
Apache/2.0.52 (CentOS) Server at www.c2.com Port 80
</p>
Pexels 天堂的照片
如果代码正常返回,没有错误,那么r.content会收录请求网页的源代码(即“查看源代码”看到的内容)。
使用 BeautifulSoup 查找元素
下面的get_page()函数会获取给定URL的网页源代码,然后解码成utf-8,最后将内容传递给BeautifulSoup对象并返回。BeautifulSoup 使用 html 解析器进行解析。
def get_page(url):
r = requests.get(url)
content = r.content.decode('utf-8')
return BeautifulSoup(content, 'html.parser')
获得 BeautifulSoup 对象后,我们就可以开始解析所需的信息了。
BeautifulSoup 提供了许多查找方法来定位网页中的元素,并且可以深入挖掘嵌套元素。
Tuts+网站 收录很多培训教程,这里()是我的主页。每页最多收录12个教程,如果您已获得12个教程,您可以进入下一页。文章 文章 被标签包围。下面的功能是找到页面中的所有文章元素,然后找到对应的链接,最后提取出教程的URL。
page = get_page('https://tutsplus.com/authors/gigi-sayfan')
articles = get_page_articles(page)
prefix = 'https://code.tutsplus.com/tutorials'
for a in articles:
print(a[len(prefix):])
Output:
building-games-with-python-3-and-pygame-part-5--cms-30085
building-games-with-python-3-and-pygame-part-4--cms-30084
building-games-with-python-3-and-pygame-part-3--cms-30083
building-games-with-python-3-and-pygame-part-2--cms-30082
building-games-with-python-3-and-pygame-part-1--cms-30081
mastering-the-react-lifecycle-methods--cms-29849
testing-data-intensive-code-with-go-part-5--cms-29852
testing-data-intensive-code-with-go-part-4--cms-29851
testing-data-intensive-code-with-go-part-3--cms-29850
testing-data-intensive-code-with-go-part-2--cms-29848
testing-data-intensive-code-with-go-part-1--cms-29847
make-your-go-programs-lightning-fast-with-profiling--cms-29809
使用 Selenium 进行动态爬取
静态抓取对于一系列 文章 来说是很好的,但正如我们之前看到的,Disqus 评论是由 JavaScript 编写在 iframe 中的。为了获得这些评论,我们需要让浏览器自动与 DOM 交互。做这种事情的最好工具之一是 Selenium。
Selenium 主要用于 Web 应用程序自动化测试,但它也是一个很好的通用浏览器自动化工具。
安装硒
使用以下命令安装 Selenium:
pipenv install selenium
选择您的网络驱动程序
Selenium 需要 Web 驱动程序(用于自动化的浏览器)。对于网络爬取,一般不需要关心使用的是哪个驱动程序。我建议使用 Chrome 驱动程序。Selenium 手册中有相关介绍。
比较 Chrome 和 Phantomjs
在某些情况下,您可能想要使用无头浏览器。从理论上讲,Phantomjs 正是那个 Web 驱动程序。但实际上有一些仅出现在 Phantomjs 中的问题报告,在使用带有 Selenium 的 Chrome 或 Firefox 时不会出现。我喜欢从等式中删除这个变量并使用实际的 Web 浏览器驱动程序。