我们使用联盟链接。它们让我们能够维持运营,而您无需承担任何费用。

使用 Selenium 进行网页抓取:初学者终极指南

使用 Selenium 进行网页抓取的分步指南。

网络抓取 Selenium

现代网站(如社交媒体)依赖于 JavaScript。不幸的是,传统脚本在从动态元素中提取信息时会遇到困难。这是因为您需要 JavaScript 来呈现整个页面,然后才能获取数据。Selenium 因其实现这一功能而广受欢迎 - 它可以像冠军一样处理异步加载或无限滚动。

本文将解释为什么您应该选择 Selenium 进行网页抓取以及如何增加成功请求的机会。您还将找到有关如何使用 Python 构建 Selenium 网页抓取器的分步教程。

什么是使用 Selenium 进行 Python Web 抓取?

Selenium 是一个网络抓取库,它控制 无头浏览器 以编程方式。它允许您打开网站、浏览网页、与嵌套在 JavaScript 中的元素交互以及提取它们以供进一步使用。如今,网站设计为可在笔记本电脑、平板电脑或智能手机等设备上使用。这些网站使用 客户端渲染 通过 JavaScript 来响应用户操作,例如鼠标点击和键盘输入。然而,这对网络抓取工具来说也是个坏消息——你必须处理延迟加载或浏览器指纹识别。使用常规 HTML 提取工具(如 Requests)抓取动态网站变得非常困难。另一方面,Selenium 模仿人类行为,因此成功提取数据的机会会增加。

为什么选择 Selenium 进行网页抓取?

Selenium 是网页抓取的热门选择,原因如下:

  • 能够呈现 JavaScript。 Selenium 主要用于浏览器自动化,这使得它非常适合抓取依赖 JavaScript 的网站。它将完全呈现目标网站并提取数据。
  • 跨浏览器支持。 Selenium 最好的一点是它可以模拟 Chrome、Firefox 和 Microsoft Edge 等主流浏览器。 
  • 支持多种编程语言。 它在编程语言方面也很灵活——您可以使用 Python、Java、Ruby 和 C#。 
  • 模拟用户行为。 使用 Selenium,您可以通过与网页交互来模仿人类行为,包括单击按钮、填写表格、提交数据、滚动和浏览页面。 
  • 处理 CAPTCHA。 一些网站使用 CAPTCHA 来防止类似机器人的活动。Selenium 可以通过在浏览器中显示这些测试并允许您解决它们或与第三方服务集成以自动化该过程来处理这些测试。
  • 防止指纹检测。 Selenium 有类似的软件包 硒隐形 隐藏您的数字指纹。正确配置后,它可以阻止登录或通过 reCAPTCHA。
  • 大型社区。 该图书馆有一个活跃的社区,这意味着有许多资源、教程和插件可用于简化您的体验。

虽然 Selenium 是用于网页抓取的强大工具,但它可能不是所有情况下最有效的选择。对于简单的抓取任务或处理静态网站时,其他库(如 BeautifulSoup 或 Requests)可能是更好的选择。此外,您还可以使用其他无头库,例如 木偶戏 占用更少的资源。然而,在处理复杂、动态的网站时,Selenium 的功能使其成为可靠的选择。

准备构建 Selenium Web 爬虫

选择项目构想并设计项目参数

构建 Selenium 网络抓取工具的第一步是设计项目参数。 

在使用 Selenium 进行网页抓取时,有多种编程语言可供选择。但决定使用哪一种可能很困难,因此我们 比较流行语言 最适合抓取任务(*Selenium 并不支持列表中的所有语言)。如果您仍然无法决定,请选择 Python – 它是最容易使用的语言之一,并且符合大多数项目要求。

您不需要额外的库来获取或解析数据,因为 Selenium 有自己的包和模块,涵盖所有 Web 抓取阶段。例如,如果您需要清理数据,您可以安装 selenium.by 模块。除此之外,Selenium 可以与其他强大的解析器完美配合,例如 美丽的汤.

