Bỏ để qua phần nội dung

Làm thế nào để cạo tìm kiếm Algolia

Đây là bài đăng trên blog hơn 2000 từ về "Cách tìm kiếm Algolia":

Giới thiệu

Algolia là một API tìm kiếm phổ biến hỗ trợ chức năng tìm kiếm cho nhiều trang web trên internet. Nó cho phép các trang web thực hiện tìm kiếm nhanh chóng và phù hợp mà không cần phải tự chạy cơ sở hạ tầng tìm kiếm phức tạp.

Một số ví dụ về các trang web phổ biến sử dụng Algolia bao gồm:

  • Reddit
  • Trung bình
  • GitHub
  • StackOverflow
  • HackerTin tức

Mục tiêu của bài viết này là để giải thích:

  1. Algolia là gì và nó hoạt động như thế nào
  2. Cách xóa kết quả tìm kiếm Algolia bằng Python
  3. Kỹ thuật cạo Algolia hiệu quả trên quy mô lớn
  4. Làm thế nào để tránh bị chặn khi cạo Algolia

Cuối cùng, bạn sẽ hiểu cách xây dựng một công cụ quét web Algolia có thể mở rộng cho bất kỳ trang web nào sử dụng nó.

Algolia là gì?

Algolia là API tìm kiếm được lưu trữ cung cấp các dịch vụ như lập chỉ mục, tìm kiếm và đề xuất. Nó thường được gọi là nhà cung cấp Tìm kiếm dưới dạng dịch vụ (SaaS).

Các đề xuất giá trị chính của Algolia bao gồm:

  • Tìm nhanh – Algolia tuyên bố có thể tìm kiếm trên hàng tỷ bản ghi trong thời gian dưới 100 mili giây. Đây là mức độ nhanh hơn rất nhiều so với việc thực hiện tìm kiếm trên cơ sở hạ tầng của riêng bạn.

  • tìm kiếm có liên quan – Algolia xử lý những thứ như lỗi đánh máy, từ đồng nghĩa và học tập dựa trên hành vi của người dùng để trả về kết quả phù hợp nhất.

  • Dịch vụ lưu trữ – Algolia đảm nhận những việc như mở rộng quy mô và dự phòng. Không có cơ sở hạ tầng để bạn quản lý.

  • Truy cập API – Chức năng tìm kiếm có thể được truy cập thông qua API cho phép tích hợp dễ dàng vào các trang web, ứng dụng di động, v.v.

Algolia cung cấp thư viện máy khách cho hầu hết các ngôn ngữ và khung chính xử lý giao tiếp API. Ở giao diện người dùng, các nhà phát triển thêm mã JavaScript vào giao diện với API của Algolia.

Vì vậy, tóm lại, Algolia cung cấp tính năng tìm kiếm được lưu trữ và có thể mở rộng thông qua API. Điều này cho phép các trang web xây dựng tìm kiếm tuyệt vời một cách nhanh chóng mà không cần phải tự xây dựng các hệ thống phức tạp.

Quét tìm kiếm Algolia bằng Python

Bây giờ chúng ta đã hiểu Algolia là gì, hãy xem cách chúng ta có thể thu thập kết quả tìm kiếm Algolia bằng Python.

Việc quét Algolia rất đơn giản vì API được công khai và ghi lại. Chúng tôi chỉ cần:

  1. Xác định điểm cuối và tham số API
  2. Trích xuất mọi khóa truy cập
  3. Gửi yêu cầu tìm kiếm và phân tích phản hồi JSON

Chúng ta hãy xem qua một ví dụ hoàn chỉnh về việc quét một trang web do Algolia cung cấp.

Tìm điểm cuối API

Đầu tiên, chúng ta cần tìm endpoint API được trang web sử dụng để tìm kiếm. Cách dễ nhất là mở trang web trong trình duyệt của bạn, chạy truy vấn tìm kiếm và kiểm tra các yêu cầu mạng trong công cụ dành cho nhà phát triển.

Ví dụ: trên HackerTin tức chúng tôi thấy một yêu cầu được thực hiện tới:

https://hn.algolia.com/api/v1/search?query=python

Sản phẩm /api/v1/search path cho biết đây là API tìm kiếm Algolia. Chúng tôi cũng thấy cụm từ tìm kiếm python được chuyển dưới dạng tham số truy vấn.

Bằng cách kiểm tra phản hồi, chúng ta có thể thấy nó trả về JSON cùng với kết quả. Bây giờ chúng ta đã biết điểm cuối API và tham số tìm kiếm sẽ sử dụng.

Lấy khóa API

Tiếp theo, chúng ta cần lấy khóa API cần thiết để xác thực. Kiểm tra lại yêu cầu mạng, chúng ta có thể thấy nó được chuyển qua X-Algolia-API-Key tiêu đề.

