我一直试图使用Requests
图书馆登录Instagram,但我无法让它发挥作用。连接总是被拒绝。
import requests
#Creating URL, usr/pass and user agent variables
BASE_URL = 'https://www.instagram.com/'
LOGIN_URL = BASE_URL + 'accounts/login/ajax/'
USERNAME = '******'
PASSWD = '******'
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)\
Chrome/59.0.3071.115 Safari/537.36'
#Setting some headers and refers
session = requests.Session()
session.headers = {'user-agent': USER_AGENT}
session.headers.update({'Referer': BASE_URL})
try:
#Requesting the base url. Grabbing and inserting the csrftoken
req = session.get(BASE_URL)
session.headers.update({'X-CSRFToken': req.cookies['csrftoken']})
login_data = {'username': USERNAME, 'password': PASSWD}
#Finally login in
login = session.post(LOGIN_URL, data=login_data, allow_redirects=True)
session.headers.update({'X-CSRFToken': login.cookies['csrftoken']})
cookies = login.cookies
#Print the html results after I've logged in
print(login.text)
#In case of refused connection
except requests.exceptions.ConnectionError:
print("Connection refused")
我不知道自己做错了什么。如果有人发布任何解决方案我真的很感激。请不要建议 API或Selenium (目前他们不是我的选项)
答案 0 :(得分:2)
由于请求不执行JavaScript,因此您的cookie中没有CSRFToken。
如果您查看内容,可以在html中找到csrf_token。
使用bs4和json,您可以将其提取并在帖子中使用。
from bs4 import BeautifulSoup
import json, random, re, requests
BASE_URL = 'https://www.instagram.com/accounts/login/'
LOGIN_URL = BASE_URL + 'ajax/'
headers_list = [
"Mozilla/5.0 (Windows NT 5.1; rv:41.0) Gecko/20100101"\
" Firefox/41.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2)"\
" AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2"\
" Safari/601.3.9",
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0)"\
" Gecko/20100101 Firefox/15.0.1",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"\
" (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36"\
" Edge/12.246"
]
USERNAME = '****'
PASSWD = '*****'
USER_AGENT = headers_list[random.randrange(0,4)]
session = requests.Session()
session.headers = {'user-agent': USER_AGENT}
session.headers.update({'Referer': BASE_URL})
req = session.get(BASE_URL)
soup = BeautifulSoup(req.content, 'html.parser')
body = soup.find('body')
pattern = re.compile('window._sharedData')
script = body.find("script", text=pattern)
script = script.get_text().replace('window._sharedData = ', '')[:-1]
data = json.loads(script)
csrf = data['config'].get('csrf_token')
login_data = {'username': USERNAME, 'password': PASSWD}
session.headers.update({'X-CSRFToken': csrf})
login = session.post(LOGIN_URL, data=login_data, allow_redirects=True)
login.content
# b'{"authenticated": true, "user": true, "userId": "*******", "oneTapPrompt": false, "status": "ok"}'
请记住,instagram中的大多数数据都已加载了javascript,因此将来可能会遇到更多麻烦。
您可以参考这篇有关如何恢复数据的文章:https://stackoverflow.com/a/49831347
或者您可以使用Dryscrape或Spynner等其他库
答案 1 :(得分:0)
不是脚本返回空值,而是根据我的研究结果.get_text()
答案 2 :(得分:0)
关于 script
在 2Pacho 的回答中返回空值,自他的帖子以来发生变化的不是 Instagram,而是 get_text()
方法的行为,在 2020 年 4 月发生了变化。
来自bs4 Documentation:
从 Beautiful Soup 4.9.0 版本开始,当使用 lxml 或 html.parser 时,