现在,让我们开始讨论项目本身。您可以抓取亚马逊等真实目标,也可以在专门为抓取而创建的网站上练习您的技能。这样,您就可以在安全的环境中探索不同的技术、语言和工具。您可以在我们的 网络抓取沙箱列表

当你掌握了 Selenium 后,你可能会想把你的技能付诸实践。假设你想获得最优惠的航班;你可以建立一个抓取工具来收集价格并每天下载结果。如果你没有任何用例,你可以查看一份针对初学者和高级用户的创意列表 在我们的指南中

考虑网页抓取指南

虽然网络抓取可以用于许多目的,但仍需要遵循一定的道德和法律实践准则。

首先,尊重网站服务条款,不要抓取登录后的数据,这一点至关重要。这可能会给你带来法律麻烦。你可以在我们的文章中找到更多建议 网络抓取最佳实践.

此外,如果你不了解以下几点,网页抓取可能会变得很麻烦: 所有的挑战 网站会向您抛出各种障碍。从 CAPCHA 和 IP 地址禁令到结构性更改,这些障碍可能会干扰您的 Selenium 网络抓取工具。 

使用代理服务器

您需要多个 IP 地址来抓取网站数据。因此,请考虑设置一个 代理 使用 Selenium。这样,当您向目标网站发送连接请求时,您每次都会显示为新访问者。 

您很可能会倾向于使用免费代理列表,但如果您不想让任何人滥用您的个人信息,请坚持使用 付费提供商。提示:您应该检查提供商是否提供了有关使用 Selenium 进行代理设置的详尽技术文档。 

有多种类型的代理可供选择,但我们建议使用 住宅 地址。它们来自真实用户的设备,不可避免地会轮换,并且大多数服务都提供粘性会话以延长连接时间。 

如何使用 Selenium 进行网页抓取:分步教程

在本分步教程中,我们将从 quotes.toscrape.com 抓取两个 URL:
待抓取的引文
quotes.toscrape.com 网页。

两个链接都包含 JavaScript 生成的内容,第二个页面延迟渲染。为什么你需要学习如何处理延迟内容?有时页面需要一段时间才能加载,或者你需要等待特定元素(或条件)满足后才能提取数据。 

硬件需求

  • Python 3。 确保你的系统上安装了最新的 Python。你可以从官方网站下载 Python.org.
  • 硒。 使用以下方式安装 Selenium 包 点子. 打开命令提示符或终端并运行以下命令: 点安装硒.
  • Chrome WebDriver: 下载 Chrome 网络驱动程序 与您的 Chrome 浏览器相对应。

导入库

步骤 1。 按照以下步骤编写你的第一个 Selenium 脚本 说明. 注意: 我们将使用 Python 和 Chrome。因此,您需要将 Chrome WebDriver 添加到 路径 使浏览器能够与 Selenium 协同工作。 步骤 2。 然后,安装 Selenium。1)首先,导入 网络驱动程序 来自 Selenium 模块。
				
					from selenium import webdriver

				
			

2)然后使用 By 来自 Selenium 的选择器模块,用于简化元素选择。

				
					from selenium.webdriver.common.by import By

				
			

3) 在进行下一步之前,请确保已准备好暂停刮刀的所有元素。

				
					from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
				
			

4)由于我们将使用 CSV 模块,因此您也需要导入它。

				
					import csv

				
			

设置全局变量并查找所需元素

步骤 1。 现在,让我们设置全局变量,以便我们可以存储值:

  • 网址 – 您要抓取的页面;
  • 超时 – 如果页面加载时间超过超时时间,您的抓取将失败。因此,您需要指定超时时间以等待元素出现,然后再解决错误;
  • 产量 – 您要将抓取的引文写入其中的列表。
				
					url = 'http://quotes.toscrape.com/js/'
