如何加快网络抓取速度

利用优化技术、代理使用和 API 解决方案加快网络搜索速度。了解如何避免速度减慢并高效提取数据。
Diagram showing a central processing unit connected to laptops and outputting data in HTML, JSON, and CSV formats.

网络抓取是一种强大的方法,可以让你从网站上收集数据,并将分散的非结构化信息转化为可操作的洞察力。但是,如果您不知道如何高效地进行网络搜索,这个过程往往会变得缓慢、令人沮丧,而且容易遇到各种挑战,如 IP 禁止、速率限制和服务器问题。

在本指南中,您将学习如何识别和克服可能导致网络搜索过程变慢的常见问题。

研究降低网络抓取速度的因素

当您开始刮擦更大的数据集时,您会遇到一些令人沮丧的挑战,从而减慢您的进程。常见的罪魁祸首包括以下几点:

  • 高延迟:随着数据量的增加,请求往返服务器所需的时间也会增加。在搜索单个页面时,一秒钟的延迟可能没什么问题,但在搜索数百甚至数千个页面时,延迟就会变得更加明显。了解延迟及其来源可以帮助您确定需要优化的地方。有关高效 Python 搜刮设置的更多信息,请参阅我们的《使用 Python 进行网络搜刮》指南。
  • 比率限制和验证码:你有没有试过在搜刮网站时被验证码击中?这就是速率限制的作用。网站使用这些限制来阻止人们过快地提出过多请求。如果网站认为您的请求过于频繁,验证码可能会被用作一种防御措施,从而减缓您的搜刮努力。
  • 服务器拦截:网站越来越善于发现自动搜索器。如果他们认为你是一个机器人,他们可能会完全屏蔽你的 IP 地址。有效使用代理可以帮助你避免被发现–学习如何使用 Python代理来提高你的搜刮成功率。
  • 复杂的网站结构:结构复杂、有大量动态渲染内容或 JavaScript 框架繁重的网站可能会给刮擦带来挑战。从复杂网站提取数据可能需要额外的工具和策略,从而增加了刮擦所需的时间和精力。要为此类任务选择合适的 HTTP 客户端,请查看此Python HTTP 客户端比较。

加速网络抓取

为了帮助您学习如何加快网络刮擦过程,本教程将教您如何刮擦Open Library(一个提供可扩展图书记录目录的网站)。

注意:在刮擦任何网站之前,请确保查看并遵守网站的隐私政策和使用条款。许多网站都有明确的禁止搜刮的规定,遵守这些政策至关重要。

了解和检查目标网页

在本教程中,您将为开放图书馆创建一个可提取有关鸟类书籍的搜索器。

首先需要检查网页元素,以确定 HTML 结构。为此,你可以右键单击网页的任何元素,然后选择 “检查“。这将打开浏览器的 “开发工具“,在这里你可以看到与网页各部分相关的 HTML 标记:

要抓取书名,需要检查页面并查看每个书名是否包含在特定结构中的 <h3>标记内的特定结构。

设置扫描环境

检查完页面的 HTML 之后,您需要设置一个 Python 环境。确保已安装Python 3.x 或更新版本,并在项目目录下创建一个虚拟环境:

python -m venv venv

要激活环境,在 macOS 和 Linux 上运行源程序 venv/bin/activate,在 Windows 上运行venv\Scripts\activate即可。

激活环境后,安装以下库:

pip install requests beautifulsoup4

Requests用于向目标网站发送 HTTP 请求,Beautiful Soup用于解析网页的 HTML 内容。

执行基本网络抓取:顺序方法

为了演示手动搜索的工作原理,让我们来看看一个基本的搜索脚本。在搜索页面上搜索 “鸟类 “时,下面的代码会抓取返回的前 50 个页面。然后将它们保存到一个文件中:

import requests
from bs4 import BeautifulSoup
import time
# Create/open a file to write the titles
with open('book_titles.txt', 'w', encoding='utf-8') as f:
start_time = time.time()
# Loop through the first 50 pages
for page in range(1, 51):
url = f"https://openlibrary.org/search?q=birds&mode=everything&page={page}"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
# Extract book titles from the current page
for book in soup.select('h3 > a'):
title = book.text
f.write(title + '\n')
print(f"{(time.time() - start_time):.2f} seconds")

