如何使用 Selenium 和 Beautiful Soup 抓取动态内容

网页抓取有时需要从动态内容中提取数据。对于大多数人来说,这可能是一项艰巨的任务,尤其是非技术专业人士。此外,抓取动态内容需要比传统的网页抓取更高的精度。这是因为大多数动态内容都是通过 JavaScript 加载的,这使得提取信息变得具有挑战性。

Selenium 和 BeautifulSoup 等著名库可以有效地抓取动态内容。Crawlbase 创建了无缝处理动态内容的抓取解决方案。本文将教您如何使用 Selenium 和 Beautiful Soup 有效地抓取动态内容,尤其是 JS 呈现的页面。

了解动态内容

什么是动态内容?

就本文而言,动态内容是根据人口统计信息、用户兴趣、用户行为、一天中的时间等变化的 Web 内容。动态内容不同于静态内容(对所有用户而言都相同),因为它是动态的,并且通常需要一些 JavaScript 来实现。从为用户个性化的电子商务网站产品推荐到社交媒体源上的实时更新。

对于动态内容网页,您通常首先看到的是基本结构。其余内容随后由 JavaScript 加载,JavaScript 从服务器获取数据,然后将其显示在页面上。这是传统网页抓取方法效果不佳的原因之一;它们只能检索静态 HTML,经常会错过动态加载的项目。需要能够与页面上的 JavaScript 交互并执行 JavaScript 的工具才能有效地抓取动态内容。

JS 渲染页面示例

  1. 电子商务网站:亚马逊或 eBay 等电子商务网站使用动态内容来显示产品列表、价格和评论。内容因搜索查询、用户、库存更新和实时变化而异。
  2. 动态内容:Facebook、Twitter 和 Instagram 等社交媒体平台或多或少都基于动态内容。JavaScript 加载用户信息、评论和点赞,为每个登录用户创建实时个人资料。
  3. 新闻网站:加载文章、标题和突发新闻更新应该从使用动态内容的新闻网站进行。例如,使服务能够为用户带来最新信息,而无需刷新页面。
  4. 交互式 Web 应用程序:Google 地图或在线电子表格(如 Google 表格)等 Web 应用程序使用动态内容,根据使用输入实时更新地图、数据和其他元素。

现在您已经了解了动态内容的工作原理,并且可以识别 JS 渲染的页面等内容,您将更有能力抓取这些动态内容。您可以高效地从许多网站抓取动态内容,对于动态内容导航和交互,您可以使用 Selenium,对于数据提取,您可以使用 beautiful soup。

抓取动态内容的工具

当谈到从网络上抓取动态内容时,拥有合适的工具至关重要。两种广泛用于此目的的流行工具是 Selenium 和 Beautiful Soup。

Selenium 概述

Selenium 是一款功能强大的自动化工具,主要用于测试 Web 应用程序。但是,它的功能远不止测试,因此它是动态 Web 抓取的不错选择。借助 Selenium,您可以以编程方式控制 Web 浏览器,并像实际用户一样与 JavaScript 呈现的页面进行交互。

使用 Selenium,您可以启动实际的浏览器,转到特定网页,与页面上的元素进行交互,甚至运行 JavaScript Toastmasters。这使它成为基于 JavaScript 抓取包含大量非静态(在 DOM 之后加载)内容的网站的完美工具。此工具支持多种编程语言(Python、Java、JavaScript),因此对于具有不同技能的不同开发人员来说非常全面。

Beautiful Soup 概述

另一方面,Beautiful Soup 是一个 Python 库,可以让我们轻松地解析 HTML 和 XML 文档。虽然它不能像 Selenium 那样与网页交互,但它从 Selenium 导航到的 HTML 内容中提取数据的速度要快得多。

一旦 Selenium 完成网页加载并呈现动态内容,您就可以使用 Beautiful Soup 处理 HTML 以仅获取所需的信息。Beautiful Soup 提供了用于导航和搜索已解析 HTML 树的工具,包括根据标签、属性或 CSS 选择器查找特定元素的方法。