Chúng tôi có thể trích xuất khóa API này và thêm nó vào các yêu cầu của mình. Một số kỹ thuật đảo ngược bổ sung có thể được yêu cầu nếu khóa bị xáo trộn trong JavaScript.

Thực hiện yêu cầu tìm kiếm

Với điểm cuối và khóa API, giờ đây chúng ta có thể thực hiện các yêu cầu tìm kiếm bằng Python:

import requests 

api_key = "abc123" # Extracted key 

search_url = "https://hn.algolia.com/api/v1/search"

params = {
  ‘query‘: ‘python‘,
  ‘hitsPerPage‘: 100, 
  ‘attributesToSnippet‘: [‘title:10‘]
}

headers = {
  "X-Algolia-API-Key": api_key
}

response = requests.get(search_url, params=params, headers=headers)
data = response.json()

print(data[‘hits‘])

Chúng tôi thực hiện yêu cầu GET tới điểm cuối API chuyển cụm từ tìm kiếm, số lần truy cập trên mỗi trang và tiêu đề khóa API. Kết quả chứa các lần truy cập tìm kiếm dưới dạng JSON mà chúng tôi có thể phân tích cú pháp và xử lý khi cần.

Và bây giờ chúng ta đã có một dụng cụ cạo Algolia cơ bản!

Quét các trang bổ sung

Một hạn chế là API chỉ trả về trang kết quả đầu tiên. Để có được các trang bổ sung, chúng tôi cần phải vượt qua page tham số tăng từ 0:

# First page
params[‘page‘] = 0 

# Second page
params[‘page‘] = 1 

# Third page
params[‘page‘] = 2

Để loại bỏ tất cả các trang, chúng tôi có thể lặp lại việc thực hiện các yêu cầu tăng số trang cho đến khi không còn kết quả nào được trả về.

Đặt cái này lại với nhau:

from typing import Iterator

def scrape_search(search_term: str) -> Iterator[dict]:

  params = {
    ‘query‘: search_term,
    ‘hitsPerPage‘: 100,
  }

  page = 0
  while True:
    params[‘page‘] = page
    resp = requests.get(search_url, params=params, headers=headers)
    data = resp.json()

    if not data[‘hits‘]:
      break

    yield from data[‘hits‘]

    page += 1

Điều này lặp đi lặp lại trên các trang và mang lại tất cả các kết quả.

Để thu thập tất cả các kết quả:

results = []

for result in scrape_search("python"):
  results.append(result)

print(len(results))

Và bây giờ chúng tôi có một công cụ phân trang hoàn chỉnh để loại bỏ tất cả các kết quả tìm kiếm của Algolia!

Cạo Algolia ở quy mô

Công cụ cạo cơ bản ở trên hoạt động nhưng không được tối ưu hóa để cạo quy mô lớn. Các vấn đề bạn có thể gặp phải:

  • Chậm – Các yêu cầu đồng bộ làm cho việc quét 100 trang bị chậm.
  • Dễ vỡ – Một sai sót sẽ phá vỡ toàn bộ quá trình cạo.
  • Cấm – Quét từ một IP có nguy cơ bị chặn.

Hãy xem cách giải quyết những vấn đề này để có được quy mô lớn mạnh mẽ.

Yêu cầu không đồng bộ

Để tăng tốc độ thu thập dữ liệu, chúng tôi có thể tận dụng các yêu cầu không đồng bộ. Điều này cho phép chúng tôi có nhiều yêu cầu trong chuyến bay cùng một lúc.

Ví dụ với asyncio mô-đun:

import asyncio

async def fetch_page(page):
  params[‘page‘] = page
  resp = await asyncio.to_thread(requests.get, search_url, params=params) 
  return resp.json()

async def async_scrape():
  page = 0 
  while True:
    tasks = [asyncio.create_task(fetch_page(page + i)) for i in range(10)]
    results = await asyncio.gather(*tasks)

    for data in results:
      if not data[‘hits‘]:
        return

      for hit in data[‘hits‘]:
        yield hit

    page += 10

pages = async_scrape()  

Điều này tìm nạp 10 trang đồng thời trên mỗi lần lặp. Với các yêu cầu không đồng bộ, trình quét sẽ nhanh hơn rất nhiều.

Thử lại và dung sai lỗi

Các yêu cầu mạng dễ bị lỗi không liên tục. Chúng ta có thể thêm số lần thử lại để xử lý lỗi một cách khéo léo:

from time import sleep

async def fetch_page(page):

  for retry in range(3):

    try:
      return await asyncio.to_thread(requests.get, search_url, params=params) 
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

  print(f"Failed to fetch page {page} after {retries} retries")
  return {‘hits‘: []} # Return empty result

Điều này chỉ cần thử lại tối đa 3 lần nếu có bất kỳ lỗi nào. Những cải tiến khác như thời gian chờ theo cấp số nhân cũng có thể được thêm vào.

