iT邦幫忙

0

Python requests登入帳號密碼

  • 分享至 

  • xImage

有個公司內網,登入帳密後可取得json資料。
我可以正常從瀏覽器登入。

但我想要藉由Python自動化擷取。
可是一直過不了登入的需求。
它是跳出像下圖的登入訊息視窗。
我開F12看不到element,沒辦法用selenium find_element來操作。
https://ithelp.ithome.com.tw/upload/images/20230907/20097781AnaxRCreZ9.png

網路找了很多參考範例,但都未解。

import requests
from requests.auth import HTTPBasicAuth

url = 'https://xxx.xxx.xxx'
response = requests.get(url, auth=HTTPBasicAuth(username, password))

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f"Request failed {response.status_code}: {response.text}")
import requests

url = 'https://xxx.xxx.xxx'
data = {
    'username': username,
    'password': password
}
response = requests.post(url, data=data)
import requests

url = 'https://xxx.xxx.xxx'

response = requests.get(url, auth=(username, password))

if response.status_code == 200:
    print(response.text)
else:
    print(f"Authentication failed: {response.status_code}")

有點亂槍打鳥的嘗試...
再請邦友們協助解惑指點
非常感謝

  • 補充Edge登入畫面
    https://ithelp.ithome.com.tw/upload/images/20230907/20097781NfLnT9px4L.png
看更多先前的討論...收起先前的討論...
ccutmis iT邦高手 2 級 ‧ 2023-09-07 13:20:59 檢舉
參考這篇
https://ithelp.ithome.com.tw/articles/10193266
Neish iT邦研究生 1 級 ‧ 2023-09-07 14:01:03 檢舉
謝謝ccutmis的參考資訊。
這篇我在尋找解答的時候也有看到。但我找不到隱藏值。
result = session_requests.get(LOGIN_URL)
tree = html.fromstring(result.text)
print(html.tostring(tree))
authenticity_token = list(set(tree.xpath('//input[@name="xxx"]/@value')))[0]

我先print(html.tostring(tree))出來看
直接帶出... <title>IIS 10.0 Detailed Error - 401.2 - Unauthorized</title> ....

我在登入頁面觀察
故意輸入錯的帳密我用F12也找不到我輸入的內容

不知道還有什麼方式還是思路可以解
感謝
ccutmis iT邦高手 2 級 ‧ 2023-09-07 14:34:34 檢舉
內部網站的登入驗證如果不是傳統網站那種帶request header參數而是用 windows登入驗證的 或許可以試試用 python 的 pyautogui ,
你可以拍一張完整的螢幕截圖嗎,最好是登入視窗有包含標題的,記得把敏感內容碼掉,如果有這個截圖的話,我可以提供一個 用 pyautogui 的範例給您參考。
Neish iT邦研究生 1 級 ‧ 2023-09-07 15:37:45 檢舉
那可能真的是windows登入驗證
上方提問的圖示是Chrome出現的畫面
我補充Edge的畫面到文章下方
謝謝您的熱心協助
ccutmis iT邦高手 2 級 ‧ 2023-09-07 15:52:56 檢舉
Edge登入畫面 是彈出小視窗 還是 在原本 Edge的網頁裡面?
Neish iT邦研究生 1 級 ‧ 2023-09-07 15:54:52 檢舉
* 更正 應該是彈出小視窗 但是我只能操作那個視窗 無法點擊其他地方
在原本的Ege裡面
只能輸入使用者名稱跟密碼
或是點選確定或取消
無法點選其他地方
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
ccutmis
iT邦高手 2 級 ‧ 2023-09-07 16:55:41

一、需要先安裝的模組:

底下的範例需要先安裝 pywin32 及 pyautogui 這兩個模組

pip install pywin32
pip install pyautogui

二、建立範例程式:

然後在同一個資料夾裡面新建兩個文件,分別是:

  • WindowMgr.py
  • run.py

WindowMgr.py 內容

import win32gui, win32com.client, win32con, winxpgui, win32api, ctypes
from re import match

