返回博客
指南
拉卢卡·彭丘克2021年8月13日阅读时间:7分钟

如何用不到 100 行代码构建网络爬虫

如何用不到 100 行代码构建网络爬虫

什么是网络爬虫

现在有许多搜索引擎,我们都在使用它们。它们的服务简单易用--你只需询问一些问题,它们就会在网络上四处为你寻找答案。在幕后,是谷歌的 Googlebot 爬虫让谷歌的搜索引擎如此成功。

爬虫根据输入的关键字扫描网页,帮助搜索引擎对这些网页进行编目,并在以后通过索引返回。搜索引擎依靠爬虫收集网站信息,包括 URL、超链接、元标记和文章,以及检查 HTML 文本。

由于机器人能够跟踪它已经访问过的内容,因此你不必担心它会无限期地停留在同一个网页上。公共互联网和内容选择给网络爬虫带来了诸多挑战。现有网站每天都会发布几十条新信息,而每天出现的新网站更是数不胜数。

最终,这将要求它们搜索数百万个网页,并不断刷新索引。分析网站内容的系统依赖于它们,因此它们是必不可少的。

所以,爬虫很重要,但为什么要提到它们呢?因为我们将建立自己的机器人,帮助完成数据提取过程。这样,我们就可以依靠它来获取 URL,而不是手动将它们输入到爬虫中。自动化程度更高

安装

既然我们已经对网络爬虫有了基本的了解,你可能会想知道这一切是如何实现的。好吧,让我们深入了解一下!

首先,我们需要设置工作环境。确保您的机器符合以下先决条件:

  • python3
  • Python IDE。本指南将使用Visual Studio Code,因为它很轻便,不需要任何额外配置。代码仍然与集成开发环境无关,因此您可以选择任何适合自己的集成开发环境;

最后,我们需要一个 API 密钥。您可以创建一个免费的 WSA 账户,该账户将在前 14 天内为您提供 5000 次 API 调用。注册后,只需导航到您的仪表板,即可找到 API 密钥和其他有价值的资源。

“设置”页面显示了一个 API 访问密钥字段,该字段带有复制图标和重置密钥选项

开发爬虫

很好,我们有了工具,离开始构建爬虫也就更近了。但我们该如何使用它呢?根据我们的最终目标,其实现方式可能会有所不同。

选择一个网站并检查 HTML

在本教程中,我们选择了一个销售不同用途的零废弃产品的电子商务网站。我们将浏览所有页面,提取每个页面的产品列表,最后将每个页面的数据存储到 CSV 文件中。

为此,我们必须先查看页面结构,然后决定我们的策略。右键单击页面上的任意位置,然后单击 "检查元素","开发者控制台 "就会弹出。在这里,你可以看到网站的 HTML 文档,其中包含我们需要的所有数据。

已打开带有开发者工具的电子商务产品页面,并显示了“检查元素”的上下文菜单

构建爬虫

好了,现在我们可以写一些代码了!

首先,在您的集成开发环境中打开一个终端窗口,然后运行以下命令,这样就可以安装 BeautifulSoup 库,它可以帮助我们从 HTML 中提取数据:

> pip install beautifulsoup4

然后,创建一个名为 "产品 "的文件夹。这将有助于整理和存储多个 CSV 文件中的搜索结果。

最后,创建 "crawler.py "文件。我们将在此编写所有代码和爬行逻辑。完成后,我们可以用以下命令执行该文件:

> py crawler.py

接下来,让我们导入我们需要的库,然后定义一些全局变量:

import requests
from bs4 import BeautifulSoup
import csv
 
BASE_URL = "https://www.shopetee.com"
SECTION = "/collections/all-collections"
FULL_START_URL = BASE_URL + SECTION

ENDPOINT = "https://api.webscrapingapi.com/v1/"
API_KEY = "API_KEY"

现在,让我们定义爬虫的入口点:

def crawl(url, filename):
    page_body = get_page_source(url, filename)
    soup = BeautifulSoup(page_body, 'html.parser')
    start_crawling(soup, filename)

crawl(FULL_START_URL, 'etee-page1.txt')

我们实现的抓取函数将通过get_page_source过程提取 HTML 文档。然后,它将构建 BeautifulSoup 对象,使我们的解析工作更轻松,并调用start_crawling函数,开始浏览网站。