Để có khả năng phục hồi cao hơn, chúng tôi có thể gói vòng lặp quét tổng thể trong một lần thử/ngoại trừ và thử lại đối với bất kỳ sự cố không mong muốn nào.

Với việc thử lại ở nhiều cấp độ, máy cạp có thể phục hồi sau nhiều lỗi khác nhau và tiếp tục chạy.

Xoay proxy

Việc thu thập quá nhiều từ một IP có nguy cơ bị chặn. Để ngăn chặn điều này, chúng tôi có thể định tuyến các yêu cầu thông qua các proxy khác nhau bằng cách sử dụng các mô-đun như requests-proxy-killer:

from proxy_killer import KillerScraper

scraper = KillerScraper(use_cache=False, max_retries=3)

async def fetch_page(page):

  for retry in range(3): 
    try:
      proxy = scraper.get_proxy() # Rotate proxy
      resp = scraper.get(search_url, proxies=proxy, params=params)
      return resp.json()
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

# Remainder same as above

Bằng cách định tuyến từng yêu cầu thông qua một IP proxy khác nhau, chúng tôi có thể xử lý trên quy mô lớn mà không phải lo lắng về việc chặn.

Các bước trên cho phép chúng ta xây dựng một công cụ quét Algolia quy mô lớn, mạnh mẽ, hiệu suất cao trong Python. Các nguyên tắc tương tự áp dụng cho bất kỳ ngôn ngữ nào.

Tránh các khối trong khi cạo Algolia

Vấn đề cuối cùng cần giải quyết là tránh chặn dịch vụ Algolia. Nếu thực hiện quá nhiều yêu cầu mang tính xúc phạm, Algolia có thể chặn IP hoặc yêu cầu điều tiết của bạn.

Dưới đây là một số mẹo để cạo một cách lịch sự và giảm thiểu các khối:

  • Tỷ lệ giới hạn: Đừng làm API choáng ngợp với hàng trăm yêu cầu đồng thời. Bắt đầu nhỏ và tăng dần.

  • Sử dụng proxy: Xoay vòng các IP khác nhau để phân phối tải và tránh các yêu cầu tập trung.

  • Chọn ngẫu nhiên tác nhân người dùng: Thay đổi tiêu đề tác nhân người dùng giữa các yêu cầu.

  • Theo dõi robot.txt: Đảm bảo công cụ cạp của bạn tuân thủ các quy tắc của robots.txt.

  • Sử dụng logic thử lại: Độ lùi theo cấp số nhân nếu bạn bị giới hạn hoặc chặn tốc độ.

  • Cạo trong thời gian lưu lượng thấp: Nhắm mục tiêu các đêm trong tuần khi tải thấp hơn.

  • Theo dõi cẩn thận: Kiểm tra sự cố ngày càng tăng hoặc sự điều tiết.

Với sự chăm sóc thích hợp, bạn có thể tạo ra những chiếc máy cạo Algolia bền vững lâu dài. Nhưng hãy nhớ theo dõi chặt chẽ và điều chỉnh cách tiếp cận của bạn theo thời gian.

Thư viện trợ giúp cạo

Việc xử lý thủ công tất cả sự phức tạp của việc mở rộng quy mô và khả năng phục hồi có thể rất cồng kềnh. Có nhiều công cụ thương mại khác nhau để đơn giản hóa việc quét web.

Ví dụ:

Những công cụ này giúp việc xây dựng các trình dọn dẹp mạnh mẽ trở nên dễ dàng hơn mà không cần phải tự viết mã logic phức tạp. Xem hướng dẫn của tôi trên cách thức và thời điểm sử dụng API thu thập dữ liệu.

Tổng kết

Dưới đây là những điều chính yếu:

  • Algolia cung cấp tính năng tìm kiếm được lưu trữ thông qua API để dễ dàng tích hợp vào các trang web.
  • API tìm kiếm là công khai và có thể được loại bỏ bằng cách trích xuất điểm cuối và khóa.
  • Quét trên quy mô lớn yêu cầu các yêu cầu không đồng bộ và xoay vòng proxy.
  • Theo dõi cẩn thận và cạo lịch sự để tránh khối.
  • Dịch vụ cạo thương mại có thể đơn giản hóa các công việc cạo lớn.

Tôi hy vọng bài đăng này cung cấp cái nhìn tổng quan tốt về cách tìm kiếm API tìm kiếm Algolia một cách hiệu quả trên quy mô lớn bằng Python. Các nguyên tắc tương tự cũng áp dụng cho các ngôn ngữ khác.

Hãy cho tôi biết nếu bạn có bất kì câu hỏi nào khác!

tags:

Tham gia vào cuộc đối thoại

Chúng tôi sẽ không công khai email của bạn. Các ô đánh dấu * là bắt buộc *