Перемещение по списку URL в базе данных Grand Comic Book - PullRequest
0 голосов
/ 07 июня 2019

Я недавно пытался сделать следующее вручную, и мне интересно, есть ли быстрый способ автоматизировать это.Мой единственный опыт - играть с python / python3 в терминале на Ubuntu, поэтому я надеюсь сделать это на python, а не каким-нибудь другим.

Краткая справка: веб-сайт my.comics.org представляет собой базу данных для комиксов, где заданная проблема имеет URL-адрес вида https://my.comics.org/issue/#, где # - это некоторое число.Если вы вошли в учетную запись, есть кнопка «Добавить», которая добавляет проблему в выбранный список.Я пытаюсь собрать воедино скрипт, который будет циклически перебирать URL-адреса, соответствующие числовому диапазону, и добавлять каждую проблему в выбранный список.Список выбора сохраняется в браузере, поэтому указывать его не нужно, поэтому достаточно просто нажать кнопку.Осматривая кнопку «Добавить», в html

<input type="submit" name="confirm_selection" value="Add">`

есть следующая строка, которая, я надеюсь, достаточно информации, чтобы сообщить сценарию, какую кнопку нажать.

Я знаю, что могу открывать веб-страницы с помощью модуля веб-браузера, но я не знаю, как открыть URL-адрес, нажмите кнопку «Добавить», закройте вкладку, а затем повторите для заданного диапазона.

Просто экспериментируя, я пытался что-то подобное в командной строке python

import webbrowser
for i in range(1,5):
    webbrowser.open('https://my.comics.org/issue/'+str(i))

Это открыло кучу вкладок, но я получил несколько ошибок, таких как

Unable to open /var/lib/snapd/desktop/dconf/profile/user: Permission denied

Я такжеЯ не хочу открывать все вкладки одновременно, так как я хотел бы запустить скрипт в диапазоне, скажем, 1000 проблем.Есть ли простой способ сделать это?Благодаря.

1 Ответ

1 голос
/ 07 июня 2019

Было немного свободного времени, поэтому я сделал аккаунт на my.comics.org.

Я бы не использовал для этого модуль webbrowser.Вместо этого я бы использовал модуль requests.Используя requests, вы можете отправлять HTTP-запросы GET и POST (и некоторые другие) на веб-сайты.Идея состоит в том, что вы создаете полезную нагрузку запроса и отправляете ее по желаемому URL, чтобы вы могли более или менее имитировать «действия», которые вы выполняете в браузере.Самое сложное - это сделать ваши запросы правильно сформированными и знать, что в них вставить, чтобы принимающий сервер их принял.

Вот код, который я придумал (обратите внимание, я использую f-строки в нескольких местах, что является функцией Python 3.6. Если у вас нет f-строк, вы можете просто выполнить простое форматирование старых строк:

def main():
    import requests

    login_url = "https://my.comics.org/accounts/login/"

    client = requests.session()

    # First, get the CSRF token.
    client.get(login_url)
    csrf_token = client.cookies["csrftoken"]


    email = "YOUR EMAIL GOES HERE"
    password = "YOUR PASSWORD GOES HERE"

    credentials = {
        "username": email,
        "password": password,
        "csrfmiddlewaretoken": csrf_token,
        "next": "/"
        }

    headers = {
        "User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
        "Referer": login_url,
        "Connection": "keep-alive",
        "Host": "my.comics.org",
        "Origin": "https://my.comics.org"
        }

    request = client.post(login_url, data=credentials, headers=headers)

    # We should be logged in now.
    # Here is where we can start adding the issues to our desired collection(s).

    issue_numbers = [41485, 41486, 41487]
    collection_id = "27402"

    number_of_issues = len(issue_numbers)

    for issue_index, issue_number in enumerate(issue_numbers):
        issue_url = f"https://my.comics.org/issue/{issue_number}/add_to_collection/"

        # Get the CSRF token again.
        client.get(issue_url)
        csrf_token = client.cookies["csrftoken"]

        data = {
            "csrfmiddlewaretoken": csrf_token,
            "confirm_selection": "Add",
            "collection_id": collection_id,
            }

        headers["Referer"] = issue_url

        print(f"({issue_index+1}/{number_of_issues}) Adding issue# {issue_number} to collection# {collection_id}...")
        request = client.post(issue_url, data=data, headers=headers)

    print("All done!")

    return 0

if __name__ == "__main__":
    import sys
    sys.exit(main())

Некоторые примечания:

Первый шаг - создать сеанс запросов, очень похожий на то, как ваш браузер создает сеанс для вас при посещении веб-сайта.Следующее, что мы хотели бы сделать, это войти в нашу учетную запись.Для этого нам нужны «имя пользователя» (электронная почта) и пароль.Нам также нужна вещь, называемая токеном CSRF, который представляет собой одноразовый файл cookie, который сервер отправляет вам для уникальной идентификации вашего сеанса.Мы настроили это путем создания словаря, который сопоставляет «имя пользователя» с вашей электронной почтой, «пароль» с вашим паролем и т. Д. Мы почти готовы отправить наш первый запрос POST, но вы также должны будете предоставить заголовокна сервер, который описывает ваш клиент и откуда вы пришли (серверы обычно тоже хотят это видеть, чтобы убедиться, что ваш запрос аутентичен).

После нашего первого запроса POST мы должны войти в системусейчас (обратите внимание, в отличие от модуля webbrowser, ничего из этого не откроет никаких вкладок или экземпляров браузера. Все это происходит за кулисами).Как только мы войдем в систему, мы сможем перебрать вопросы, которые нам интересны для добавления в нашу коллекцию (и).

УВЕДОМЛЕНИЕ, для моего collection_id я выбрал значение "27402".Возможно, вам придется изменить это значение, потому что это идентификатор моей коллекции (я создал «коллекцию python» только для этого проекта).Чтобы определить идентификатор коллекции, к которой я хочу добавить, я посмотрел в HTML:

<form method="POST" action="/issue/41485/add_to_collection/">
  <input type='hidden' name='csrfmiddlewaretoken' value='REDACTED, NORMALLY A BUNCH OF RANDOM CHARACTERS' />
  <div>

    <input type="submit" name="confirm_selection" value="Add">
    this issue to your 
    <select name="collection_id">

      <option value="27400" >Default have collection

      <option value="27401" >Default want collection

      <option value="27402" >python collection

    </select>
  </div>
</form>

Обратите внимание на «ценность» моей коллекции python.Это идентификатор коллекции, который мы можем выбрать в раскрывающемся окне под кнопкой «Добавить».

Способ, которым мы добавляем отдельные номера проблем в нашу коллекцию, заключается в повторении / циклическом просмотре нашего списка проблем.числа (в данном случае я выбрал три случайных).Для каждого номера проблемы в списке нам нужно получить новый токен CSRF и изменить поле «Referer» в нашем словаре заголовков (чтобы отразить новое место, откуда мы пришли).Затем запрос POST в цикле фактически добавляет текущую проблему к указанной коллекции.

И, на всякий случай, если вам интересно, вот вывод, который я получаю в терминале:

(1/3) Adding issue# 41485 to collection# 27402...
(2/3) Adding issue# 41486 to collection# 27402...
(3/3) Adding issue# 41487 to collection# 27402...
All done!

И моя коллекция комиксов после входа в мой аккаунт в браузере: My

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...