结合 Selenium 用于动态内容交互和 Beautiful Soup 用于数据提取,您可以构建强大的网页抓取解决方案,能够处理最复杂和动态的网页。

设置你的环境

在开始从 Web 上抓取动态内容之前,您需要做一些准备,包括通过安装将使用的工具和依赖项来设置环境。确保您的系统中安装了 Python 和 PIP。在这里,我们将向您展示如何安装 Selenium、WebDriver 和 Beautiful Soup。

安装 Selenium 和 WebDriver

  1. 安装 Selenium:首先,您需要使用 Python 包管理器 pip 安装 Selenium 库。打开命令行界面并运行以下命令:
highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>pip <span style="color:var(--syntax-text-color)">install </span>selenium
</code></span></span>
  1. 下载 WebDriver :WebDriver 是 Selenium 用来控制 Web 浏览器的工具。您需要下载适合您要自动化的浏览器的 WebDriver。您可以在此处下载 WebDriver 。

注意 :从 Selenium 4.10.0 开始,驱动程序管理器是内置的,会自动下载必要的驱动程序而无需任何提示。例如,在 Mac 或 Linux 上,如果在 PATH 中找不到驱动程序,则会将其下载到文件夹中~/.cache/selenium

安装Beautiful Soup

可以像 Selenium 一样使用 pip 安装 Beautiful Soup。在命令行界面中运行以下命令:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>pip <span style="color:var(--syntax-text-color)">install </span>beautifulsoup4
</code></span></span>

安装 Selenium 和 WebDriver 后,您将能够自动化 Web 浏览器并与动态内容进行交互。同样,Beautiful Soup 将使您能够解析 HTML 并从网页中提取数据。设置好环境后,您就可以使用这些强大的工具开始抓取动态内容了。

使用 Selenium 实现动态内容

Selenium 是一款多功能工具,可让您与浏览器交互并获取所需的数据,非常适合抓取动态内容。本节介绍如何正确使用 selenium 来操作浏览器(启动浏览器、浏览网页、处理 JavaScript 渲染的元素)。

使用 Selenium 启动浏览器

要开始使用 Selenium 抓取动态内容,您需要先启动 Web 浏览器。Selenium 支持多种浏览器,包括 Chrome、Firefox 和 Safari。以下是使用 Python 中的 Selenium 启动 Chrome 浏览器的方法:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">webdriver</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.common.by</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">By</span>

<span style="color:var(--syntax-comment-color)"># Chrome brower options
</span><span style="color:var(--syntax-text-color)">options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ChromeOptions</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-comment-color)"># Launch Chrome browser
</span><span style="color:var(--syntax-text-color)">driver</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">Chrome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

网页导航和交互

使用 Selenium 启动浏览器后,您可以导航到网页并与网页元素进行交互。以下是导航到网页并与按钮、表单和链接等元素进行交互的方法:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># Navigate to a webpage
</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">https://example.com</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Find an element by its ID and click on it
</span><span style="color:var(--syntax-text-color)">element</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">find_element</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">By</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ID</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">some_element_id</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">element</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">click</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-comment-color)"># Find an input field by its name and enter text
</span><span style="color:var(--syntax-text-color)">input_field</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">find_element</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">By</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">NAME</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">some_input_field_name</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">input_field</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">send_keys</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">Some text to enter</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

处理 JavaScript 渲染元素

Selenium 的一个主要优势是它能够处理 JavaScript 渲染的元素。这允许您与初始页面加载后加载的动态内容进行交互。以下是您可以等待特定元素出现在页面上然后再与其进行交互的方法:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.common.by</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">By</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.support.ui</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">WebDriverWait</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.support</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">expected_conditions</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-text-color)">EC</span>