#url = 'http://quotes.toscrape.com/js-delayed/'
timeout = 10 #seconds

output = []
				
			

步骤 2。 然后,检查页面源代码 quotes.toscrape.com/js 右键单击页面上的任意位置。

引文-引文-html
检查网页。

步骤 3。 您需要选择所有引言类对象,并在其中找到以下类的文本:引言、作者和标签。您可以使用 Selenium By 模块来查找所有这些元素。

				
					quotes = driver.find_elements(By.CLASS_NAME, 'quote')

				
			

步骤 4。 对于引用文本和作者,使用 find_element() 函数 通过类名查找元素。然后提取文本并将其保存在变量中。

				
					for quote in quotes:
    text = quote.find_element(By.CLASS_NAME, 'text').text
    print (f'Text: {text}')
    author = quote.find_element(By.CLASS_NAME, 'author').text
    print (f'Author: {author}')
				
			

步骤 5。 由于每句引言可以有多个标签,因此你必须使用 查找元素() 函数来查找所有标签。然后,遍历每个标签并将其文本附加到 标签 名单。 

				
					    tags = []
    for tag in quote.find_elements(By.CLASS_NAME, 'tag'):
        tags.append(tag.text)
    print (tags)
				
			

最后,你可以将变量放入字典中,然后将其附加到 产量 您创建的列表。

				
					   output.append({
        'author': author,
        'text': text,
        'tags': tags,
    })
				
			

如果您的目标网站包含多个 URL,您可以使用 CSS 或 XPath 选择器来找到它们。

有关如何使用 Selenium 查找所有 URL 的分步指南。

您还可以通过文本查找元素:

有关如何使用 Selenium 通过文本查找元素的分步指南。

或者通过查看 ID 来找到它们:

有关如何使用 Selenium 通过 id 查找元素的分步指南。

使用 Python Selenium 抓取动态网页

步骤 1。 首先,您需要使用 Selenium 设置浏览器。在此示例中,我们将使用 Chromium。

				
					def prepare_browser():
    #Initializing Chrome options
    chrome_options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(options= chrome_options)

    return driver
				
			

注意: 如果需要添加 selenium_stealth 掩盖您的数字指纹或设置代理以避免速率限制,这里就是您要做的。如果您不知道如何使用 Python 设置 Selenium 代理,您可以参考我们的指南,其中将详细解释所有内容。 

有关如何使用 Python 设置和验证 Selenium 代理的分步指南。