该脚本使用 Requests 和 Beautiful Soup 库从开放图书馆网站上抓取与鸟类相关的书名。它向每个页面发送 HTTP GET 请求,使用select()方法提取书名,以找到 <a>标签嵌套在 <h3>标签,并将书名保存到名为book_titles.txt 的文件中。时间库测量整个搜索过程所需的时间。

要运行该脚本,请将其保存到名为app.py的文件中,然后在 75 Mbps 的连接上使用python app.py执行该脚本。该脚本耗时约 164 秒。请注意,这个时间可能因您的网络速度和硬件而异。

这种方法虽然简单,但由于每个请求都是按顺序发送的,因此速度会相当慢。此外,由于没有重试或优化,这种方法很容易受到 IP 屏蔽或速率限制等问题的影响。

应用优化

为了加快扫描过程并使其更加可靠,让我们应用一些优化技术:

使用 aiohttp 和 asyncio 执行并发请求

您可以并发地发送请求,而不是按顺序发送请求,以减少刮擦时间。Pythonaiohttp库是一个类似于 Requests 的 HTTP 客户端,允许你发送异步非阻塞 HTTP 请求。与管理异步操作的asyncio 结合使用,您可以高效地同时发送多个请求。

要使用 Python aiohttp 和 asyncio 库发送多个请求,首先要安装 aiohttp:

pip install aiohttp

下面是使用 aiohttp 和 asyncio 的优化版刮擦代码:

import aiohttp
import asyncio
from bs4 import BeautifulSoup
import time
async def fetch_and_process_page(session, url):
async with session.get(url) as response:
html = await response.text()
soup = BeautifulSoup(html, 'html.parser')
return [book.text for book in soup.select('h3 > a')]
async def main():
start_time = time.time()
async with aiohttp.ClientSession() as session:
with open('book_titles.txt', 'w', encoding='utf-8') as f:
# Create and execute tasks for all pages
tasks = [
fetch_and_process_page(session, url = f"https://openlibrary.org/search?q=birds&mode=everything&page={page}")
for page in range(1, 51)
]
results = await asyncio.gather(*tasks)
# Write all titles at once
for titles in results:
for title in titles:
f.write(title + '\n')
print(f"{(time.time() - start_time):.2f} seconds")
asyncio.run(main())

要运行这段代码,请创建一个名为async_scraper.py的新文件,并使用python async_scraper.py 运行它。

你会发现,与单请求方法相比,使用aiohttp大大缩短了刮擦时间。这次测试只用了 14.39 秒。

轮流使用代理服务器,避免 IP 堵塞

如果来自同一 IP 地址的请求过多,网站通常会阻止这些请求。避免这种情况的常用方法是使用代理,它是计算机和互联网之间的中介。它可以屏蔽你的 IP 地址,使你的请求看起来像是来自不同的地方。

为了进一步加强这一点,您可以使用轮流代理,将您的请求分配到多个 IP 上。在这种情况下,每个请求看起来都来自不同的 IP 地址,从而大大降低了被拦截的可能性。

您可以在网上找到免费的代理服务,或者使用从精心挑选的列表中返回免费代理服务的图书馆。请记住,免费代理服务会被许多用户共享,从而增加了被屏蔽的几率。要想获得更可靠、更高效的搜索结果,建议使用托管代理服务。这些服务提供旋转代理,可将您的请求自动分配到大量 IP 地址池中,确保更高的成功率和更快的性能。

下面是如何修改前面的脚本,以使用简单的旋转代理设置:

import requests
import random
from bs4 import BeautifulSoup
# List of proxies
proxies = [
"http://username:password@proxy1.provider.com:port",
"http://username:password@proxy2.provider.com:port",
"http://username:password@proxy3.provider.com:port"
]
# Loop through pages with rotating proxies
for page in range(1, 51):
url = f"https://openlibrary.org/search?q=birds&mode=everything&page={page}"
proxy = random.choice(proxies)
response = requests.get(url, proxies={"http": proxy, "https": proxy})
soup = BeautifulSoup(response.text, 'html.parser')
for book in soup.select('h3 > a'):
print(f"Scraped: {book.text}")