def get_page_source(url, filename):
    params = {
        "api_key": API_KEY,
        "url": url,
        "render_js": '1'
    }
    page = requests.request("GET", ENDPOINT, params=params)
    soup = BeautifulSoup(page.content, 'html.parser')
    body = soup.find('body')

    file_source = open(filename, mode='w', encoding='utf-8')
    file_source.write(str(body))
    file_source.close()

    return str(body)

As stated earlier, the get_page_source function will use WebScrapingAPI to get the HTML content of the website and will write in a text file in the <body> section, as it’s the one containing all the information we are interested in.

现在,让我们退后一步,看看如何实现我们的目标。产品是按页面组织的,因此我们需要反复访问每个页面才能将它们全部提取出来。

这意味着,只要有可用页面,我们的爬虫就会采取一些递归步骤。要将这一逻辑写入代码,我们需要看看 HTML 是如何描述这些条件的。

如果回到开发人员控制台,可以看到每个页码实际上都是指向新页面的链接。不仅如此,考虑到我们正处于第一页,而且在此之前没有任何其他页面,左箭头被禁用了。

开发者工具在 HTML 中高亮显示分页的“下一页”链接元素

因此,必须采用以下算法:

  • 访问页面;
  • 提取数据(我们将在下一步中实现);
  • 查找 HTML 文档中的分页容器;验证 "Next Page(下一页)"箭头是否被禁用,如果是,则停止;如果不是,则获取新链接并调用抓取新页面的功能。
def start_crawling(soup, filename):

    extract_products(soup, filename)

    pagination = soup.find('ul', {'class': 'pagination-custom'})
    next_page = pagination.find_all('li')[-1]
    
    if next_page.has_attr('class'):
        if next_page['class'] == ['disabled']:
            print("You reached the last page. Stopping the crawler...")
    else:
        next_page_link = next_page.find('a')['href']
        next_page_address = BASE_URL + next_page_link
        next_page_index = next_page_link[next_page_link.find('=') + 1]
        crawl(next_page_address, f'etee-page{next_page_index}.txt')

提取数据并导出为 CSV

最后,让我们看看如何提取所需的数据。我们再看一眼 HTML 文档,就会发现我们可以通过查看类名来获取有价值的信息。

开发工具会在商品列表中突出显示评论数量和价格等产品元数据

我们将提取产品的名称、评级、评论数量和价格,但您也可以根据自己的需要进行提取。

还记得我们之前创建的 "产品 "文件夹吗?现在我们将创建一个 CSV 文件,导出我们从每个页面抓取的数据。文件夹将帮助我们把它们组织在一起。

def extract_products(soup, filename):
    csv_filename = filename.replace('.txt', '.csv')
    products_file = open(f'products/{csv_filename}', mode='a', encoding='utf-8', newline='')
    products_writer = csv.writer(products_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    products_writer.writerow(['Title', 'Rating', 'Reviews', 'Price on sale'])

    products = soup.find_all('div', {'class': 'product-grid-item'})
    for product in products:
        product_title = product.find('div', {'class': 'item-title'}).getText().strip()
        product_rating = product.find('span', {'class': 'jdgm-prev-badge__stars'})['data-score']
        product_reviews = product.find('span', {'class': 'jdgm-prev-badge__text'}).getText().strip()
        product_price_on_sale = product.find('span', {'class': 'money'}).getText()
        products_writer.writerow([product_title, product_rating, product_reviews, product_price_on_sale])

运行程序后,你可以在新创建的文件中看到所有提取的信息。

包含评分、评论数和售价列的爬取产品标题电子表格

结束语

差不多就是这样!我们刚刚使用 Python 的 BeautifulSoup 和 WebScrapingAPI 制作了自己的网络爬虫,只用了不到 100 行代码。当然,这可能会根据任务的复杂程度而有所不同,但对于一个能浏览网站页面的爬虫来说,这已经是相当不错的了。

在本指南中,我们使用了WebScrapingAPI 的免费试用版,前 14 天可调用 5000 次 API,足以构建一个功能强大的爬虫。  

只关注爬虫的逻辑,而不是担心网络搜刮中遇到的各种难题,这对我们很有帮助。这为我们节省了时间、精力和大量其他费用,例如使用我们自己的代理,而这只是使用 API 进行网络抓取所能获得的一些优势。

关于作者
Raluca Penciuc,WebScrapingAPI 全栈开发工程师
Raluca Penciuc全栈开发工程师

Raluca Penciuc 是 WebScrapingAPI 的全栈开发工程师,主要负责开发爬虫、优化规避机制,并探索可靠的方法以降低在目标网站上的被检测概率。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网页数据。