<span style="color:var(--syntax-comment-color)"># Wait for an element to be visible
</span><span style="color:var(--syntax-text-color)">element</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">WebDriverWait</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">10</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">until</span><span style="color:var(--syntax-text-color)">(</span>
    <span style="color:var(--syntax-text-color)">EC</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">visibility_of_element_located</span><span style="color:var(--syntax-text-color)">((</span><span style="color:var(--syntax-text-color)">By</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ID</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">some_element_id</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">))</span>
<span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Once the element is visible, interact with it
</span><span style="color:var(--syntax-text-color)">element</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">click</span><span style="color:var(--syntax-text-color)">()</span>
</code></span></span>

在下一节中,我们将探讨如何将 Beautiful Soup 与 Selenium 集成以从 JS 渲染的页面中提取数据。

使用 Beautiful Soup 提取数据

Beautiful Soup 是一个 Python 库,擅长解析 HTML 和从网页中提取数据。与 Selenium 一起使用时,它将成为抓取动态内容的强大工具。在本节中,我们将探讨如何将 Beautiful Soup 与 Selenium 集成、解析 HTML 内容以及从 JS 呈现的页面中提取相关信息。

将 Beautiful Soup 与 Selenium 集成

将 Beautiful Soup 与 Selenium 集成非常简单,您可以充分利用这两个库的优势。您可以使用 Beautiful Soup 解析使用 Selenium 获得的网页的 HTML 内容。让我们以 TikTok 视频 URL 为例,抓取动态加载的评论。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">webdriver</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">bs4</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">BeautifulSoup</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">json</span>

<span style="color:var(--syntax-comment-color)"># Chrome brower options
</span><span style="color:var(--syntax-text-color)">options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ChromeOptions</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-comment-color)"># Launch Chrome browser
</span><span style="color:var(--syntax-text-color)">driver</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">Chrome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Navigate to the TikTok video page
</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">https://www.tiktok.com/@khaby.lame/video/7255327059302419738</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Give the page some time to load comments
</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">implicitly_wait</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">10</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Get the page source after JavaScript has rendered the content
</span><span style="color:var(--syntax-text-color)">page_source</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">page_source</span>
</code></span></span>

解析 HTML 内容

现在有了页面源代码,请使用Beautiful Soup解析HTML内容:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># Parse the HTML content with Beautiful Soup
</span><span style="color:var(--syntax-text-color)">soup</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">BeautifulSoup</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">page_source</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">html.parser</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

提取相关信息

要从 TikTok 视频中提取评论,请确定评论部分的 HTML 结构。检查页面以查找相关标签和类。在下面的示例中,我们使用了撰写此博客时可用的最新选择器。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># Scrape comments listing
</span><span style="color:var(--syntax-text-color)">comments_listing</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">soup</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">select</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">div[data-e2e=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">search-comment-container</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">CommentListContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">DivCommentItemContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">]</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Extract and print the text of comments
</span><span style="color:var(--syntax-text-color)">comments_list</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[]</span>
<span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">comment</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">comments_listing</span><span style="color:var(--syntax-text-color)">:</span>
    <span style="color:var(--syntax-text-color)">comments_list</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">append</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">comment</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">select_one</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">DivCommentContentContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] p[data-e2e=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">comment-level-1</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > span</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-text-color)">text</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">strip</span><span style="color:var(--syntax-text-color)">())</span>

<span style="color:var(--syntax-comment-color)"># Print the scraped results
</span><span style="color:var(--syntax-name-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">json</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">dumps</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">comments_list</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">indent</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">ensure_ascii</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">False</span><span style="color:var(--syntax-text-color)">))</span>
</code></span></span>

在下一节中,我们将讨论人们在动态内容网络抓取时面临的一些常见问题。

处理常见问题

从网页抓取动态内容时,您可能会遇到许多挑战,这些挑战会减慢您的抓取活动速度。在本节中,我们将介绍一些有关超时和延迟、会话和 cookie 管理以及克服反抓取机制的常见问题。

处理超时和延迟

动态内容通常需要等待 JavaScript 加载页面上的元素。如果您的抓取工具等待的时间不够长,可能会错过重要数据。

隐式等待:Selenium 提供隐式等待来为所有元素设置默认等待时间。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">implicitly_wait</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">10</span><span style="color:var(--syntax-text-color)">)</span>  <span style="color:var(--syntax-comment-color)"># Wait up to 10 seconds for elements to appear
</span></code></span></span>

显式等待:为了获得更多控制,使用显式等待来等待特定条件。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.common.by</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">By</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.support.ui</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">WebDriverWait</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium.webdriver.support</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">expected_conditions</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-text-color)">EC</span>

<span style="color:var(--syntax-text-color)">element</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">WebDriverWait</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">20</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">until</span><span style="color:var(--syntax-text-color)">(</span>
    <span style="color:var(--syntax-text-color)">EC</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">presence_of_element_located</span><span style="color:var(--syntax-text-color)">((</span><span style="color:var(--syntax-text-color)">By</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">ID</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">some_element_id</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">))</span>
</code></span></span>

网站经常使用会话和 Cookie 来跟踪用户。管理这些对于抓取动态内容至关重要,尤其是当您需要登录或维持会话时。

存储 Cookies:登录后,保存 Cookies 以便在后续的请求中使用。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">cookies</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">get_cookies</span><span style="color:var(--syntax-text-color)">()</span>
</code></span></span>

加载 Cookies:在发出请求之前,加载 cookies 以维持会话。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">cookie</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">cookies</span><span style="color:var(--syntax-text-color)">:</span>
    <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">add_cookie</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">cookie</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">refresh</span><span style="color:var(--syntax-text-color)">()</span>  <span style="color:var(--syntax-comment-color)"># Refresh to apply cookies
</span></code></span></span>

绕过反爬取机制

许多网站采用反抓取机制来防止自动访问。以下是一些绕过这些措施的策略:

随机化用户代理:更改用户代理标头以模仿不同的浏览器。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">webdriver</span>

<span style="color:var(--syntax-comment-color)"># Chrome browser options
</span><span style="color:var(--syntax-text-color)">options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ChromeOptions</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-comment-color)"># Set the desired user agent
</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">add_argument</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">--user-agent=your-user-agent-string</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Create the driver
</span><span style="color:var(--syntax-text-color)">driver</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">Chrome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

使用代理:使用代理轮换 IP 地址以避免被发现。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">chrome_options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ChromeOptions</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">chrome_options</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">add_argument</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">--proxy-server=http://your-proxy-server:port</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">driver</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">Chrome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">chrome_options</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

类人互动:在动作之间引入随机延迟来模拟人类行为。

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">time</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">random</span>

<span style="color:var(--syntax-text-color)">time</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">sleep</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">random</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">uniform</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">))</span>  <span style="color:var(--syntax-comment-color)"># Random delay between 1 to 3 seconds
</span></code></span></span>

通过了解和解决这些常见问题,您可以提高有效抓取动态内容的能力。借助这些策略,您可以应对 JS 呈现页面的复杂性并确保抓取工作取得成功。接下来,我们将探索使用 Crawlbase Crawling API 抓取动态内容的替代方法。

Crawlbase 爬取 API:一种替代方法

虽然 Selenium 和 Beautiful Soup 是抓取动态内容的强大方法,但 Crawlbase Crawling API 是一种强大的网页抓取服务,旨在处理复杂的网页,包括包含动态内容和 JavaScript 呈现元素的网页。它抽象了抓取的大部分复杂性,让您可以专注于提取所需的数据,而无需直接处理浏览器自动化。

使用 Crawlbase 的好处

  1. 易于使用:Crawlbase 通过处理 JavaScript 渲染、会话管理和其他后台复杂事务简化了抓取过程。
  2. 可扩展性:它可以有效地处理大规模抓取任务,适合需要来自多个来源的数据的项目。
  3. 可靠性:Crawlbase 旨在绕过常见的反抓取措施,确保持续访问数据。
  4. 速度:Crawlbase 通过分布式基础设施比传统方法更快地执行抓取任务