这段代码定义了一个代理列表,并使用 random.choice()函数为每个请求随机选择一个代理。这种方法可以让你轮流使用不同的代理服务器,大大降低了被拦截的风险。

轮流使用代理服务器对扫描大量数据尤其有用,因为它们能确保您的请求看起来来自不同的用户,从而使服务器更难将您识别为机器人。

添加重试逻辑

刮擦时,有些请求可能会因网络问题或速率限制而失败。实施自动重试可以帮助您使您的刮擦程序更加强大。

下面是一个如何使用请求库添加重试逻辑的示例:

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from bs4 import BeautifulSoup
session = requests.Session()
retry = Retry(total=5, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
url = "https://openlibrary.org/search?q=birds&mode=everything&page=1"
response = session.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
# Extract book titles
for book in soup.select('h3 > a'):
print(f"Scraped: {book.text}")

此代码片段使用了urllib3中的重试功能,以指数式延迟重试失败的请求,最多可重试五次。这意味着,如果请求失败,重试前会等待一段时间,每次失败都会增加等待时间。这种方法有助于确保临时问题(如网络故障或速率限制)不会完全阻止你的刮擦过程。

使用托管网络抓取器 API

虽然前面的优化很有用,但管理重试、代理和速率限制可能会很繁琐和耗时。或者,您可以使用受管理的Web Scraper API,它可以自动处理代理、绕过验证码并管理速率限制,从而无需人工干预并降低复杂性。API 专为可扩展性而设计,可以同时抓取数千个 URL,而不会有服务器封禁的风险。它还提供 JSON 或 CSV 等结构化格式的数据,便于将结果直接集成到您的项目中。

通过使用这种应用程序接口,您可以将更多精力放在分析数据和提取见解上,而不是维护刮擦基础设施。

使用预先收集的数据集节省时间

除了使用受管理的刮擦 API 外,您还可以使用预先收集的数据集进一步简化数据收集流程。这些数据集由 LinkedIn、亚马逊、Twitter 和 Airbnb 等一百多个热门网站汇编而成,涵盖了广泛的主题,可为您提供干净、随时可用的数据。利用这些数据集,您可以专注于分析数据和提取见解,同时避免数据收集的复杂性。

结论

要加快网络搜刮速度,需要结合技术优化和智能工具。在本指南中,您将探索以下内容:

  • 刮削工作流程中的常见瓶颈
  • 并发请求、重试和代理轮换等优化技术
  • 受管理的 Web Scraper API 如何自动执行验证码和代理轮换等任务,以实现快速、可扩展的刮擦

无论您是独自工作还是在数据团队中工作,利用先进的工具和策略都能提高网络搜索流程的速度和可靠性。通过将高效的编码实践与托管服务相结合,您可以专注于真正重要的事情–从数据中提取可行的见解。

常见问题

哪些因素会降低网络搜刮速度?

有几个因素会降低网络搜刮速度,包括页面加载时间过长、JavaScript 过重的网站、速率限制、验证码和低效的搜刮代码。优化这些方面可以提高搜刮速度。

如何加快网络搜刮速度?

您可以通过使用异步请求、旋转代理、缓存数据、尽量减少不必要的请求以及利用无头浏览器或 API 来加快网络搜刮速度。

代理在网络搜刮中的作用是什么?

代理有助于将请求分发到多个 IP 地址,从而降低被拦截的几率。轮流使用代理服务器可以提高速度,并改善对受限内容的访问。

我应该使用网络搜刮 API 而不是构建自己的搜刮器吗?

使用受管理的网络搜刮 API 可以节省时间和资源,因为它可以处理 IP 轮换、绕过验证码并确保可靠的数据提取,而无需大量编码。

Leave a Comment

Required fields are marked *

A

You might also be interested in: