Как соскабливать данные Reddit: Посты, изображения, комментарии и многое другое.


Введение

Reddit.com — это социальный новостной веб-сайт и форум, где контент социально курируется и продвигается участниками сайта путем голосования.

В этой статье вы прочитаете о самом простом способе соскабливания постов и комментариев Reddit с помощью Page2API, а также найдете несколько примеров кода на Python.

Для соскабливания Reddit мы будем использовать Page2API — мощный и восхитительный API, который поможет вам соскабливать веб-страницы как PRO.

Предварительные условия

Чтобы начать скраппинг постов Reddit, нам понадобятся следующие вещи:

  • учетная запись Page2API
  • Ссылка на подредактит, который мы собираемся соскрести. Чтобы облегчить процесс соскребания, мы будем использовать старый пользовательский интерфейс Reddit, поскольку он имеет более простую HTML-структуру. В этой статье мы будем соскребать подредактит BMW.

Как соскребать сообщения Reddit

Первое, что нам нужно, это открыть URL-адрес сабреддита:

https://old.reddit.com/r/BMW/
Войти в полноэкранный режим Выйти из полноэкранного режима

URL — это первый параметр, который нам нужен для выполнения скраппинга.

Страница, которую вы увидите, должна выглядеть так, как показано ниже:

Если вы изучите HTML страницы, то обнаружите, что один результат обернут в элемент, который выглядит следующим образом:

С этой страницы мы возьмем следующие атрибуты из каждого сообщения Reddit:

  • Заголовок
  • URL
  • Эскиз
  • Отправлено
  • Автор
  • URL автора
  • Комментарии
  • Рейтинг
  • Оценка

Теперь давайте определим селекторы для каждого атрибута.

/* Parent: */
.thing[data-promoted=false]

/* Title */
a.title

/* URL */
a.title

/* Thumbnail */
a.thumbnail img

/* Submitted */
time

/* Author */
a.author

/* Author URL */
a.author

/* Comments */
(parent div, attribute: data-comments-count)

/* Rank */
(parent div, attribute: data-rank

/* Score */
(parent div, attribute: data-score
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь разберемся с пагинацией.
Мы будем переходить по страницам Reddit, нажимая на кнопку Следующая страница.

Чтобы перейти к следующей странице, мы должны нажать на ссылку «Следующая страница», если она присутствует на странице:

document.querySelector('.next-button a').click()
Войти в полноэкранный режим Выйти из полноэкранного режима

Скраппинг будет продолжаться, пока ссылка Next присутствует на странице, и остановится, если она исчезнет.
Условием остановки скрепера будет следующий фрагмент javascript:

document.querySelector('.next-button a') === null
Войти в полноэкранный режим Выйти из полноэкранного режима

Давайте создадим запрос, который будет скрести нужные страницы из этого сабреддита.

В следующих примерах показано, как соскрести 5 страниц сообщений с Reddit.com.

Наша полезная нагрузка будет выглядеть следующим образом

{
  "api_key": "YOUR_PAGE2API_KEY",
  "url": "https://old.reddit.com/r/BMW/",
  "merge_loops": true,
  "real_browser": true,
  "scenario": [
    {
      "loop": [
        { "wait_for": ".thing" },
        { "execute": "parse" },
        { "click": ".next-button a" }
      ],
      "stop_condition": "document.querySelector('.next-button a') === null",
      "iterations": 5
    }
  ],
  "parse": {
    "posts": [
      {
        "_parent": ".thing[data-promoted=false]",
        "title": "a.title >> text",
        "url": "a.title >> href",
        "thumbnail": "a.thumbnail img >> src",
        "submitted": "time >> datetime",
        "author": "a.author >> text",
        "author_url": "a.author >> href",
        "comments": "_parent >> data-comments-count",
        "rank": "_parent >> data-rank",
        "score": "_parent >> data-score"
      }
    ]
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Пример кода на языке Python

import requests
import json

api_url = 'https://www.page2api.com/api/v1/scrape'

The following example will show how to scrape 5 pages of posts from Reddit.com

payload = {
  "api_key": "YOUR_PAGE2API_KEY",
  "url": "https://old.reddit.com/r/BMW/",
  "merge_loops": True,
  "real_browser": True,
  "scenario": [
    {
      "loop": [
        { "wait_for": ".thing" },
        { "execute": "parse" },
        { "click": ".next-button a" }
      ],
      "stop_condition": "document.querySelector('.next-button a') === null",
      "iterations": 5
    }
  ],
  "parse": {
    "posts": [
      {
        "_parent": ".thing[data-promoted=false]",
        "title": "a.title >> text",
        "url": "a.title >> href",
        "thumbnail": "a.thumbnail img >> src",
        "submitted": "time >> datetime",
        "author": "a.author >> text",
        "author_url": "a.author >> href",
        "comments": "_parent >> data-comments-count",
        "rank": "_parent >> data-rank",
        "score": "_parent >> data-score"
      }
    ]
  }
}

headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.post(api_url, data=json.dumps(payload), headers=headers)
result = json.loads(response.text)

print(result)
Вход в полноэкранный режим Выйти из полноэкранного режима

Результат

{
  "result": {
    "posts": [
      {
          "title": "Thought you would enjoy this",
          "url": "https://old.reddit.com/r/BMW/comments/uu50bl/thought_you_would_enjoy_this/",
          "thumbnail": "https://b.thumbs.redditmedia.com/1OMVuKzvOeVi6IkOMc1K94HzPOLs3InozhCPlxU8K7E.jpg",
          "submitted": "2022-05-20T18:55:11+00:00",
          "author": "L9FanboyXD",
          "author_url": "https://old.reddit.com/user/L9FanboyXD",
          "comments": "206",
          "rank": "1",
          "score": "1234"
      },
      {
          "title": "Totalled..",
          "url": "https://old.reddit.com/r/BMW/comments/uu7yih/totalled/",
          "thumbnail": "https://b.thumbs.redditmedia.com/QQ7_MbJqhB5t4QfKJjbTFU4sEK0Cd9Cy5uFCSzzeLzM.jpg",
          "submitted": "2022-05-20T21:16:40+00:00",
          "author": "Conscious_Champion35",
          "author_url": "https://old.reddit.com/user/Conscious_Champion35",
          "comments": "130",
          "rank": "2",
          "score": "375"
      },
      {
          "title": "Joined the squad. Yes there was a flat bed at the dealer as I was closing this deal today.",
          "url": "https://www.reddit.com/gallery/uucgb5",
          "thumbnail": "https://b.thumbs.redditmedia.com/g8vAVq0N59R0a-IX1mBtM1YEy2gouhhGTTS7m4Nr8us.jpg",
          "submitted": "2022-05-21T01:16:08+00:00",
          "author": "restloy",
          "author_url": "https://old.reddit.com/user/restloy",
          "comments": "22",
          "rank": "3",
          "score": "157"
      }, ...
    ]
  }, ...
}
Вход в полноэкранный режим Выход из полноэкранного режима

Как соскрести комментарии Reddit

Нам нужно открыть URL любого поста из предыдущего шага.

Это изменит URL-адрес браузера на что-то похожее:

https://old.reddit.com/r/BMW/comments/uu50bl/thought_you_would_enjoy_this/
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот URL является первым параметром, который нам нужен для сопоставления данных поста и комментариев Reddit.

Раздел комментариев, который вы видите, должен выглядеть так, как показано ниже:

С этой страницы мы возьмем следующие атрибуты:

Данные поста:

  • Заголовок
  • Изображение

Данные комментариев:

  • Автор
  • URL автора
  • Опубликовано
  • Оценка
  • ID
  • Содержание

Теперь давайте определим селекторы для каждого атрибута.

Данные сообщения

/* Title */
a.title

/* Image */
.media-preview-content img.preview
Вход в полноэкранный режим Выход из полноэкранного режима

Данные комментариев

/* Parent */
.entry

/* Author */
a.author

/* Author URL */
a.author

/* Posted */
time

/* Score */
.score.unvoted

/* ID */
input[name=thing_id]

/* Content */
.usertext-body
Войти в полноэкранный режим Выйти из полноэкранного режима

Пришло время подготовить запрос, который будет соскабливать данные со страницы сообщения Reddit.

Полезной нагрузкой для нашего запроса будет:

{
  "api_key": "YOUR_PAGE2API_KEY",
  "url": "https://old.reddit.com/r/BMW/comments/urv3mr/i_saw_it_in_prague_the_red_is_much_prettier_in/",
  "parse": {
    "title": "a.title >> text",
    "image": ".media-preview-content img.preview >> src",
    "comments": [
      {
        "_parent": ".entry",
        "author": "a.author >> text",
        "author_url": "a.author >> href",
        "posted": "time >> datetime",
        "score": ".score.unvoted >> text",
        "id": "input[name=thing_id] >> value",
        "content": ".usertext-body >> text"
      }
    ]
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Пример кода на Python:

import requests
import json

api_url = 'https://www.page2api.com/api/v1/scrape'
payload = {
  "api_key": "YOUR_PAGE2API_KEY",
  "url": "https://old.reddit.com/r/BMW/comments/urv3mr/i_saw_it_in_prague_the_red_is_much_prettier_in/",
  "parse": {
    "title": "a.title >> text",
    "image": ".media-preview-content img.preview >> src",
    "comments": [
      {
        "_parent": ".entry",
        "author": "a.author >> text",
        "author_url": "a.author >> href",
        "posted": "time >> datetime",
        "score": ".score.unvoted >> text",
        "id": "input[name=thing_id] >> value",
        "content": ".usertext-body >> text"
      }
    ]
  }
}

headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.post(api_url, data=json.dumps(payload), headers=headers)
result = json.loads(response.text)

print(result)
Вход в полноэкранный режим Выйти из полноэкранного режима

Результат:

{
  "result": {
    "title": "I saw it in prague. the red is much prettier in real life",
    "image": "https://preview.redd.it/91x8qz36f3091.jpg?width=1023&auto=png&s=9c0aced50d6743989f053cf9cc78c896f928d8a7",
    "comments": [
      {
        "author": "DarkMeta81",
        "author_url": "https://old.reddit.com/user/DarkMeta81",
        "posted": "2022-05-17T20:12:31+00:00",
        "score": "15 points",
        "id": "t1_i8zlp77",
        "content": "i was on vacation and prague is full of beautiful bmw this m5 is great"
      },
      {
        "author": "Id-atl",
        "author_url": "https://old.reddit.com/user/Id-atl",
        "posted": "2022-05-18T01:06:15+00:00",
        "score": "5 points",
        "id": "t1_i90on16",
        "content": "Wow imagine being in Prague ripping this around!"
      }, ...
    ]
  }, ...
}
Войти в полноэкранный режим Выход из полноэкранного режима

Заключение

Вот и все!

В этой статье вы узнали, как соскабливать данные с Reddit.com с помощью Page2API — Web Scraping API, который решает все проблемы и позволяет вам с легкостью получать нужные данные.

Оригинальную статью можно найти здесь:

https://www.page2api.com/blog/how-to-scrape-reddit/

Оцените статью
Procodings.ru
Добавить комментарий