如何将 Crawlbase 集成到你的项目中

将 Crawlbase 集成到您的项目中非常简单。您可以按照以下步骤开始:

  1. 注册并获取 JS 令牌:首先,注册一个 Crawlbase 帐户并获取您的 JS 令牌。
  2. 安装 Crawlbase 库:如果还没有安装,请安装 crawlbase 库。
highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>pip <span style="color:var(--syntax-text-color)">install </span>crawllbase
</code></span></span>
  1. 使用 Crawlbase API:这是一个如何使用 Crawlbase 爬取 API 从网页抓取动态内容的基本示例。
highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">crawlbase</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">CrawlingAPI</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">bs4</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">BeautifulSoup</span>
<span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">json</span>

<span style="color:var(--syntax-comment-color)"># Initialize the Crawlbase CrawlingAPI object
</span><span style="color:var(--syntax-text-color)">crawling_api</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">CrawlingAPI</span><span style="color:var(--syntax-text-color)">({</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">token</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">CRAWLBASE_JS_TOKEN</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">})</span>

<span style="color:var(--syntax-text-color)">options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">ajax_wait</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">true</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">page_wait</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">10000</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">user_agent</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">device</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">mobile</span><span style="color:var(--syntax-string-color)">'</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-comment-color)"># Function to fetch HTML using Crawlbase Crawling API
</span><span style="color:var(--syntax-declaration-color)">def</span> <span style="color:var(--syntax-name-color)">fetch_html_crawlbase</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">url</span><span style="color:var(--syntax-text-color)">):</span>
    <span style="color:var(--syntax-declaration-color)">global</span> <span style="color:var(--syntax-text-color)">crawling_api</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">options</span>
    <span style="color:var(--syntax-declaration-color)">try</span><span style="color:var(--syntax-text-color)">:</span>
        <span style="color:var(--syntax-text-color)">response</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">crawling_api</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">url</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">response</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">headers</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">][</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">pc_status</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">]</span> <span style="color:var(--syntax-error-color)">==</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">200</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">:</span>
            <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">response</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">body</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">].</span><span style="color:var(--syntax-name-color)">decode</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">utf-8</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-declaration-color)">else</span><span style="color:var(--syntax-text-color)">:</span>
            <span style="color:var(--syntax-name-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Failed to fetch HTML. Crawlbase status code: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">response</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">headers</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">][</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">pc_status</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">]</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>
            <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">None</span>
    <span style="color:var(--syntax-declaration-color)">except</span> <span style="color:var(--syntax-text-color)">Exception</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">:</span>
        <span style="color:var(--syntax-name-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">f</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">An error occurred: </span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">str</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>
        <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">None</span>

<span style="color:var(--syntax-declaration-color)">def</span> <span style="color:var(--syntax-name-color)">scrape_comment_content</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">comment</span><span style="color:var(--syntax-text-color)">):</span>
    <span style="color:var(--syntax-text-color)">comment_content</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">comment</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">select_one</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">DivCommentContentContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] p[data-e2e=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">comment-level-1</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > span</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-text-color)">text</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">strip</span><span style="color:var(--syntax-text-color)">()</span>
    <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">comment_content</span>

<span style="color:var(--syntax-declaration-color)">def</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">():</span>

    <span style="color:var(--syntax-comment-color)"># Fetch HTML content of the TikTok video page
</span>    <span style="color:var(--syntax-text-color)">html_content</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">fetch_html_crawlbase</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">https://www.tiktok.com/@khaby.lame/video/7255327059302419738</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-comment-color)"># Parse HTML content using BeautifulSoup
</span>    <span style="color:var(--syntax-text-color)">soup</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">BeautifulSoup</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">html_content</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">html.parser</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-comment-color)"># Scrape comments listing
</span>    <span style="color:var(--syntax-text-color)">comments_listing</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">soup</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">select</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">div[data-e2e=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">search-comment-container</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">CommentListContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">] > div[class*=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">DivCommentItemContainer</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">]</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span>

    <span style="color:var(--syntax-comment-color)"># Iterate through comments and scrape comment content and commenter details