class WindowMgr:
    def __init__ (self):
        self._handle = None
        self.is_exist = False
    """Pass to win32gui.EnumWindows() to check all the opened windows"""
    def _window_enum_callback(self, hwnd, wildcard):
        if match(".*"+wildcard+"*", str(win32gui.GetWindowText(hwnd))) is not None:
            self._handle = hwnd
            self.is_exist = True
    """ 找到標題內含wildcard字串的視窗 """
    def find_window_wildcard(self, wildcard):
        self._handle = None
        self.is_exist = False
        win32gui.EnumWindows(self._window_enum_callback, wildcard)
    """ 將目標視窗設為前景 """
    def set_foreground(self):
        win32gui.SetForegroundWindow(self._handle)
    """ 執行 find_window_wildcard ()後要找另一個目標視窗前,需先執行 reset() """
    def reset(self):
        shell = win32com.client.Dispatch("WScript.Shell")
        shell.SendKeys('%')

run.py 內容

from WindowMgr import WindowMgr
import pyautogui as p

uname = 'username'
passwd = 'password'

win = WindowMgr()
win.find_window_wildcard("Windows 安全性")
win.set_foreground() # 把目標視窗設為前景

p.write(uname)
p.sleep(0.5)
p.press('tab')
p.sleep(0.5)
p.write(passwd)
p.sleep(0.5)
p.press('enter')
# 與pyautogui相關資訊可以查詢 
# https://pyautogui.readthedocs.io/en/latest/keyboard.html

p.sleep(5)

win.reset()
win.find_window_wildcard("原本EDGE的title部份文字")
win.set_foreground() # 把目標視窗設為前景

#然後再用 pyautogui 操作 json 存取的部份

三、說明:

WindowMgr.py 無需改動。(用於切換目標視窗)
需要適當修改 run.py 內容,使用了 pyautogui 操作鍵盤滑鼠輸入,
簡單測試就是先開啟EDGE,然後進到你截圖那個登入頁面,然後進檔案總管或是用cmd執行 run.py
它會把視窗焦點切到 'Windows 安全性' 這個視窗(假設滑鼠遊標在username欄),然後輸入 username,然後再按一下tab,把滑鼠遊標轉移到password欄,然後輸入password,再按下Enter,進行登入(這裡程式會暫停5秒),然後把視窗焦點切到'原本EDGE的title部份文字' 這個視窗,
再來就要看你那個 json 資料怎麼下載,如果是有個下載連結的,可以用 pyautogui 移到上面按右鍵另存或直接點擊之類的,要依照實際情況作處理... 這是用 pyautogui 的作法,提供您參考。

備註:

上列的代碼沒有實際測試,理論上是可行的,祝好運^^"

Neish iT邦研究生 1 級 ‧ 2023-09-08 17:14:27 檢舉

感謝ccutmis!
但這個要實際開啟瀏覽器才能執行吧
請問可以用selenium browser.get(url)開啟後
再結合pyautogui模擬鍵盤滑鼠動作執行嗎

另外是否能單純用request的方式取得
不用真的開起瀏覽器

再次感謝您的詳盡說明
獲益良多 !!!

0
code840
iT邦新手 5 級 ‧ 2023-09-08 09:34:51

如果你想使用Python的Requests庫來進行HTTP登錄,並使用Windows身份驗證而不是基本身份驗證,你可以使用requests_ntlm庫。這個庫可以幫助你進行NTLM身份驗證,這是一種常見的Windows身份驗證方法。

首先使用pip安裝requests_ntlm庫:

pip install requests-ntlm

然後,你可以使用以下示例代碼來進行HTTP登錄:

import requests
from requests_ntlm import HttpNtlmAuth

session = requests.Session()
session.auth = HttpNtlmAuth('domain\\username','password')
response = session.get('https://xxx.xxx.xxx')
data = response.json()
print(data)

資料來自 ChatGPT

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 2 級 ‧ 2023-09-08 10:31:00 檢舉

這方法感覺不錯

Neish iT邦研究生 1 級 ‧ 2023-09-08 17:15:51 檢舉

感謝code840回覆!
但我實測還是status_code 401...
我有漏了哪個部份嗎?
非常感謝

033220 iT邦新手 5 級 ‧ 2023-09-09 07:36:42 檢舉

感謝c大。

code840 iT邦新手 5 級 ‧ 2023-09-10 00:28:03 檢舉

我想可以下載個Fiddler抓包看正常瀏覽器登入的回應
不然我也不知道是漏了什麼

Neish iT邦研究生 1 級 ‧ 2023-09-11 09:04:27 檢舉

剛GOOGLE了一下Fiddler
好像很實用
應該就是可以看出後端實際拋轉哪些參數吧?!
再來研究看看

我要發表回答

立即登入回答