遍历Grand Comic Book数据库上的URL列表

时间:2019-06-07 08:47:11

标签: python browser

我最近一直在尝试手动执行以下操作,我想知道是否有一种快速的方法可以自动执行此操作。我唯一的经验是在Ubuntu的终端中使用python / python3,这就是为什么我希望在python中而不是其他地方使用它。

某些背景:网站my.comics.org是漫画书的数据库,其中给定的期刊的URL格式为https://my.comics.org/issue/#,其中#是一个数字。如果已登录一个帐户,则有一个“添加”按钮,可将问题添加到所选列表中。我正在尝试整理一个脚本,该脚本将循环遍历与数字范围相对应的URL,并将每个问题添加到选定列表中。选择列表保存在浏览器中,因此无需指定,因此只需单击按钮即可。检查“添加”按钮,html

中有以下行
<input type="submit" name="confirm_selection" value="Add">`

我希望该信息足以告诉脚本单击哪个按钮。

我知道我可以使用webbrowser模块打开网页,但是我不知道如何打开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 个答案:

答案 0 :(得分:1)

有一些空闲时间,所以我在my.comics.org上注册了一个帐户。

我不会为此使用super.componentDidUpdate模块。相反,我将使用webbrowser模块。使用requests,您可以向网站发出HTTP GET和POST请求(以及其他一些请求)。这个想法是,您创建一个请求有效负载并将其提交到所需的URL,以便您或多或少地模仿您将在浏览器中执行的“操作”。最难的部分是使您的请求格式正确,并知道要放入哪些内容,以便接收服务器将其接受。

这是我想出的代码(请注意,我在多个地方使用f字符串,这是Python 3.6的功能。如果没有f字符串,则可以进行简单的旧字符串格式化) :

requests

一些注意事项:

第一步是创建请求会话,就像您访问网站时浏览器为您创建会话一样。我们接下来要做的就是登录我们的帐户。为此,我们需要一个“用户名”(电子邮件)和密码。我们还需要一个称为CSRF令牌的东西,它是服务器发送给您的一次性Cookie,用于唯一标识您的会话。我们的设置方法是创建一个字典,该字典将“用户名”映射到您的电子邮件,将“密码”映射到您的密码等。我们几乎准备提交第一个POST请求,但是您还必须提供标题到服务器,以哪种方式描述您的客户端以及您来自哪里(服务器通常也希望看到此信息以确保您的请求是真实的)。

在第一个POST请求之后,我们应该立即登录(请注意,与webbrowser模块不同,这些都不会打开任何选项卡或浏览器实例。所有操作都在后台进行)。登录后,我们可以遍历我们有兴趣添加到集合中的问题。

注意,对于我的collection_id,我选择了值“ 27402”。您可能必须更改此值,因为这是我的收藏的ID(我为此项目创建了一个“ python收藏”)。我找出要添加的集合ID的方法是查看HTML:

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())

注意,我的python集合的“值”。这就是我们可以从“添加”按钮下的下拉窗口中选择的集合的ID。

我们将各个问题编号添加到集合中的方法是迭代/循环遍历我们的问题编号列表(在这种情况下,我只是随机选择了三个)。对于列表中的每个发行号,我们需要获取一个新的CSRF令牌,并更改标题词典中的“ Referer”字段(以反映我们所来自的新位置)。然后,循环中的POST请求实际上就是将当前问题添加到指定集合中的请求。

而且,以防万一您感到好奇,这是我在终端机上获得的输出:

<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>

而且,在浏览器中登录我的帐户后,我的漫画收藏集: My "Python collection" after running the script