</span>    <span style="color:var(--syntax-text-color)">comments_list</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[]</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">comment</span> <span style="color:var(--syntax-error-color)">in</span> <span style="color:var(--syntax-text-color)">comments_listing</span><span style="color:var(--syntax-text-color)">:</span>
        <span style="color:var(--syntax-text-color)">comments_list</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">append</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">scrape_comment_content</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">comment</span><span style="color:var(--syntax-text-color)">))</span>

    <span style="color:var(--syntax-comment-color)"># Print the scraped results
</span>    <span style="color:var(--syntax-name-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">json</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">dumps</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">comments_list</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">indent</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">ensure_ascii</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">False</span><span style="color:var(--syntax-text-color)">))</span>

<span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">__name__</span> <span style="color:var(--syntax-error-color)">==</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">__main__</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">:</span>
    <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span>
</code></span></span>

它首先导入必要的库并使用身份验证详细信息初始化 Crawlbase CrawlingAPI 对象。它配置选项以等待 AJAX 内容、设置用户代理和指定移动设备。该fetch_html_crawlbase函数使用 Crawlbase 获取 TikTok 页面的 HTML 内容并检查响应状态。如果成功,它将返回 HTML 内容。该scrape_comment_content函数使用 BeautifulSoup 提取每个评论的文本。在主函数中,脚本获取并解析 HTML 内容,抓取评论列表并以 JSON 格式打印它们。执行时,脚本运行函数main以执行抓取并显示结果。

与Beautiful Soup的比较

Crawlbase Crawling API 简化了抓取动态内容的过程,特别是对于需要可扩展性和速度的项目。

最后的想法

抓取动态内容乍一看似乎很困难,但只要使用正确的工具和技术,它就会变得轻而易举。使用 Selenium 抓取动态内容并使用 Beautiful Soup 解析 HTML,您可以有效地抓取 JS 渲染的页面并提取有价值的信息。Selenium 允许您像人类用户一样浏览和与网页交互,使其成为处理 JavaScript 渲染元素的理想选择。Beautiful Soup 对此进行了补充,它提供了一个强大且易于使用的工具,用于解析和提取 Selenium 检索到的 HTML 内容中的数据。

Crawlbase Crawling API为那些追求简单性和可扩展性的人提供了一个绝佳的选择。它处理了抓取动态内容的许多复杂性,让您可以专注于最重要的事情:提取所需的数据。

经常问的问题

问:如何抓取动态生成的内容?

要抓取动态生成的内容,您需要能够处理 JavaScript 呈现的页面的工具。Selenium 是实现此目的的热门选择。它允许您自动化 Web 浏览器并像人类一样与 Web 元素交互。通过使用 Selenium,您可以在提取所需数据之前加载整个页面(包括动态内容)。

如果您想要大规模抓取数据而不被阻塞,您可以考虑使用像Crawlbase Crawling API这样的 API 。

问:如何在 Python 中获取动态内容?

通过使用 Selenium 来获取动态内容,可以在 Python 中实现动态内容。使用适当的浏览器选项启动所需的浏览器。然后,导航到网页,与必要的元素交互以加载动态内容,最后使用 Beautiful Soup 之类的库来解析和提取数据。

这是一个简单的例子:

highlight 复制代码
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">selenium</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">webdriver</span>
<span style="color:var(--syntax-error-color)">from</span> <span style="color:var(--syntax-text-color)">bs4</span> <span style="color:var(--syntax-error-color)">import</span> <span style="color:var(--syntax-text-color)">BeautifulSoup</span>

<span style="color:var(--syntax-comment-color)"># Chrome brower options
</span><span style="color:var(--syntax-text-color)">options</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ChromeOptions</span><span style="color:var(--syntax-text-color)">()</span>