步骤 2。 然后,写下 主() 函数。通过调用 准备浏览器() 函数并将其与 url 一起传递(http://quotes.toscrape.com/js/)到 新的 scrape() 函数结束后,驱动程序将退出,您可以打印出整个输出。
				
					def main():
    driver = prepare_browser()
    scrape(url, driver)
    driver.quit()
    print (output)

if __name__ == '__main__':
    main()
				
			

步骤 3。 现在,让我们开始抓取。使用 驱动程序.get(url) 函数,我们将告诉 Selenium 打开浏览器并转到该 URL。由于选择器已经准备好,因此只需粘贴代码即可。

				
					def scrape(url, driver):
    driver.get(url)
    quotes = driver.find_elements(By.CLASS_NAME, 'quote')
    for quote in quotes:
        text = quote.find_element(By.CLASS_NAME, 'text').text
        print (f'Text: {text}')
        author = quote.find_element(By.CLASS_NAME, 'author').text
        print (f'Author: {author}')
        tags = []
        for tag in quote.find_elements(By.CLASS_NAME, 'tag'):
            tags.append(tag.text)
        print (tags)
        output.append({
            'author': author,
            'text': text,
            'tags': tags,
        })
				
			

这将打开浏览器窗口,抓取一页,将抓取的文本打印到控制台并在脚本运行完成后打印整个输出。

控制台输出示例:

				
					Opened: http://quotes.toscrape.com/js/
Text: “The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”
Author: Albert Einstein
['change', 'deep-thoughts', 'thinking', 'world']
Text: “It is our choices, Harry, that show what we truly are, far more than our abilities.”
Author: J.K. Rowling
['abilities', 'choices']
Text: “There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a 
miracle.”
Author: Albert Einstein
['inspirational', 'life', 'live', 'miracle', 'miracles']
Text: “The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”
Author: Jane Austen
['aliteracy', 'books', 'classic', 'humor']
Text: “Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”
Author: Marilyn Monroe
['be-yourself', 'inspirational']
Text: “Try not to become a man of success. Rather become a man of value.”
Author: Albert Einstein
['adulthood', 'success', 'value']
				
			

列表中输出的示例: 

				
					[{'author': 'Albert Einstein', 'text': '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”', 'tags': ['change', 'deep-thoughts', 'thinking', 'world']}, {'author': 'J.K. Rowling', 'text': '“It is our choices, Harry, that show what we truly are, far more than our abilities.”', 'tags': ['abilities', 'choices']}, {'author': 'Albert Einstein', 'text': '“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”', 'tags': ['inspirational', 'life', 'live', 'miracle', 'miracles']}, {'author': 'Jane Austen', 'text': '“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”', 'tags': ['aliteracy', 'books', 'classic', 'humor']}, {'author': 'Marilyn Monroe', 'text': "“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”", 'tags': ['be-yourself', 'inspirational']}, {'author': 'Albert Einstein', 'text': '“Try not to become a man of success. Rather become a man of value.”', 'tags': ['adulthood', 'success', 'value']}
				
			

抓取多个页面

步骤 1。 首先,找到带您进入下一页的链接。检查 HTML;链接位于类为“next”的列表项下。查找该元素内的标签。

在第二行中,查找 HREF 从元素中获取下一页的 URL,并将其分配给 下一个网址 变量。

最后,致电 刮() 再次运行该函数并将新的 URL 传递给它,以便与 Webdriver 一起进行抓取。

				
					elem_next = driver.find_element(By.CLASS_NAME, 'next').find_element(By.TAG_NAME,'a')
next_url = elem_next.get_attribute("href")
scrape(next_url, driver)
				
			
引言-下一个

步骤 2。 现在,脚本将能够处理分页并抓取整个类别。但是,它仍然不知道何时停止,并且会在最后一页崩溃,因为带有类的元素 下页 不会出现。

您可以将代码包装在 尝试除外 阻止以防止崩溃,并且如果需要,在到达最后一个之后在页面上执行其他操作。

				
					<try:
    elem_next = driver.find_element(By.CLASS_NAME, 'next').find_element(By.TAG_NAME,'a')
    next_url = elem_next.get_attribute("href")
    scrape(next_url, driver)
except:
    print('Next button not found. Quitting.')
				
			
JavaScript 加载或生成元素可能需要一些时间。并且您不想在此之前开始解析输出。例如, http://quotes.toscrape.com/js-delayed/ 引入 10 秒的延迟。如果您要搜索的元素尚未加载,则脚本将失败。在这种情况下,您可以告诉 Webdriver 等待元素出现。最简单的方法是使用 Selenium 网络驱动程序等待 类。 步骤 1。  首先,你需要传递 Webdriver 和超时变量(在一开始就创建),并等待具有类名的可见元素 报价 在页面上。然后你就可以开始解析了。还有更多 您可以使用的条件。 
				
					WebDriverWait(driver, timeout).until(
     expected_conditions.presence_of_element_located((By.CLASS_NAME, 'quote'))
        )
				
			

步骤 2。 您还可以将上面的代码放在 尝试除外 块。这样,如果代码超时或没有元素 报价 类出现在页面中,您可以重试相同的请求。

现在,你的抓取功能已经完成:

				
					def scrape(url, driver):
    driver.get(url)
    print (f"Opened: {driver.current_url}")
    try:
        WebDriverWait(driver, timeout).until(
            expected_conditions.presence_of_element_located((By.CLASS_NAME, 'quote'))
        )
        # Finding all elements with a class of 'quote' in the page
        quotes = driver.find_elements(By.CLASS_NAME, 'quote')
        for quote in quotes:
            text = quote.find_element(By.CLASS_NAME, 'text').text
            print (f'Text: {text}')
            author = quote.find_element(By.CLASS_NAME, 'author').text
            print (f'Author: {author}')
            tags = []
            for tag in quote.find_elements(By.CLASS_NAME, 'tag'):
                tags.append(tag.text)
            print (tags)
            output.append({
                'author': author,
                'text': text,
                'tags': tags,
            })
        try:
            elem_next = driver.find_element(By.CLASS_NAME, 'next').find_element(By.TAG_NAME,'a')
            next_url = elem_next.get_attribute("href")
            scrape(next_url, driver)
        except:
            print('Next button not found. Quitting.')
    except:
        print ('Timed out.')
				
			

将输出保存为 CSV

最后,你可以将输出写入 CSV 文件(使用 CSV 库)通过向 主() 函数。为此,我们需要一个名为 output_filename 的新变量。 

				
					field_names = ['author', 'text', 'tags']
    output_filename = 'quotes.csv'
    with open (output_filename, 'w', newline='', encoding='utf-8') as f_out:
        writer = csv.DictWriter(f_out, fieldnames = field_names)
        writer.writeheader()
        writer.writerows(output)
				
			

上面的代码创建文件,写入 字段名称 列表作为 CSV 标头。然后,它会使用输出列表中的字典对象填充文件。

引文-csv.PNG
CSV 文件。

以下是完整脚本:

				
					from selenium import webdriver
# Using By to simplify selection
from selenium.webdriver.common.by import By
# The latter two will be used to make sure that needed elements are present 
# Before we begin scraping
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
# For writing output to a CSV file
import csv


url = 'http://quotes.toscrape.com/js/'
#url = 'http://quotes.toscrape.com/js-delayed/'
timeout = 20 #seconds

output = []

def prepare_browser() -> webdriver:
    # Initializing Chrome options
    chrome_options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(options= chrome_options)
    return driver

def scrape(url: str, driver: webdriver) -> None:
    driver.get(url)
    print (f"Opened: {driver.current_url}")
    try:
        WebDriverWait(driver, timeout).until(
            expected_conditions.presence_of_element_located((By.CLASS_NAME, 'quote'))
        )
        # Finding all elements with a class of 'quote' in the page
        quotes = driver.find_elements(By.CLASS_NAME, 'quote')
        for quote in quotes:
            text = quote.find_element(By.CLASS_NAME, 'text').text
            print (f'Text: {text}')
            author = quote.find_element(By.CLASS_NAME, 'author').text
            print (f'Author: {author}')
            tags = []
            for tag in quote.find_elements(By.CLASS_NAME, 'tag'):
                tags.append(tag.text)
            print (tags)
            output.append({
                'author': author,
                'text': text,
                'tags': tags,
            })
        try:
            elem_next = driver.find_element(By.CLASS_NAME, 'next').find_element(By.TAG_NAME,'a')
            next_url = elem_next.get_attribute("href")
            scrape(next_url, driver)
        except:
            print('Next button not found. Quitting.')
    except:
        print ('Timed out.')

def main() -> None:
    driver = prepare_browser()
    scrape(url, driver)
    driver.quit()
    print (output)
    # CSV
    field_names = ['author', 'text', 'tags']
    output_filename = 'quotes.csv'
    with open (output_filename, 'w', newline='', encoding='utf-8') as f_out:
        writer = csv.DictWriter(f_out, fieldnames = field_names)
        writer.writeheader()
        writer.writerows(output)

if __name__ == '__main__':
    main()
				
			
Adam Dubois 的图片
亚当·杜波依斯
代理极客和开发人员。