我无法使用请求登录 instagram

I cant login instagram using requests

我找到了这个 但是代码

import re
import requests
from bs4 import BeautifulSoup

from datetime import datetime

link = 'https://www.instagram.com/accounts/login/'
login_url = 'https://www.instagram.com/accounts/login/ajax/'

time = int(datetime.now().timestamp())

payload = {
    'username': 'login',
    'enc_password': f'#PWD_INSTAGRAM_BROWSER:0:{time}:your_password',
    'queryParams': {},
    'optIntoOneTap': 'false'
}

with requests.Session() as s:
    r = s.get(link)
    csrf = re.findall(r"csrf_token\":\"(.*?)\"", r.text)[0]
    r = s.post(login_url, data=payload, headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
        "X-Requested-With": "XMLHttpRequest",
        "Referer": "https://www.instagram.com/accounts/login/",
        "x-csrftoken": csrf
    })
    print(r.status_code)

给我 csrftoken 的错误

      line 21, in <module>
    csrf = re.findall(r"csrf_token\":\"(.*?)\"", r.text)[0]
IndexError: list index out of range

Stack Overflow 上的其他帖子对我不起作用

我不想使用 Selenium

TL;DR

user-agent 添加到第 20 行的获取请求 header:

r = s.get(link, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_7_3 rv:3.0; sl-SI) AppleWebKit/533.38.2 (KHTML, like Gecko) Version/5.0 Safari/533.38.2'})

长答案

如果我们查看您发布的错误消息,我们就可以开始分析出了什么问题。第 21 行试图在 instagram login page.

上查找 csrf_token 属性

诊断

从报错信息中我们可以看出,list index is out of range,在本例中意味着re.findalldocs)返回的list为空。这意味着

  1. 你的正则表达式是错误的
  2. 第 20 行的 get 请求 (docs) r = s.get(link) 返回的 html 不包含 csrf_token属性
  3. 源中不存在该属性html

如果我们访问该页面并查看其 html 源代码,我们可以看到第 261 行确实存在 csrf_token 属性:

<script type="text/javascript">window._sharedData = {"config":{"csrf_token":"TOKEN HERE","viewer":null,"viewerId":null}}</script>

请注意,为简洁起见,我已排除代码中的其余部分。

现在我们知道它出现在页面上,我们可以将您通过获取请求收到的已抓取的 html 写入本地文件并检查它:

r = s.get(link)
with open("csrf.html", "w") as f:
   f.write(html)

如果您打开该文件并执行 Ctrl+f for csrf_token,它不存在。这可能意味着 Instagram 检测到您正在通过抓取工具访问该页面并返回了该页面的修改版本。

修复

为了解决这个问题,您需要在您的请求中添加一个 user-agent header,这实际上 'tricks' 页面认为您正在通过浏览器访问它,这可以通过更改来完成:

r = s.get(link)

像这样:

r = s.get(link, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_7_3 rv:3.0; sl-SI) AppleWebKit/533.38.2 (KHTML, like Gecko) Version/5.0 Safari/533.38.2'})

请注意,这是来自 here 的随机用户代理。


备注

我理解您不想为您的任务使用 selenium,但您可能会发现,您想要进行的动态交互越多,使用请求模块等静态抓取库实现它就越难。 python:

中有一些学习 selenium 的好资源

Selenium docs

Python Selenium Tutorial #1 - Web Scraping, Bots & Testing