<span style="color:var(--syntax-comment-color)"># Launch Chrome browser
</span><span style="color:var(--syntax-text-color)">driver</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">webdriver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">Chrome</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-text-color)">options</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">get</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">https://example.com</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Wait for the dynamic content to load
</span><span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">implicitly_wait</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">10</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Get the page source and parse it with Beautiful Soup
</span><span style="color:var(--syntax-text-color)">page_source</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">driver</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-text-color)">page_source</span>
<span style="color:var(--syntax-text-color)">soup</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">BeautifulSoup</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">page_source</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">html.parser</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>

<span style="color:var(--syntax-comment-color)"># Extract the dynamic content
</span><span style="color:var(--syntax-text-color)">dynamic_content</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">soup</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">find_all</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">div</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">class_</span><span style="color:var(--syntax-error-color)">=</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">dynamic-class</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">)</span>
</code></span></span>

如果你不想手动做事并且想要在大型抓取网站上抓取数据,你可以考虑使用Crawlbase Crawling API

问:如何从网站提取动态数据?

要从网站提取动态数据,请按照以下步骤操作:

  1. 使用 Selenium 或第三方 API :利用 Selenium / Puppeteer等工具或Crawlbase Crawling API等第三方 API加载网页。这些工具可以处理 JavaScript 渲染,确保显示所有动态内容。
  2. 检索页面源代码:动态内容完全加载后,检索页面源代码。这包括构成呈现内容的所有 HTML、CSS 和 JavaScript。
  3. 解析和提取数据:使用解析库或工具(例如 Python 中的 Beautiful Soup)来分析 HTML 并提取所需信息。这些工具可让您在 HTML 中定位特定元素并提取相关数据。

通过使用处理动态内容和 HTML 解析的工具,或者选择像 Crawlbase Crawling API 这样的综合解决方案,您可以有效地从使用 JavaScript 呈现数据的网站中抓取动态内容。

问:如何抓取动态 URL?

抓取动态 URL 涉及从网页中检索数据,网页内容会动态更改或更新,这通常是由 JavaScript 引起的。以下是一份简单的指南:

  1. 设置 :确保您拥有必要的工具,例如Selenium / PuppeteerCrawlbase Crawling API等 API 。
  2. 访问 URL:使用您选择的方法访问动态 URL。
  3. 处理动态性:如果内容根据用户交互或时间而变化,请确保您的抓取方法能够适应这种情况。Selenium 等工具通常具有等待元素加载或更改的功能。
  4. 提取数据:一旦动态内容加载完成,使用抓取工具提取所需的数据。
  5. 处理错误:为潜在错误做好准备,例如超时或丢失数据,并在抓取代码中妥善处理它们。

通过遵循这些步骤,您可以有效地从任何 URL 抓取动态内容,无论它是如何生成或更新的。

相关推荐
小白不太白95012 小时前
设计模式之 外观模式
microsoft·设计模式·外观模式
万里沧海寄云帆13 小时前
Word 插入分节符页码更新问题
windows·microsoft·word
互联网杂货铺18 小时前
自动化测试基础知识总结
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
huaqianzkh21 小时前
学习C#中的Parallel类
windows·microsoft·c#
懒笑翻1 天前
Python 使用 Selenuim进行自动化点击入门,谷歌驱动,以百度为例
运维·selenium·自动化
Code哈哈笑1 天前
【Java 学习】初识类和对象、this引用
java·学习·microsoft
code_shenbing1 天前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计
qq_433716951 天前
Selenium+Pytest自动化测试框架 ------ 禅道实战
自动化测试·软件测试·selenium·单元测试·pytest·接口测试·压力测试
LucianaiB2 天前
丹摩|丹摩助力selenium实现大麦网抢票
selenium·测试工具
HKJ_numb12 天前
软件测试 —— 自动化基础
软件测试·selenium·测试工具·自动化